[package] name = "jiff" version = "0.2.14" #:version authors = ["Andrew Gallant "] license = "Unlicense OR MIT" repository = "https://github.com/BurntSushi/jiff" documentation = "https://docs.rs/jiff" description = ''' A date-time library that encourages you to jump into the pit of success. This library is heavily inspired by the Temporal project. ''' categories = ["date-and-time", "no-std"] keywords = ["date", "time", "calendar", "zone", "duration"] edition = "2021" autotests = false autoexamples = false rust-version = "1.70" # We include `/tests/lib.rs` to squash a `cargo package` warning that the # `integration` test target is being ignored. We don't include anything else # so tests obviously won't work, but it makes `cargo package` quiet. include = [ "/src/**/*.rs", "/tests/lib.rs", "/*.md", "COPYING", "LICENSE-MIT", "UNLICENSE", ] [workspace] members = [ "crates/jiff-cli", "crates/jiff-static", "crates/jiff-tzdb", "crates/jiff-tzdb-platform", ] # Features are documented in the "Crate features" section of the crate docs: # https://docs.rs/jiff/*/#crate-features [features] default = [ "std", "tz-system", "tz-fat", "tzdb-bundle-platform", "tzdb-zoneinfo", "tzdb-concatenated", "perf-inline", ] std = ["alloc", "log?/std", "serde?/std"] # alloc = ["serde?/alloc", "portable-atomic-util/alloc"] alloc = [] serde = ["dep:serde"] logging = ["dep:log"] # When enabled, Jiff will include code that attempts to determine the "system" # time zone. For example, on Unix systems, this is usually determined by # looking at the symlink information on /etc/localtime. But in general, it's # very platform specific and heuristic oriented. On some platforms, this may # require extra dependencies. (For example, `windows-sys` on Windows.) tz-system = ["std", "dep:windows-sys"] # When enabled, Jiff will "fatten" time zone data so that it contains more # transitions. This uses a little extra heap memory (or binary size, when # embedding time zone data into your binary) in exchange for generally faster # time zone lookups. # # Why is this a thing? The TZif files that make up the IANA Time Zone Database # contain both explicit transitions for when offsets change (e.g., twice a # year for DST) _and_ a more general rule for dealing with offset changes # that aren't explicitly listed. In the long ago, TZif data only contained the # explicit transitions. Later, they added support for the general rule # mechanism, which is only used for "current" transitions. The general rule # is implemented via, roughly, POSIX time zone strings. # # Not all consumers of the IANA Time Zone Database support POSIX time zone # strings, and so, the TZif files can be built in a "fat" mode that adds extra # transitions (usually up to the year 2037). This means that if you want to # find the offset for a timestamp in a particular time zone before 2037, you # just need to do one very fast binary search on the explicit transitions. # # However, these explicit transitions up through 2037 aren't, strictly speaking, # required. For example, the DST transition rule in the United States is # perfectly described by a single POSIX time zone string: # # EST5EDT,M3.2.0,M11.1.0 # # Therefore, it isn't necessary to add any explicit transitions to, e.g., # `America/New_York` after the year 2007. (It would only become necessary if # the DST transition rule changed.) # # Thus, the TZif data files for the IANA Time Zone Database can _also_ be # generated in a "slim" fashion, where only the historical transitions are # included. Some platforms use the slim data by default, while others uses # the fat data. # # The problem is that determining the offset from a POSIX time zone can # generally be more costly than a simple binary search on explicit transitions. # That in turn means your time zone lookup performance can vary quite a bit due # to factors generally beyond your control. In order to mitigate this problem, # Jiff will automatically "fatten" up slim TZif data to include more explicit # transitions in memory. This smoothes out those performance differences. # # Users may want to disable this if they are sensitive to the extra memory # used. But generally speaking, the extra memory used is no more than what # would be used by "fat" TZif data files from `/usr/share/zoneinfo`. tz-fat = ["jiff-static?/tz-fat"] # When enabled, the `jiff::tz::get` and `jiff::tz::include` proc-macros # become available. These proc macros enable creating `TimeZone` values in a # `const` context for use in `core`-only environments. # # Users should generally prefer using Jiff's default zoneinfo integration at # runtime. On Unix systems, this will enable applications using Jiff to get # automatic tzdb updates when `/usr/share/zoneinfo` is updated without needing # to re-compile the application. # # Note that this introduces a build-time dependency on `jiff-tzdb`. static = ["static-tz", "jiff-static?/tzdb"] # When enabled, the `jiff::tz::include` macro becomes available. # # This proc-macro parses the TZif data (from a file) at compile time and # generates a special static structure that can be used by Jiff at runtime # to do tzdb lookups. This effectively provides a way to use time zones in # core-only environments without dynamic memory allocation. # # This is a subset of the functionality provided by `static`. Namely, this # doesn't result in a dependency on `jiff-tzdb`. It requires users to include # the time zone they want as a file, where as enabling `static` (which also # enables this feature, by necessity) permits using Jiff's bundled tzdb. static-tz = ["dep:jiff-static"] # This conditionally bundles tzdb into the binary depending on which platform # Jiff is being built for. tzdb-bundle-platform = ["dep:jiff-tzdb-platform", "alloc"] # This forces the jiff-tzdb crate to be included. If tzdb-zoneinfo is enabled, # then the system tzdb will take priority over the bundled database. tzdb-bundle-always = ["dep:jiff-tzdb", "alloc"] # This enables the system or "zoneinfo" time zone database. This is the # database that is typically found at /usr/share/zoneinfo on macOS and Linux. tzdb-zoneinfo = ["std"] # This enables the system concatenated time zone database. On some platforms, # like Android, this is the standard time zone database instead of the more # widespread `zoneinfo` directory created by `zic` itseld. # # This being enabled just means that some standard paths will be searched # for the concatenated database and it will be used if the standard zoneinfo # directory couldn't be found. tzdb-concatenated = ["std"] # This enables bindings to web browser APIs for retrieving the current time # and configured time zone. This ONLY applies on wasm32-unknown-unknown and # wasm64-unknown-unknown targets. Specifically, *not* on wasm32-wasi or # wasm32-unknown-emscripten targets. # # This is an "ecosystem" compromise due to the fact that there is no general # way to determine at compile time whether a wasm target is intended for use # on the "web." In practice, only wasm{32,64}-unknown-unknown targets are used # on the web, but wasm{32,64}-unknown-unknown targets can be used in non-web # contexts as well. Thus, the `js` feature should be enabled only by binaries, # tests or benchmarks when it is *known* that the application will be used in a # web context. # # Libraries that depend on Jiff should not need to define their own `js` # feature just to forward it to Jiff. Instead, application authors can depend # on Jiff directly and enable the `js` feature themselves. # # (This is the same dependency setup that the `getrandom` crate uses.) js = ["dep:wasm-bindgen", "dep:js-sys"] # When enabled, more aggressive inline annotations are used. This can # improve performance in some cases, particularly around the areas of parsing # and formatting. perf-inline = [] [dependencies] jiff-static = { version = "0.2", path = "crates/jiff-static", optional = true } jiff-tzdb = { version = "0.1.4", path = "crates/jiff-tzdb", optional = true } log = { version = "0.4.21", optional = true, default-features = false } serde = { version = "1.0.203", optional = true, default-features = false } # This ensures that `jiff-static` is always used with a compatible version # of `jiff`. Namely, since `jiff-static` emits code that relies on internal # Jiff APIs that aren't covered by semver, we only guarantee compatibility for # one version of Jiff for each release of `jiff-static`. # # (This is the same pattern that `serde` and `serde_derive` use as of # 2025-02-22.) # # This also helps with compilation, although in Jiff's case, we don't use # `syn` so this is less of a problem. # # See: https://github.com/matklad/macro-dep-test # [target.'cfg(any())'.dependencies] # jiff-static = { version = "=0.2.14", path = "crates/jiff-static" } # Note that the `cfg` gate for the `tzdb-bundle-platform` must repeat the # target gate on this dependency. The intent is that `tzdb-bundle-platform` # is enabled by default, but that the `tzdb-bundle-platform` crate is only # actually used on platforms without a system tzdb (i.e., Windows and wasm). [target.'cfg(any(windows, target_family = "wasm"))'.dependencies] jiff-tzdb-platform = { version = "0.1.3", path = "crates/jiff-tzdb-platform", optional = true } [target.'cfg(windows)'.dependencies.windows-sys] version = ">=0.52.0, <=0.59.*" default-features = false features = ["Win32_Foundation", "Win32_System_Time"] optional = true [target.'cfg(all(any(target_arch = "wasm32", target_arch = "wasm64"), target_os = "unknown"))'.dependencies] js-sys = { version = "0.3.50", optional = true } wasm-bindgen = { version = "0.2.70", optional = true } # For targets that have no atomics in `std`, we add a dependency on # `portable-atomic-util` for its Arc implementation. # # Note that for this to work, you may need to enable a `portable-atomic` # feature like `portable-atomic/unsafe-assume-single-core` or # `portable-atomic/critical-section`. # [target.'cfg(not(target_has_atomic = "ptr"))'.dependencies] # portable-atomic = { version = "1.10.0", default-features = false } # portable-atomic-util = { version = "0.2.4", default-features = false } [dev-dependencies] anyhow = "1.0.81" chrono = { version = "0.4.38", features = ["serde"] } chrono-tz = "0.10.0" humantime = "2.1.0" insta = "1.39.0" log = "0.4.21" # We force `serde` to be enabled in dev mode so that the docs render and test # correctly. We also enable `static` so that we can test our proc macros. jiff = { path = "./", default-features = false, features = ["serde", "static"] } quickcheck = { version = "1.0.3", default-features = false } serde = { version = "1.0.203", features = ["derive"] } serde_json = "1.0.117" serde_yaml = "0.9.34" tabwriter = "1.4.0" time = { version = "0.3.36", features = ["local-offset", "macros", "parsing"] } tzfile = "0.1.3" walkdir = "2.5.0" # Uncomment if you want to activate doc tests that import from `jiff_icu` # (currently only in `COMPARE.md`). Otherwise, this creates a circular # dependency and causes `jiff-icu` to get re-compiled all the time. # icu = { version = "1.5.0", features = ["std"] } # jiff-icu = { path = "./crates/jiff-icu" } # hifitime doesn't build on wasm for some reason, so exclude it there. [target.'cfg(not(target_family = "wasm"))'.dev-dependencies.hifitime] version = "3.9.0" [[test]] path = "tests/lib.rs" name = "integration" # This is just like the default 'test' profile, but debug_assertions are # disabled. This is important to cover for Jiff because we do a lot of extra # work in our internal ranged integer types when debug_assertions are enabled. # It also makes types fatter. It's very useful for catching overflow bugs. # But since there's a fair bit of logic there, it's also worth running tests # without debug_assertions enabled to exercise the *actual* code paths used # in production. [profile.testrelease] inherits = "test" debug-assertions = false [package.metadata.docs.rs] # We want to document all features. all-features = true # Since this crate's feature setup is pretty complicated, it is worth opting # into a nightly unstable option to show the features that need to be enabled # for public API items. To do that, we set 'docsrs', and when that's enabled, # we enable the 'doc_auto_cfg' feature. # # To test this locally, run: # # RUSTDOCFLAGS="--cfg docsrs" cargo +nightly doc --all-features rustdoc-args = ["--cfg", "docsrs"]