devela::_dep::jiff

Module civil

Available on crate features dep_jiff and alloc only.
Expand description

Facilities for dealing with inexact dates and times.

§Overview

The essential types in this module are:

  • Date is a specific day in the Gregorian calendar.
  • Time is a specific wall clock time.
  • DateTime is a combination of a day and a time.

Moreover, the date and time free functions can be used to conveniently create values of any of three types above:

use jiff::civil::{date, time};

assert_eq!(date(2024, 7, 31).to_string(), "2024-07-31");
assert_eq!(time(15, 20, 0, 123).to_string(), "15:20:00.000000123");
assert_eq!(
    date(2024, 7, 31).at(15, 20, 0, 123).to_string(),
    "2024-07-31T15:20:00.000000123",
);
assert_eq!(
    time(15, 20, 0, 123).on(2024, 7, 31).to_string(),
    "2024-07-31T15:20:00.000000123",
);

§What is “civil” time?

A civil datetime is a calendar date and a clock time. It also goes by the names “naive,” “local” or “plain.” The most important thing to understand about civil time is that it does not correspond to a precise instant in time. This is in contrast to types like Timestamp and Zoned, which do correspond to a precise instant in time (to nanosecond precision).

Because a civil datetime never has a time zone associated with it, and because some time zones have transitions that skip or repeat clock times, it follows that not all civil datetimes precisely map to a single instant in time. For example, 2024-03-10 02:30 never existed on a clock in America/New_York because the 2 o’clock hour was skipped when the clocks were “moved forward” for daylight saving time. Conversely, 2024-11-03 01:30 occurred twice in America/New_York because the 1 o’clock hour was repeated when clocks were “moved backward” for daylight saving time. (When time is skipped, it’s called a “gap.” When time is repeated, it’s called a “fold.”)

In contrast, an instant in time (that is, Timestamp or Zoned) can always be converted to a civil datetime. And, when a civil datetime is combined with its time zone identifier and its offset, the resulting machine readable string is unambiguous 100% of the time:

use jiff::{civil::date, tz::TimeZone};

let tz = TimeZone::get("America/New_York")?;
let dt = date(2024, 11, 3).at(1, 30, 0, 0);
// It's ambiguous, so asking for an unambiguous instant presents an error!
assert!(tz.to_ambiguous_zoned(dt).unambiguous().is_err());
// Gives you the earlier time in a fold, i.e., before DST ends:
assert_eq!(
    tz.to_ambiguous_zoned(dt).earlier()?.to_string(),
    "2024-11-03T01:30:00-04:00[America/New_York]",
);
// Gives you the later time in a fold, i.e., after DST ends.
// Notice the offset change from the previous example!
assert_eq!(
    tz.to_ambiguous_zoned(dt).later()?.to_string(),
    "2024-11-03T01:30:00-05:00[America/New_York]",
);
// "Just give me something reasonable"
assert_eq!(
    tz.to_ambiguous_zoned(dt).compatible()?.to_string(),
    "2024-11-03T01:30:00-04:00[America/New_York]",
);

§When should I use civil time?

Here is a likely non-exhaustive list of reasons why you might want to use civil time:

  • When you want or need to deal with calendar and clock units as an intermediate step before and/or after associating it with a time zone. For example, perhaps you need to parse strings like 2000-01-01T00:00:00 from a CSV file that have no time zone or offset information, but the time zone is implied through some out-of-band mechanism.
  • When time zone is actually irrelevant. For example, a fitness tracking app that reminds you to work-out at 6am local time, regardless of which time zone you’re in.
  • When you need to perform arithmetic that deliberately ignores daylight saving time.
  • When interacting with legacy systems or systems that specifically do not support time zones.

Structs§

Enums§

  • The era corresponding to a particular year.
  • A representation for the day of the week.

Functions§

  • Creates a new Date value in a const context.
  • Creates a new DateTime value in a const context.
  • Creates a new Time value in a const context.