calternal_plugin::zone
The user’s time zone and local-day arithmetic (#141).
A day key (YYYY-MM-DD: a Daily note, a Calendar day, date:today in
search) is a date in the user’s IANA zone, never in UTC. In IST the local
date is one day ahead of UTC from 00:00 to 05:30, and in
America/Los_Angeles it is one day behind from 17:00 (16:00 in summer) to
midnight. A server that takes “today” from Utc::now() puts entries on
the wrong Daily note in that window.
Resolution order, the same for every route:
- The zone the request carries: the
X-Calternal-Timezoneheader, which every web request sends (@calternal/api-client), or a route’s own explicittzparameter or body field. An invalid value is an error, never a silent fallback, so a client bug cannot move data to another day. - The user setting
timezonein.calternal/settings.json, for requests that carry no zone (CalDAV clients, the CLI, background work). - UTC, only when neither exists.
Source: crates/calternal-plugin/src/zone.rs
Re-exports
Section titled “Re-exports”pub use chrono_tz::Tz
Structs
Section titled “Structs”InvalidZone
Section titled “InvalidZone”pub struct InvalidZone;A zone name that is not a known IANA zone.
Implements: Clone, Copy, Debug, PartialEq, Eq, std::fmt::Display, std::error::Error
Source: crates/calternal-plugin/src/zone.rs:34
Functions
Section titled “Functions”day_bounds
Section titled “day_bounds”pub fn day_bounds(day: NaiveDate, zone: Tz) -> (DateTime<Utc>, DateTime<Utc>)The half-open instant range [start, end) of the local day day.
Source: crates/calternal-plugin/src/zone.rs:132
day_start
Section titled “day_start”pub fn day_start(day: NaiveDate, zone: Tz) -> DateTime<Utc>The first instant of the local day day in zone.
Midnight does not exist on some DST change days (America/Santiago, Asia/Beirut and others move 00:00 to 01:00), so the first valid local time of the day is used. In a repeated hour the earlier instant wins. A day that a zone skipped entirely (Pacific/Apia on 2011-12-30) starts where the next day starts, so the range of that day is empty.
Source: crates/calternal-plugin/src/zone.rs:114
header_zone
Section titled “header_zone”pub fn header_zone(headers: &HeaderMap) -> Result<Option<Tz>, InvalidZone>The zone in the X-Calternal-Timezone header, if the request has one.
Source: crates/calternal-plugin/src/zone.rs:54
local_day
Section titled “local_day”pub fn local_day(instant: DateTime<Utc>, zone: Tz) -> NaiveDateThe local date of an instant in zone.
Source: crates/calternal-plugin/src/zone.rs:98
parse_zone
Section titled “parse_zone”pub fn parse_zone(name: &str) -> Result<Tz, InvalidZone>Parse an IANA zone name. Rejects empty and oversized values before the table lookup.
Source: crates/calternal-plugin/src/zone.rs:46
request_zone
Section titled “request_zone”pub fn request_zone(headers: &HeaderMap, root: &Root, user: &str) -> Result<Tz, InvalidZone>resolve_zone for a request that carries its zone in the header.
Source: crates/calternal-plugin/src/zone.rs:90
resolve_zone
Section titled “resolve_zone”pub fn resolve_zone(requested: Option<&str>, root: &Root, user: &str) -> Result<Tz, InvalidZone>The user’s zone for one request: requested (a route’s own tz value or
the header), else the user setting, else UTC. See the module docs.
Source: crates/calternal-plugin/src/zone.rs:82
settings_document_zone
Section titled “settings_document_zone”pub fn settings_document_zone(settings: &[u8]) -> Option<Tz>The timezone field of a settings document. A missing, malformed or
unknown value is None: the setting is optional.
Source: crates/calternal-plugin/src/zone.rs:63
settings_zone
Section titled “settings_zone”pub fn settings_zone(root: &Root, user: &str) -> Option<Tz>The user’s timezone setting from .calternal/settings.json.
Source: crates/calternal-plugin/src/zone.rs:72
pub fn today(zone: Tz) -> NaiveDateToday in zone.
Source: crates/calternal-plugin/src/zone.rs:103
Constants
Section titled “Constants”TIMEZONE_HEADER
Section titled “TIMEZONE_HEADER”pub const TIMEZONE_HEADER: &strThe request header that carries the client’s IANA zone.