Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

A Rust implementation of ECMAScript's Temporal API

License

Apache-2.0, MIT licenses found

Licenses found

Apache-2.0
LICENSE-Apache
MIT
LICENSE-MIT
NotificationsYou must be signed in to change notification settings

boa-dev/temporal

Temporal is a calendar and timezone aware date/time builtin currentlyproposed for addition to the ECMAScript specification.

temporal_rs is an implementation of Temporal in Rust that aims to be100% test compliant. While initially developed forBoa, thecrate has been externalized and is being used in other engines such asV8 andKiesel.

For more information ontemporal_rs's general position in the Rustdate/time library ecoystem, see ourFAQ.

Temporal is an API for working with date and time in a calendarand time zone aware manner.

temporal_rs is designed with ECMAScript implementations and generalpurpose Rust usage in mind, meaning that temporal_rs can be used to implementthe Temporal built-ins in an ECMAScript implementation or generallyused as a date and time library in a Rust project.

temporal_rs is the primary library for the Temporal API implementation in Boa, Kiesel,and V8. Each of these engines pass the large ECMAScript conformance test suite forthe specification.

Why use temporal_rs?

As previously mentioned, Temporal is an API for working with date and time ina calendar and time zone aware manner. This means that calendar and time zone supportare first class in Temporal as well as in temporal_rs.

For instance, converting between calendars is as simple as providing the calendar asshown below.

use temporal_rs::{PlainDate,Calendar};use tinystr::tinystr;use core::str::FromStr;// Create a date with an ISO calendarlet iso8601_date =PlainDate::try_new_iso(2025,3,3).unwrap();// Create a new date with the japanese calendarlet japanese_date = iso8601_date.with_calendar(Calendar::JAPANESE);assert_eq!(japanese_date.era(),Some(tinystr!(16,"reiwa")));assert_eq!(japanese_date.era_year(),Some(7));assert_eq!(japanese_date.month(),3)

Beyond the general calendar use case, temporal_rs has robust support fortime zones which can generally by applied to aPlainDate via [ZonedDateTime].

Important Note: The below API is enabled with thecompiled_data feature flag.

use temporal_rs::{ZonedDateTime,TimeZone};use temporal_rs::options::{Disambiguation,OffsetDisambiguation};let zdt =ZonedDateTime::from_utf8(b"2025-03-01T11:16:10Z[America/Chicago][u-ca=iso8601]",Disambiguation::Compatible,OffsetDisambiguation::Reject).unwrap();assert_eq!(zdt.year(),2025);assert_eq!(zdt.month(),3);assert_eq!(zdt.day(),1);// Using Z and a timezone projects a UTC datetime into the timezone.assert_eq!(zdt.hour(),5);assert_eq!(zdt.minute(),16);assert_eq!(zdt.second(),10);// You can also update a time zone easily.let zurich_zone =TimeZone::try_from_str("Europe/Zurich").unwrap();let zdt_zurich = zdt.with_timezone(zurich_zone).unwrap();assert_eq!(zdt_zurich.year(),2025);assert_eq!(zdt_zurich.month(),3);assert_eq!(zdt_zurich.day(),1);assert_eq!(zdt_zurich.hour(),12);assert_eq!(zdt_zurich.minute(),16);assert_eq!(zdt_zurich.second(),10);

Overview

temporal_rs provides 8 core types for working with date and time. The core types are:

  • [PlainDate]
  • [PlainTime]
  • [PlainDateTime]
  • [ZonedDateTime]
  • [Instant]
  • [Duration]
  • [PlainYearMonth]
  • [PlainMonthDay]

In addition to these types, there are the [Calendar] and [TimeZone] type thatsupport the calendars or time zones. The specific support for calendars and timezones per type are as follows.

Temporal typeCategoryCalendar supportTime zone support
PlainDateCalendar dateyesno
PlainTimeWall-clock timenono
PlainDateTimeCalendar date and wall-clock timeyesno
ZonedDateTimeCalendar date and exact timeyesyes
InstantExact timenono
DurationNonenono
PlainYearMonthCalendar dateyesno
PlainMonthDayCalendar dateyesno

There is also the [Now][now::Now], which provides access to the current host systemtime. This can then be used to map to any of the above Temporal types.

Important Note: the below example is only available with thesys andcompiled_data feature flag enabled.

use core::cmp::Ordering;use temporal_rs::{Temporal,Calendar,ZonedDateTime};let current_instant =Temporal::now().instant().unwrap();let current_zoned_date_time =Temporal::now().zoned_date_time_iso(None).unwrap();/// Create a `ZonedDateTime` from the requested instant.let zoned_date_time_from_instant =ZonedDateTime::try_new(current_instant.as_i128(),*current_zoned_date_time.time_zone(),Calendar::ISO,).unwrap();// The two `ZonedDateTime` will be equal down to the second.assert_eq!(current_zoned_date_time.year(), zoned_date_time_from_instant.year());assert_eq!(current_zoned_date_time.month(), zoned_date_time_from_instant.month());assert_eq!(current_zoned_date_time.day(), zoned_date_time_from_instant.day());assert_eq!(current_zoned_date_time.hour(), zoned_date_time_from_instant.hour());assert_eq!(current_zoned_date_time.minute(), zoned_date_time_from_instant.minute());assert_eq!(current_zoned_date_time.second(), zoned_date_time_from_instant.second());// The `Instant` reading that occurred first will be less than the ZonedDateTime// readingassert_eq!(zoned_date_time_from_instant.compare_instant(&current_zoned_date_time),Ordering::Less);

General design

While temporal_rs can be used in native Rust programs, the library is -- first andforemost -- designed for use in ECMAScript implementations. This is not to detractfrom temporal_rs's use in a native Rust program, but it is important information tounderstand in order to understand the library's architecture and general API design.

Without default feature flags, temporal_rs does not have with access to the hostenvironment and it does not embed any time zone data. This is important from aninterpreter perspective, because access to the host environment and time zone datacomes from the interpreter's agent, not from a dependency.

Instead, temporal_rs provides the [HostHooks][host::HostHooks] and [TimeZoneProvider][provider::TimeZoneProvider]traits that can be implemented and provided as function arguments that temporal_rs willuse to access the host system or time zone data. temporal_rs also provides some baselineimplementations of the traits that can be selected from depending on application needs.

That being said, this does not mean that everyone must implement their own traitimplementations for that functionality to exist, but the APIs are there for powerusers who may need a custom host system or time zone data implementation.

A default host system and time zone provider have been implemented and are automaticallyactive as default features.

A quick walkthrough

For instance, the examples thus far have been using the general usage Rust API withthesys andcompiled_data feature.

For instance, let's manually write our [Now][now::Now] implementation instead of using[Temporal::now()] with an empty host system implementation.

use temporal_rs::{Instant, now::Now, host::EmptyHostSystem};// The empty host system is a system implementation HostHooks that always// returns the UNIX_EPOCH and the "+00:00" time zone.let now =Now::new(EmptyHostSystem);let time_zone = now.time_zone().unwrap();assert_eq!(time_zone.identifier().unwrap(),"+00:00");let now =Now::new(EmptyHostSystem);assert_eq!(now.instant(),Instant::try_new(0));

However, even in our above example, we cheated a bit. We were still relying on thecompiled_data feature flag that provided time zone data for us. Let's try again,but this time without the feature flag.

use temporal_rs::{Instant, now::Now, host::EmptyHostSystem};use timezone_provider::tzif::CompiledTzdbProvider;let provider =CompiledTzdbProvider::default();// The empty host system is a system implementation HostHooks that always// returns the UNIX_EPOCH and the "+00:00" time zone.let now =Now::new(EmptyHostSystem);let time_zone = now.time_zone_with_provider(&provider).unwrap();assert_eq!(time_zone.identifier_with_provider(&provider).unwrap(),"+00:00");let now =Now::new(EmptyHostSystem);assert_eq!(now.instant(),Instant::try_new(0));

Now -- pun only partially intended -- we've successfully written a no-default-featuresexample with temporal_rs!

What have we learned going over this all this?

First, any API that has the suffix_with_provider is a power user API for supplyinga custom or specific time zone data provider. Furthermore, any API that has a_with_provider suffix will also have a version without the suffix that automagicallyprovides time zone data for you.

Finally, sourcing time zone data is a very scary (but fun!) business. If you're interestedin learning more, feel free to check out thetimezone_provider crate!

With any luck, this also highlights the general design of temporal_rs. It provides ageneral usage API that aligns with the Temporal specification while also beingflexible enough to provide an power user to take control of their host system accessand time zone data sourcing as needed.

Formatting

temporal_rs adheres to Temporal grammar, which is a strict version ofRFC9557's IXDTF. RFC9557 is an update to RFC3339 that addsextensions to the format.

More information

Temporal is the Stage 3 proposal for ECMAScript thatprovides new JS objects and functions for working with dates andtimes that fully supports time zones and non-gregorian calendars.

This library's primary development source is the TemporalProposalspecification.

Temporal proposal

Relevant links and information regarding Temporal can be found below.

Core maintainers

Contributing

This project is open source and welcomes anyone interested toparticipate. Please seeCONTRIBUTING.md for moreinformation.

Test262 Conformance

Thetemporal_rs's current conformance results can be viewed on Boa'stest262 conformance page.

FFI

temporal_rs currently has bindings for C++, available via thetemporal_capi crate.

Communication

Feel free to contact us onMatrix.

License

This project is licensed under theApache orMIT licenses, at your option.

About

A Rust implementation of ECMAScript's Temporal API

Resources

License

Apache-2.0, MIT licenses found

Licenses found

Apache-2.0
LICENSE-Apache
MIT
LICENSE-MIT

Contributing

Stars

Watchers

Forks

Packages

No packages published

Contributors22

Languages


[8]ページ先頭

©2009-2025 Movatter.jp