| 1 | [package] |
| 2 | name = "jiff" |
| 3 | version = "0.2.10" #:version |
| 4 | authors = ["Andrew Gallant <jamslam@gmail.com>" ] |
| 5 | license = "Unlicense OR MIT" |
| 6 | repository = "https://github.com/BurntSushi/jiff" |
| 7 | documentation = "https://docs.rs/jiff" |
| 8 | description = '' ' |
| 9 | A date-time library that encourages you to jump into the pit of success. |
| 10 | |
| 11 | This library is heavily inspired by the Temporal project. |
| 12 | ' '' |
| 13 | categories = ["date-and-time" , "no-std" ] |
| 14 | keywords = ["date" , "time" , "calendar" , "zone" , "duration" ] |
| 15 | edition = "2021" |
| 16 | autotests = false |
| 17 | autoexamples = false |
| 18 | rust-version = "1.70" |
| 19 | # We include `/tests/lib.rs` to squash a `cargo package` warning that the |
| 20 | # `integration` test target is being ignored. We don't include anything else |
| 21 | # so tests obviously won't work, but it makes `cargo package` quiet. |
| 22 | include = [ |
| 23 | "/src/**/*.rs" , |
| 24 | "/tests/lib.rs" , |
| 25 | "/*.md" , |
| 26 | "COPYING" , |
| 27 | "LICENSE-MIT" , |
| 28 | "UNLICENSE" , |
| 29 | ] |
| 30 | |
| 31 | [workspace] |
| 32 | members = [ |
| 33 | "crates/jiff-cli" , |
| 34 | "crates/jiff-static" , |
| 35 | "crates/jiff-tzdb" , |
| 36 | "crates/jiff-tzdb-platform" , |
| 37 | ] |
| 38 | |
| 39 | # Features are documented in the "Crate features" section of the crate docs: |
| 40 | # https://docs.rs/jiff/*/#crate-features |
| 41 | [features] |
| 42 | default = [ |
| 43 | "std" , |
| 44 | "tz-system" , |
| 45 | "tz-fat" , |
| 46 | "tzdb-bundle-platform" , |
| 47 | "tzdb-zoneinfo" , |
| 48 | "tzdb-concatenated" , |
| 49 | "perf-inline" , |
| 50 | ] |
| 51 | std = ["alloc" , "log?/std" , "serde?/std" ] |
| 52 | alloc = ["serde?/alloc" , "portable-atomic-util/alloc" ] |
| 53 | serde = ["dep:serde" ] |
| 54 | logging = ["dep:log" ] |
| 55 | |
| 56 | # When enabled, Jiff will include code that attempts to determine the "system" |
| 57 | # time zone. For example, on Unix systems, this is usually determined by |
| 58 | # looking at the symlink information on /etc/localtime. But in general, it's |
| 59 | # very platform specific and heuristic oriented. On some platforms, this may |
| 60 | # require extra dependencies. (For example, `windows-sys` on Windows.) |
| 61 | tz-system = ["std" , "dep:windows-sys" ] |
| 62 | |
| 63 | # When enabled, Jiff will "fatten" time zone data so that it contains more |
| 64 | # transitions. This uses a little extra heap memory (or binary size, when |
| 65 | # embedding time zone data into your binary) in exchange for generally faster |
| 66 | # time zone lookups. |
| 67 | # |
| 68 | # Why is this a thing? The TZif files that make up the IANA Time Zone Database |
| 69 | # contain both explicit transitions for when offsets change (e.g., twice a |
| 70 | # year for DST) _and_ a more general rule for dealing with offset changes |
| 71 | # that aren't explicitly listed. In the long ago, TZif data only contained the |
| 72 | # explicit transitions. Later, they added support for the general rule |
| 73 | # mechanism, which is only used for "current" transitions. The general rule |
| 74 | # is implemented via, roughly, POSIX time zone strings. |
| 75 | # |
| 76 | # Not all consumers of the IANA Time Zone Database support POSIX time zone |
| 77 | # strings, and so, the TZif files can be built in a "fat" mode that adds extra |
| 78 | # transitions (usually up to the year 2037). This means that if you want to |
| 79 | # find the offset for a timestamp in a particular time zone before 2037, you |
| 80 | # just need to do one very fast binary search on the explicit transitions. |
| 81 | # |
| 82 | # However, these explicit transitions up through 2037 aren't, strictly speaking, |
| 83 | # required. For example, the DST transition rule in the United States is |
| 84 | # perfectly described by a single POSIX time zone string: |
| 85 | # |
| 86 | # EST5EDT,M3.2.0,M11.1.0 |
| 87 | # |
| 88 | # Therefore, it isn't necessary to add any explicit transitions to, e.g., |
| 89 | # `America/New_York` after the year 2007. (It would only become necessary if |
| 90 | # the DST transition rule changed.) |
| 91 | # |
| 92 | # Thus, the TZif data files for the IANA Time Zone Database can _also_ be |
| 93 | # generated in a "slim" fashion, where only the historical transitions are |
| 94 | # included. Some platforms use the slim data by default, while others uses |
| 95 | # the fat data. |
| 96 | # |
| 97 | # The problem is that determining the offset from a POSIX time zone can |
| 98 | # generally be more costly than a simple binary search on explicit transitions. |
| 99 | # That in turn means your time zone lookup performance can vary quite a bit due |
| 100 | # to factors generally beyond your control. In order to mitigate this problem, |
| 101 | # Jiff will automatically "fatten" up slim TZif data to include more explicit |
| 102 | # transitions in memory. This smoothes out those performance differences. |
| 103 | # |
| 104 | # Users may want to disable this if they are sensitive to the extra memory |
| 105 | # used. But generally speaking, the extra memory used is no more than what |
| 106 | # would be used by "fat" TZif data files from `/usr/share/zoneinfo`. |
| 107 | tz-fat = ["jiff-static?/tz-fat" ] |
| 108 | |
| 109 | # When enabled, the `jiff::tz::get` and `jiff::tz::include` proc-macros |
| 110 | # become available. These proc macros enable creating `TimeZone` values in a |
| 111 | # `const` context for use in `core`-only environments. |
| 112 | # |
| 113 | # Users should generally prefer using Jiff's default zoneinfo integration at |
| 114 | # runtime. On Unix systems, this will enable applications using Jiff to get |
| 115 | # automatic tzdb updates when `/usr/share/zoneinfo` is updated without needing |
| 116 | # to re-compile the application. |
| 117 | # |
| 118 | # Note that this introduces a build-time dependency on `jiff-tzdb`. |
| 119 | static = ["static-tz" , "jiff-static?/tzdb" ] |
| 120 | |
| 121 | # When enabled, the `jiff::tz::include` macro becomes available. |
| 122 | # |
| 123 | # This proc-macro parses the TZif data (from a file) at compile time and |
| 124 | # generates a special static structure that can be used by Jiff at runtime |
| 125 | # to do tzdb lookups. This effectively provides a way to use time zones in |
| 126 | # core-only environments without dynamic memory allocation. |
| 127 | # |
| 128 | # This is a subset of the functionality provided by `static`. Namely, this |
| 129 | # doesn't result in a dependency on `jiff-tzdb`. It requires users to include |
| 130 | # the time zone they want as a file, where as enabling `static` (which also |
| 131 | # enables this feature, by necessity) permits using Jiff's bundled tzdb. |
| 132 | static-tz = ["dep:jiff-static" ] |
| 133 | |
| 134 | # This conditionally bundles tzdb into the binary depending on which platform |
| 135 | # Jiff is being built for. |
| 136 | tzdb-bundle-platform = ["dep:jiff-tzdb-platform" , "alloc" ] |
| 137 | |
| 138 | # This forces the jiff-tzdb crate to be included. If tzdb-zoneinfo is enabled, |
| 139 | # then the system tzdb will take priority over the bundled database. |
| 140 | tzdb-bundle-always = ["dep:jiff-tzdb" , "alloc" ] |
| 141 | |
| 142 | # This enables the system or "zoneinfo" time zone database. This is the |
| 143 | # database that is typically found at /usr/share/zoneinfo on macOS and Linux. |
| 144 | tzdb-zoneinfo = ["std" ] |
| 145 | |
| 146 | # This enables the system concatenated time zone database. On some platforms, |
| 147 | # like Android, this is the standard time zone database instead of the more |
| 148 | # widespread `zoneinfo` directory created by `zic` itseld. |
| 149 | # |
| 150 | # This being enabled just means that some standard paths will be searched |
| 151 | # for the concatenated database and it will be used if the standard zoneinfo |
| 152 | # directory couldn't be found. |
| 153 | tzdb-concatenated = ["std" ] |
| 154 | |
| 155 | # This enables bindings to web browser APIs for retrieving the current time |
| 156 | # and configured time zone. This ONLY applies on wasm32-unknown-unknown and |
| 157 | # wasm64-unknown-unknown targets. Specifically, *not* on wasm32-wasi or |
| 158 | # wasm32-unknown-emscripten targets. |
| 159 | # |
| 160 | # This is an "ecosystem" compromise due to the fact that there is no general |
| 161 | # way to determine at compile time whether a wasm target is intended for use |
| 162 | # on the "web." In practice, only wasm{32,64}-unknown-unknown targets are used |
| 163 | # on the web, but wasm{32,64}-unknown-unknown targets can be used in non-web |
| 164 | # contexts as well. Thus, the `js` feature should be enabled only by binaries, |
| 165 | # tests or benchmarks when it is *known* that the application will be used in a |
| 166 | # web context. |
| 167 | # |
| 168 | # Libraries that depend on Jiff should not need to define their own `js` |
| 169 | # feature just to forward it to Jiff. Instead, application authors can depend |
| 170 | # on Jiff directly and enable the `js` feature themselves. |
| 171 | # |
| 172 | # (This is the same dependency setup that the `getrandom` crate uses.) |
| 173 | js = ["dep:wasm-bindgen" , "dep:js-sys" ] |
| 174 | |
| 175 | # When enabled, more aggressive inline annotations are used. This can |
| 176 | # improve performance in some cases, particularly around the areas of parsing |
| 177 | # and formatting. |
| 178 | perf-inline = [] |
| 179 | |
| 180 | [dependencies] |
| 181 | jiff-static = { version = "0.2" , path = "crates/jiff-static" , optional = true } |
| 182 | jiff-tzdb = { version = "0.1.4" , path = "crates/jiff-tzdb" , optional = true } |
| 183 | log = { version = "0.4.21" , optional = true, default-features = false } |
| 184 | serde = { version = "1.0.203" , optional = true, default-features = false } |
| 185 | |
| 186 | # This ensures that `jiff-static` is always used with a compatible version |
| 187 | # of `jiff`. Namely, since `jiff-static` emits code that relies on internal |
| 188 | # Jiff APIs that aren't covered by semver, we only guarantee compatibility for |
| 189 | # one version of Jiff for each release of `jiff-static`. |
| 190 | # |
| 191 | # (This is the same pattern that `serde` and `serde_derive` use as of |
| 192 | # 2025-02-22.) |
| 193 | # |
| 194 | # This also helps with compilation, although in Jiff's case, we don't use |
| 195 | # `syn` so this is less of a problem. |
| 196 | # |
| 197 | # See: https://github.com/matklad/macro-dep-test |
| 198 | [target.'cfg(any())'.dependencies] |
| 199 | jiff-static = { version = "=0.2.10" , path = "crates/jiff-static" } |
| 200 | |
| 201 | # Note that the `cfg` gate for the `tzdb-bundle-platform` must repeat the |
| 202 | # target gate on this dependency. The intent is that `tzdb-bundle-platform` |
| 203 | # is enabled by default, but that the `tzdb-bundle-platform` crate is only |
| 204 | # actually used on platforms without a system tzdb (i.e., Windows and wasm). |
| 205 | [target.'cfg(any(windows, target_family = "wasm"))'.dependencies] |
| 206 | jiff-tzdb-platform = { version = "0.1.3" , path = "crates/jiff-tzdb-platform" , optional = true } |
| 207 | |
| 208 | [target.'cfg(windows)'.dependencies.windows-sys] |
| 209 | version = ">=0.52.0, <=0.59.*" |
| 210 | default-features = false |
| 211 | features = ["Win32_Foundation" , "Win32_System_Time" ] |
| 212 | optional = true |
| 213 | |
| 214 | [target.'cfg(all(any(target_arch = "wasm32", target_arch = "wasm64"), target_os = "unknown"))'.dependencies] |
| 215 | js-sys = { version = "0.3.50" , optional = true } |
| 216 | wasm-bindgen = { version = "0.2.70" , optional = true } |
| 217 | |
| 218 | # For targets that have no atomics in `std`, we add a dependency on |
| 219 | # `portable-atomic-util` for its Arc implementation. |
| 220 | # |
| 221 | # Note that for this to work, you may need to enable a `portable-atomic` |
| 222 | # feature like `portable-atomic/unsafe-assume-single-core` or |
| 223 | # `portable-atomic/critical-section`. |
| 224 | [target.'cfg(not(target_has_atomic = "ptr"))'.dependencies] |
| 225 | portable-atomic = { version = "1.10.0" , default-features = false } |
| 226 | portable-atomic-util = { version = "0.2.4" , default-features = false } |
| 227 | |
| 228 | [dev-dependencies] |
| 229 | anyhow = "1.0.81" |
| 230 | chrono = { version = "0.4.38" , features = ["serde" ] } |
| 231 | chrono-tz = "0.10.0" |
| 232 | humantime = "2.1.0" |
| 233 | insta = "1.39.0" |
| 234 | # We force `serde` to be enabled in dev mode so that the docs render and test |
| 235 | # correctly. We also enable `static` so that we can test our proc macros. |
| 236 | jiff = { path = "./" , default-features = false, features = ["serde" , "static" ] } |
| 237 | quickcheck = { version = "1.0.3" , default-features = false } |
| 238 | serde = { version = "1.0.203" , features = ["derive" ] } |
| 239 | serde_json = "1.0.117" |
| 240 | serde_yaml = "0.9.34" |
| 241 | tabwriter = "1.4.0" |
| 242 | time = { version = "0.3.36" , features = ["local-offset" , "macros" , "parsing" ] } |
| 243 | tzfile = "0.1.3" |
| 244 | walkdir = "2.5.0" |
| 245 | |
| 246 | # Uncomment if you want to activate doc tests that import from `jiff_icu` |
| 247 | # (currently only in `COMPARE.md`). Otherwise, this creates a circular |
| 248 | # dependency and causes `jiff-icu` to get re-compiled all the time. |
| 249 | # icu = { version = "1.5.0", features = ["std"] } |
| 250 | # jiff-icu = { path = "./crates/jiff-icu" } |
| 251 | |
| 252 | # hifitime doesn't build on wasm for some reason, so exclude it there. |
| 253 | [target.'cfg(not(target_family = "wasm"))'.dev-dependencies.hifitime] |
| 254 | version = "3.9.0" |
| 255 | |
| 256 | [[test]] |
| 257 | path = "tests/lib.rs" |
| 258 | name = "integration" |
| 259 | |
| 260 | # This is just like the default 'test' profile, but debug_assertions are |
| 261 | # disabled. This is important to cover for Jiff because we do a lot of extra |
| 262 | # work in our internal ranged integer types when debug_assertions are enabled. |
| 263 | # It also makes types fatter. It's very useful for catching overflow bugs. |
| 264 | # But since there's a fair bit of logic there, it's also worth running tests |
| 265 | # without debug_assertions enabled to exercise the *actual* code paths used |
| 266 | # in production. |
| 267 | [profile.testrelease] |
| 268 | inherits = "test" |
| 269 | debug-assertions = false |
| 270 | |
| 271 | [package.metadata.docs.rs] |
| 272 | # We want to document all features. |
| 273 | all-features = true |
| 274 | # Since this crate's feature setup is pretty complicated, it is worth opting |
| 275 | # into a nightly unstable option to show the features that need to be enabled |
| 276 | # for public API items. To do that, we set 'docsrs', and when that's enabled, |
| 277 | # we enable the 'doc_auto_cfg' feature. |
| 278 | # |
| 279 | # To test this locally, run: |
| 280 | # |
| 281 | # RUSTDOCFLAGS="--cfg docsrs" cargo +nightly doc --all-features |
| 282 | rustdoc-args = ["--cfg" , "docsrs" ] |
| 283 | |