commit 0e1a16ac41454af181f13c157bb5735052387b60
parent 8283ddfb77f5e894fdacc091e46fc4d4fdeb1284
Author: Byron Torres <b@torresjrjr.com>
Date: Sun, 14 May 2023 02:57:12 +0100
time::chrono: use daydate, daytime; improve docs
This commit renames the .date and .time fields of
[[time::chrono::mooment]] to .daydate and .daytime, to disambiguate
between the "date" noun's reserved meaning of a general date, and a
scalar day number date; and between the problematic multiple definitions
of the "time" noun and the time-of-day. "time" is too general to be
anything but a module name.
Various docs are updated, and the READMEs are made terser.
Diffstat:
13 files changed, 165 insertions(+), 194 deletions(-)
diff --git a/time/chrono/README b/time/chrono/README
@@ -1,22 +1,13 @@
-The time::chrono submodule provides the basis for chronology in Hare, namely
-[[timescale]]s (leap second handling), [[timezone]]s, and the [[moment]] type,
-an abstracted date/time object for external modules to interface with.
-
-For working with the Gregorian chronology, see the [[time::date]] module.
-
-Hare defines a chronology as a system used to name and order moments in time. In
-practice, a chronology is the combination of a calendar (for handling days) and
-a wall clock (for handling times throughout a day).
-
-This module implements a small chronology of dates & times. A moment observes
-certain chronological values according to its [[locality]]. The "observe"
-functions [[date]], [[time]], and [[zone]] obtain these values.
-
-Higher level modules like [[time::date]] expand upon this with more complex
-chronological values (years, hours, etc.). The [[time::date::date]] type
-embeds [[moment]], and other modules implementing other chronologies may
-interoperate with their own extension types.
-
-[[time::instant]]s can be [[convert]]ed via the [[timescale]] interface. The
-[[tai]] timescale acts as the central intermediary timescale. Other timescales
-are expected to be able to convert their instants to TAI and back.
+The time::chrono module provides timescale utilities, and the foundations for
+chronology with the [[moment]] type, an abstract, extendable date/time object.
+For the Gregorian chronology, see the [[time::date]] module.
+
+Hare defines a chronology as a system for naming and ordering moments in time.
+In practice, it is the combination of a calendar and wall clock. This module
+implements a simple date & time chronology with [[moment]], which observes
+certain chronological values according to its [[locality]]. The observer
+functions [[daydate]], [[daytime]], and [[mzone]] obtain these values.
+Use [[in]] to localize a moment to another [[locality]]; consult [[tz]].
+
+The [[timescale]] interface facilitates leap-second aware [[convert]]ion of
+[[time::instant]]s. The [[tai]] timescale is the default intermediary timescale.
diff --git a/time/chrono/chronology.ha b/time/chrono/chronology.ha
@@ -5,36 +5,35 @@ use time;
// Invalid [[moment]].
export type invalid = !void;
-// A moment in time within a [[locality]]. Create one with [[new]].
-//
-// Moments extend the [[time::instant]] type and couples it with a [[timescale]]
-// via its [[locality]] field.
+// A moment in time within a [[locality]]. Create one with [[new]]. This type
+// extends the [[time::instant]] type and couples it with a [[timescale]] via
+// its [[locality]] field.
//
// This object should be treated as private and immutable. Directly mutating its
// fields causes undefined behavour when used with module functions. Likewise,
// interrogating the fields' type and value (e.g. using match statements) is
// also improper.
//
-// Moments observe a date, time-of-day, and [[zone]], which are evaluated and
-// obtained with the [[date]], [[time]], and [[mzone]] "observe" functions.
-// These values are derived from the embedded instant and locality information,
-// and thus are guaranteed to be valid.
+// Moments observe a daydate, time-of-day, and [[zone]], which are evaluated,
+// cached and obtained with the observer functions [[daydate]], [[daytime]], and
+// [[mzone]]. These values are derived from the embedded instant and locality
+// information, and thus are guaranteed to be valid.
export type moment = struct {
- // The embedded [[time::instant]] of this moment
+ // The embedded [[time::instant]].
time::instant,
- // The [[locality]] with which to interpret this moment
+ // The [[locality]] with which to interpret this moment.
loc: locality,
- // The observed [[zone]]
+ // The observed [[zone]].
zone: nullable *zone,
- // The observed ordinal day (on Earth or otherwise)
- // since an abitrary epoch, like the Hare epoch 1970-01-01
- date: (void | i64),
+ // The observed daydate (scalar day number)
+ // since an abitrary epoch (e.g. the Unix epoch 1970-01-01).
+ daydate: (void | i64),
- // The observed time since the start of the day
- time: (void | time::duration),
+ // The observed time-of-day (amount of daytime progressed in a day).
+ daytime: (void | time::duration),
};
// Creates a new [[moment]]. Uses a given [[time::instant]] with a [[timescale]]
@@ -45,12 +44,12 @@ export fn new(loc: locality, i: time::instant) moment = {
nsec = i.nsec,
loc = loc,
zone = null,
- date = void,
- time = void,
+ daydate = void,
+ daytime = void,
};
};
-// Evalutes, caches, and returns a [[moment]]'s observed [[zone]].
+// Observes a [[moment]]'s observed [[zone]].
export fn mzone(m: *moment) zone = {
match (m.zone) {
case let z: *zone =>
@@ -62,43 +61,43 @@ export fn mzone(m: *moment) zone = {
};
};
-// Evaluates, caches, and returns a [[moment]]'s observed epochal date.
+// Observes a [[moment]]'s observed daydate (day number since epoch).
//
// For moments with [[locality]]s based on the [[utc]], [[tai]], [[gps]], and
// similar timescales, their epoch date should be interpreted as the Unix epoch
// (1970 Janurary 1st). Other timescales may suggest their own interpretations
// applicable to other chronologies.
-export fn date(m: *moment) i64 = {
- match (m.date) {
- case let d: i64 =>
- return d;
+export fn daydate(m: *moment) i64 = {
+ match (m.daydate) {
+ case let dd: i64 =>
+ return dd;
case void =>
- const (d, t) = calc_datetime(
+ const (dd, dt) = calc_datetime(
m.loc, *(m: *time::instant), mzone(m).zoff,
);
- m.time = t;
- m.date = d;
- return d;
+ m.daytime = dt;
+ m.daydate = dd;
+ return dd;
};
};
-// Evaluates, caches, and returns a [[moment]]'s observed time-of-day as a
-// [[time::duration]] since the start of a day.
-export fn time(m: *moment) time::duration = {
- match (m.time) {
- case let t: time::duration =>
- return t;
+// Observes a [[moment]]'s observed time-of-day (amount of daytime progressed in
+// a day) as a [[time::duration]].
+export fn daytime(m: *moment) time::duration = {
+ match (m.daytime) {
+ case let dt: time::duration =>
+ return dt;
case void =>
- const (d, t) = calc_datetime(
+ const (dd, dt) = calc_datetime(
m.loc, *(m: *time::instant), mzone(m).zoff,
);
- m.time = t;
- m.date = d;
- return t;
+ m.daytime = dt;
+ m.daydate = dd;
+ return dt;
};
};
-// Calculates the observed date and time-of-day of a [[time::instant]] in a
+// Calculates the observed daydate and time-of-day of a [[time::instant]] in a
// [[locality]] at a particular zone offset.
fn calc_datetime(
loc: locality,
@@ -108,44 +107,44 @@ fn calc_datetime(
const i = time::add(inst, zoff);
const day = loc.daylength;
const daysec = day / time::SECOND;
- const d = if (i.sec >= 0) i.sec / daysec else (i.sec + 1) / daysec - 1;
- const t = ((i.sec % daysec + daysec) * time::SECOND + i.nsec) % day;
- return (d, t);
+ const dd = if (i.sec >= 0) i.sec / daysec else (i.sec + 1) / daysec - 1;
+ const dt = ((i.sec % daysec + daysec) * time::SECOND + i.nsec) % day;
+ return (dd, dt);
};
-// Creates a [[moment]] from a given [[locality]], zone offset, date, and
+// Creates a [[moment]] from a given [[locality]], zone offset, daydate, and
// time-of-day.
export fn from_datetime(
loc: locality,
zo: time::duration,
- d: i64,
- t: time::duration,
+ dd: i64,
+ dt: time::duration,
) moment = {
- const inst = calc_instant(loc.daylength, zo, d, t);
+ const inst = calc_instant(loc.daylength, zo, dd, dt);
return moment {
sec = inst.sec,
nsec = inst.nsec,
loc = loc,
zone = null,
- date = d,
- time = t,
+ daydate = dd,
+ daytime = dt,
};
};
fn calc_instant(
day: time::duration, // length of a day
zo: time::duration, // zone offset
- d: i64, // date since epoch
- t: time::duration, // time since start of day
+ dd: i64, // date since epoch
+ dt: time::duration, // time since start of day
) time::instant = {
const daysec = (day / time::SECOND): i64;
const dayrem = day % time::SECOND;
let i = time::instant {
- sec = d * daysec,
+ sec = dd * daysec,
nsec = 0,
};
- i = time::add(i, d * dayrem);
- i = time::add(i, t);
+ i = time::add(i, dd * dayrem);
+ i = time::add(i, dt);
i = time::add(i, -zo);
return i;
};
diff --git a/time/chrono/timescale.ha b/time/chrono/timescale.ha
@@ -121,7 +121,7 @@ fn tai_convfrom(ts: *timescale, i: time::instant) ([]time::instant | void) = {
// During a program's initialization, this timescale initializes by loading its
// UTC/TAI leap second data from [[UTC_LEAPSECS_FILE]]; otherwise, fails
// silently. If failed, any attempt to consult UTC leapsec data (e.g. calling
-// [[convert]] on UTC) causes an abort. This includes [[chrono::in]].
+// [[convert]] on UTC) causes an abort. This includes [[in]].
export const utc: timescale = timescale {
name = "Coordinated Universal Time",
abbr = "UTC",
diff --git a/time/date/README b/time/date/README
@@ -1,33 +1,20 @@
The time::date module implements the common international Gregorian chronology,
based on the astronomically numbered proleptic Gregorian calendar, as per ISO
8601, and the common 24 hour clock. It provides [[date]], a representation of
-civil date/time, and an extension of the [[time::chrono::moment]] type,
-optimized for dealing with the Gregorian chronology.
-
+civil date/time and a optimized extension of the [[time::chrono::moment]] type.
The [[time::chrono]] module has many useful functions which interoperate with
dates. Any [[time::chrono]] function which accepts *moment also accepts *date.
-Dates are created with [[new]], [[now]], or one of the "from_" functions.
-Alternatively, use the [[virtual]] interface to construct a date.
-
-The [[virtual]] interface, coupled with the [[realize]] function, provides a way
-to handle uncertain or invalid date/time information intermediately, transform
-date/time values with arithmetic, [[parse]] date/time strings, and construct new
-dates safely.
-
-The "observe" functions accept a *date and evaluates one of its observed
-chronological values. This includes [[year]], [[month]], [[day]], [[hour]] etc.
-
-Dates may be localized to different [[time::chrono::locality]]s via the [[in]]
-function. The "observe" functions will evaluate the correct values accordingly.
-You'll find a standard selection of world timezones in [[time::chrono]].
-
+Dates are created using [[new]], [[now]], [[nowutc]], or a "from_" function.
+Alternatively, the [[virtual]]/[[realize]] interface can handle uncertain or
+invalid date/time information, and construct new dates incrementally and safely.
+The observer functions ([[year]], [[hour]], etc.) evaluate a date's observed
+chronological values, adjusted for its associated [[time::chrono::locality]].
+Use [[in]] to localize a date to another locality; consult [[time::chrono::tz]].
See [[parse]] and [[format]] for working with date/time strings.
-Timescale-wise date arithmetic using the [[time::duration]] type is possible,
-with [[add]] and [[time::chrono::diff]].
-
-Chronology-wise date arithmetic using the [[period]] type is possible, with
-[[reckon]] and the [[calculus]] type, [[pdiff]], [[unitdiff]], and [[truncate]].
-Note that chronological and calendrical arithmetic is highly irregular due to
+Date arithmetic operations are categorized into "timescalar" or "chronological".
+Timescalar uses [[time::duration]]; see [[add]], [[time::chrono::diff]].
+Chronological uses [[period]]; see [[reckon]], [[pdiff]], [[unitdiff]],
+[[truncate]]. Note that calendrical arithmetic is highly irregular due to field
overflows and timezone discontinuities, so think carefully about what you want.
diff --git a/time/date/arithmetic.ha b/time/date/arithmetic.ha
@@ -107,7 +107,7 @@ export fn unitdiff(a: date, b: date, u: unit) i64 = {
case unit::WEEK =>
return unitdiff(a, b, unit::DAY) / 7;
case unit::DAY =>
- return chrono::date(&b) - chrono::date(&a);
+ return chrono::daydate(&b) - chrono::daydate(&a);
case unit::HOUR =>
return unitdiff(a, b, unit::DAY) * 24 + pdiff(a, b).hours;
case unit::MINUTE =>
@@ -147,8 +147,8 @@ export fn truncate(d: date, u: unit) date = {
0, 0, 0, 0,
)!;
case unit::WEEK =>
- const date = chrono::date(&d) - _weekday(&d);
- const ymd = calc_ymd(date);
+ const dd = chrono::daydate(&d) - _weekday(&d);
+ const ymd = calc_ymd(dd);
yield new(d.loc, chrono::mzone(&d).zoff,
ymd.0, ymd.1, ymd.2,
0, 0, 0, 0,
diff --git a/time/date/chronology.ha b/time/date/chronology.ha
@@ -7,46 +7,46 @@ use time::chrono;
// These functions are renamed to avoid namespace conflicts, like in the
// parameters of the [[new]] function.
-// Returns a [[date]]'s era.
+// Observes a [[date]]'s era.
export fn era(d: *date) int = _era(d);
-// Returns a [[date]]'s year.
+// Observes a [[date]]'s year.
export fn year(d: *date) int = _year(d);
-// Returns a [[date]]'s month of the year.
+// Observes a [[date]]'s month of the year.
export fn month(d: *date) int = _month(d);
-// Returns a [[date]]'s day of the month.
+// Observes a [[date]]'s day of the month.
export fn day(d: *date) int = _day(d);
-// Returns a [[date]]'s day of the week; Monday=0 to Sunday=6.
+// Observes a [[date]]'s day of the week; Monday=0 to Sunday=6.
export fn weekday(d: *date) int = _weekday(d);
-// Returns a [[date]]'s ordinal day of the year.
+// Observes a [[date]]'s ordinal day of the year.
export fn yearday(d: *date) int = _yearday(d);
-// Returns a [[date]]'s ISO week-numbering year.
+// Observes a [[date]]'s ISO week-numbering year.
export fn isoweekyear(d: *date) int = _isoweekyear(d);
-// Returns a [[date]]'s Gregorian week starting Monday.
+// Observes a [[date]]'s Gregorian week starting Monday.
export fn week(d: *date) int = _week(d);
-// Returns a [[date]]'s Gregorian week starting Sunday.
+// Observes a [[date]]'s Gregorian week starting Sunday.
export fn sundayweek(d: *date) int = _sundayweek(d);
-// Returns a [[date]]'s ISO week.
+// Observes a [[date]]'s ISO week.
export fn isoweek(d: *date) int = _isoweek(d);
-// Returns a [[date]]'s hour of the day.
+// Observes a [[date]]'s hour of the day.
export fn hour(d: *date) int = _hour(d);
-// Returns a [[date]]'s minute of the hour.
+// Observes a [[date]]'s minute of the hour.
export fn minute(d: *date) int = _minute(d);
-// Returns a [[date]]'s second of the minute.
+// Observes a [[date]]'s second of the minute.
export fn second(d: *date) int = _second(d);
-// Returns a [[date]]'s nanosecond of the second.
+// Observes a [[date]]'s nanosecond of the second.
export fn nanosecond(d: *date) int = _nanosecond(d);
fn _era(d: *date) int = {
@@ -65,7 +65,7 @@ fn _era(d: *date) int = {
fn _year(d: *date) int = {
match (d.year) {
case void =>
- const ymd = calc_ymd(chrono::date(d));
+ const ymd = calc_ymd(chrono::daydate(d));
d.year = ymd.0;
d.month = ymd.1;
d.day = ymd.2;
@@ -78,7 +78,7 @@ fn _year(d: *date) int = {
fn _month(d: *date) int = {
match (d.month) {
case void =>
- const ymd = calc_ymd(chrono::date(d));
+ const ymd = calc_ymd(chrono::daydate(d));
d.year = ymd.0;
d.month = ymd.1;
d.day = ymd.2;
@@ -91,7 +91,7 @@ fn _month(d: *date) int = {
fn _day(d: *date) int = {
match (d.day) {
case void =>
- const ymd = calc_ymd(chrono::date(d));
+ const ymd = calc_ymd(chrono::daydate(d));
d.year = ymd.0;
d.month = ymd.1;
d.day = ymd.2;
@@ -104,7 +104,7 @@ fn _day(d: *date) int = {
fn _weekday(d: *date) int = {
match (d.weekday) {
case void =>
- d.weekday = calc_weekday(chrono::date(d));
+ d.weekday = calc_weekday(chrono::daydate(d));
return d.weekday: int;
case let y: int =>
return y;
@@ -221,7 +221,7 @@ fn _isoweek(d: *date) int = {
fn _hour(d: *date) int = {
match (d.hour) {
case void =>
- const hmsn = calc_hmsn(chrono::time(d));
+ const hmsn = calc_hmsn(chrono::daytime(d));
d.hour = hmsn.0;
d.minute = hmsn.1;
d.second = hmsn.2;
@@ -235,7 +235,7 @@ fn _hour(d: *date) int = {
fn _minute(d: *date) int = {
match (d.minute) {
case void =>
- const hmsn = calc_hmsn(chrono::time(d));
+ const hmsn = calc_hmsn(chrono::daytime(d));
d.hour = hmsn.0;
d.minute = hmsn.1;
d.second = hmsn.2;
@@ -249,7 +249,7 @@ fn _minute(d: *date) int = {
fn _second(d: *date) int = {
match (d.second) {
case void =>
- const hmsn = calc_hmsn(chrono::time(d));
+ const hmsn = calc_hmsn(chrono::daytime(d));
d.hour = hmsn.0;
d.minute = hmsn.1;
d.second = hmsn.2;
@@ -263,7 +263,7 @@ fn _second(d: *date) int = {
fn _nanosecond(d: *date) int = {
match (d.nanosecond) {
case void =>
- const hmsn = calc_hmsn(chrono::time(d));
+ const hmsn = calc_hmsn(chrono::daytime(d));
d.hour = hmsn.0;
d.minute = hmsn.1;
d.second = hmsn.2;
diff --git a/time/date/date.ha b/time/date/date.ha
@@ -191,9 +191,9 @@ fn calc_weekday(e: i64) int = {
return (wd + 7) % 7;
};
-// Calculates the date,
+// Calculates the daydate,
// given a year, month, and day-of-month.
-fn calc_date__ymd(y: int, m: int, d: int) (i64 | invalid) = {
+fn calc_daydate__ymd(y: int, m: int, d: int) (i64 | invalid) = {
if (!is_valid_ymd(y, m, d)) {
return invalid;
};
@@ -212,24 +212,24 @@ fn calc_date__ymd(y: int, m: int, d: int) (i64 | invalid) = {
return e;
};
-// Calculates the date,
+// Calculates the daydate,
// given a year, week, and day-of-week.
-fn calc_date__ywd(y: int, w: int, wd: int) (i64 | invalid) = {
+fn calc_daydate__ywd(y: int, w: int, wd: int) (i64 | invalid) = {
const jan1wd = calc_janfirstweekday(y);
const yd = wd - jan1wd + 7 * w;
- return calc_date__yd(y, yd)?;
+ return calc_daydate__yd(y, yd)?;
};
-// Calculates the date,
+// Calculates the daydate,
// given a year and day-of-year.
-fn calc_date__yd(y: int, yd: int) (i64 | invalid) = {
+fn calc_daydate__yd(y: int, yd: int) (i64 | invalid) = {
if (yd < 1 || yd > calc_year_daycnt(y)) {
return invalid;
};
- return calc_date__ymd(y, 1, 1)? + yd - 1;
+ return calc_daydate__ymd(y, 1, 1)? + yd - 1;
};
-@test fn calc_date__ymd() void = {
+@test fn calc_daydate__ymd() void = {
const cases = [
(( -768, 2, 5), -999999, false),
(( -1, 12, 31), -719529, false),
@@ -265,7 +265,7 @@ fn calc_date__yd(y: int, yd: int) (i64 | invalid) = {
const params = cases[i].0;
const expect = cases[i].1;
const should_error = cases[i].2;
- const actual = calc_date__ymd(
+ const actual = calc_daydate__ymd(
params.0, params.1, params.2,
);
@@ -278,7 +278,7 @@ fn calc_date__yd(y: int, yd: int) (i64 | invalid) = {
};
};
-@test fn calc_date__ywd() void = {
+@test fn calc_daydate__ywd() void = {
const cases = [
(( -768, 0, 4), -1000034),
(( -768, 5, 4), -999999),
@@ -316,13 +316,13 @@ fn calc_date__yd(y: int, yd: int) (i64 | invalid) = {
for (let i = 0z; i < len(cases); i += 1) {
const ywd = cases[i].0;
const expected = cases[i].1;
- const actual = calc_date__ywd(ywd.0, ywd.1, ywd.2)!;
+ const actual = calc_daydate__ywd(ywd.0, ywd.1, ywd.2)!;
assert(actual == expected,
- "incorrect calc_date__ywd() result");
+ "incorrect calc_daydate__ywd() result");
};
};
-@test fn calc_date__yd() void = {
+@test fn calc_daydate__yd() void = {
const cases = [
( -768, 36, -999999),
( -1, 365, -719529),
@@ -351,14 +351,14 @@ fn calc_date__yd(y: int, yd: int) (i64 | invalid) = {
const y = cases[i].0;
const yd = cases[i].1;
const expected = cases[i].2;
- const actual = calc_date__yd(y, yd)!;
+ const actual = calc_daydate__yd(y, yd)!;
assert(expected == actual,
"error in date calculation from yd");
};
- assert(calc_date__yd(2020, 0) is invalid,
- "calc_date__yd() did not reject invalid yearday");
- assert(calc_date__yd(2020, 400) is invalid,
- "calc_date__yd() did not reject invalid yearday");
+ assert(calc_daydate__yd(2020, 0) is invalid,
+ "calc_daydate__yd() did not reject invalid yearday");
+ assert(calc_daydate__yd(2020, 400) is invalid,
+ "calc_daydate__yd() did not reject invalid yearday");
};
@test fn calc_ymd() void = {
diff --git a/time/date/datetime.ha b/time/date/datetime.ha
@@ -9,10 +9,7 @@ use time::chrono;
export type invalid = !chrono::invalid;
// A date/time object; a [[time::chrono::moment]] wrapper optimized for the
-// Gregorian chronology
-//
-// It is by extension a [[time::instant]] wrapper, and carries information about
-// its [[time::chrono::timescale]] and [[time::chrono::locality]].
+// Gregorian chronology, and by extension a [[time::instant]] wrapper.
//
// This object should be treated as private and immutable. Directly mutating its
// fields causes undefined behaviour when used with module functions. Likewise,
@@ -20,8 +17,8 @@ export type invalid = !chrono::invalid;
// also improper.
//
// A date observes various chronological values, cached in its fields. To
-// evaluate and obtain these values, use the various "observe" functions
-// ([[year]], [[day]], etc.). These values are derived from the embedded moment
+// evaluate and obtain these values, use the various observer functions
+// ([[year]], [[hour]], etc.). These values are derived from the embedded moment
// information, and thus are guaranteed to be valid.
//
// See [[virtual]] for an public, mutable, intermediary representation of a
@@ -51,8 +48,8 @@ fn init() date = date {
nsec = 0,
loc = chrono::UTC,
zone = null,
- date = void,
- time = void,
+ daydate = void,
+ daytime = void,
era = void,
year = void,
@@ -153,8 +150,8 @@ export fn new(
const sec = _fields[5];
const nsec = _fields[6];
- const mdate = calc_date__ymd(year, month, day)?;
- const mtime = calc_time__hmsn(hour, min, sec, nsec)?;
+ const mdate = calc_daydate__ymd(year, month, day)?;
+ const mtime = calc_daytime__hmsn(hour, min, sec, nsec)?;
// create the moment
const m = match (zo) {
@@ -213,8 +210,8 @@ export fn from_moment(m: chrono::moment) date = {
d.loc = m.loc;
d.sec = m.sec;
d.nsec = m.nsec;
- d.date = m.date;
- d.time = m.time;
+ d.daydate = m.daydate;
+ d.daytime = m.daytime;
d.zone = m.zone;
return d;
};
diff --git a/time/date/duration.ha b/time/date/duration.ha
@@ -2,10 +2,10 @@
// (c) 2023 Byron Torres <b@torresjrjr.com>
use time;
-// Adds a [[time::duration]] to a [[date]] with [[time::add]].
+// Adds a [[time::duration]] to a [[date]] with [[time::add]]. This is a
+// timescalar aritmetic operation.
//
-// See [[reckon]] for a chronology-wise arithmetic operation which uses
-// [[period]].
+// See [[reckon]].
export fn add(d: date, x: time::duration) date = {
return from_instant(d.loc, time::add(*(&d: *time::instant), x));
};
diff --git a/time/date/parse.ha b/time/date/parse.ha
@@ -255,8 +255,8 @@ fn scan_str(iter: *strings::iterator) (str | failure) = {
let v = newvirtual();
assert(parse(&v, "foo", "foo") is void, "none: parsefail");
assert(v.zone == null, "none: non-null zone");
- assert(v.date is void, "none: non-void date");
- assert(v.time is void, "none: non-void time");
+ assert(v.daydate is void, "none: non-void daydate");
+ assert(v.daytime is void, "none: non-void daytime");
assert(v.era is void, "none: non-void era");
assert(v.year is void, "none: non-void year");
assert(v.month is void, "none: non-void month");
diff --git a/time/date/reckon.ha b/time/date/reckon.ha
@@ -49,13 +49,11 @@ export type calculus = enum uint {
FOLD = 1 << 4,
};
-// Reckons from a given [[date]] to a new one, via a set of [[period]]s.
-// This is a chronology-wise arithmetic operation. Each period is reckoned
+// Reckons from a given [[date]] to a new one, via a given set of [[period]]s.
+// This is a chronological arithmetic operation. Each period is reckoned
// independently in succession, applying (adding) their units from most to least
-// significant.
-//
-// The [[calculus]] parameter determines arithmetic and resolution behaviour
-// when encountering deviations (e.g. overflows).
+// significant. The [[calculus]] parameter determines certain behaviours, like
+// for when encountering invalid date states (e.g. field overflows).
//
// let dest = date::reckon(
// start, // 2000-02-29 09:00:00
@@ -67,8 +65,7 @@ export type calculus = enum uint {
// },
// );
//
-// See [[add]] for a timescale-wise arithmetic operation which uses
-// [[time::duration]].
+// See [[add]].
export fn reckon(d: date, calc: calculus, ps: period...) date = {
let r = newvirtual(); // our reckoner
r.vloc = d.loc;
diff --git a/time/date/time.ha b/time/date/time.ha
@@ -4,7 +4,7 @@ use errors;
use time;
// Calculates the wall clock (hour, minute, second, nanosecond),
-// given a time since the start of a day.
+// given a time-of-day (amount of daytime progressed in a day).
fn calc_hmsn(t: time::duration) (int, int, int, int) = {
// TODO: Special case for leap seconds, 61st second?
const hour = (t / time::HOUR): int;
@@ -14,9 +14,9 @@ fn calc_hmsn(t: time::duration) (int, int, int, int) = {
return (hour, min, sec, nsec);
};
-// Calculates the time since the start of a day,
+// Calculates the time-of-day (amount of daytime progressed in a day),
// given a wall clock (hour, minute, second, nanosecond).
-fn calc_time__hmsn(
+fn calc_daytime__hmsn(
hour: int,
min: int,
sec: int,
diff --git a/time/date/virtual.ha b/time/date/virtual.ha
@@ -13,12 +13,12 @@ export type insufficient = !void;
//
// Unlike [[date]], a virtual's fields are meant to be treated as public and
// mutable. The embedded [[time::instant]] and [[time::chrono::locality]] fields
-// (.sec .nsec .loc) are considered meaningless. Behaviour with the "observe"
+// (.sec .nsec .loc) are considered meaningless. Behaviour with the observer
// functions is undefined.
//
-// This can be used to construct a new [[date]] piece-by-piece. Start with
-// [[newvirtual]], then collect enough date/time information incrementally by
-// direct field assignments and/or with [[parse]]. Finish with [[realize]].
+// This can be used to safely construct a new [[date]] piece-by-piece. Start
+// with [[newvirtual]], then collect enough date/time information incrementally
+// by direct field assignments and/or with [[parse]]. Finish with [[realize]].
//
// let v = date::newvirtual();
// v.vloc = time::chrono::UTC;
@@ -52,8 +52,8 @@ export fn newvirtual() virtual = virtual {
nsec = 0,
loc = chrono::UTC,
zone = null,
- date = void,
- time = void,
+ daydate = void,
+ daytime = void,
era = void,
year = void,
@@ -84,17 +84,17 @@ export fn newvirtual() virtual = virtual {
// each of which use a certain set of non-void fields from the given virtual.
// The following determination strategies will be attempted in order.
//
-// Field sets for determining the date:
+// Field sets for determining the daydate:
//
-// 1. date
+// 1. daydate
// 2. year, month, day
// 3. year, yearday
// 4. year, week, weekday
// 5. isoweekyear, isoweek, weekday
//
-// Field sets for determining the time:
+// Field sets for determining the time-of-day:
//
-// 1. time
+// 1. daytime
// 2. hour, minute, second, nanosecond
//
// Field sets for determining the zone offset:
@@ -117,15 +117,15 @@ export fn realize(
v: virtual,
locs: time::chrono::locality...
) (date | insufficient | invalid) = {
- // determine .date
- if (v.date is i64) {
+ // determine .daydate
+ if (v.daydate is i64) {
void;
} else if (
v.year is int &&
v.month is int &&
v.day is int
) {
- v.date = calc_date__ymd(
+ v.daydate = calc_daydate__ymd(
v.year as int,
v.month as int,
v.day as int,
@@ -134,7 +134,7 @@ export fn realize(
v.year is int &&
v.yearday is int
) {
- v.date = calc_date__yd(
+ v.daydate = calc_daydate__yd(
v.year as int,
v.yearday as int,
)?;
@@ -143,21 +143,21 @@ export fn realize(
v.week is int &&
v.weekday is int
) {
- v.date = calc_date__ywd(
+ v.daydate = calc_daydate__ywd(
v.year as int,
v.week as int,
v.weekday as int,
)?;
} else if (false) {
- // TODO: calendar.ha: calc_date__isoywd()
+ // TODO: calendar.ha: calc_daydate__isoywd()
void;
} else {
- // cannot deduce date
+ // cannot deduce daydate
return insufficient;
};
- // determine .time
- if (v.time is time::duration) {
+ // determine .daytime
+ if (v.daytime is time::duration) {
void;
} else {
const hour = if (v.hour is int) {
@@ -175,7 +175,7 @@ export fn realize(
v.second is int &&
v.nanosecond is int
) {
- v.time = calc_time__hmsn(
+ v.daytime = calc_daytime__hmsn(
hour,
v.minute as int,
v.second as int,
@@ -211,8 +211,8 @@ export fn realize(
const d = from_moment(chrono::from_datetime(
v.loc,
v.zoff as time::duration,
- v.date as i64,
- v.time as time::duration,
+ v.daydate as i64,
+ v.daytime as time::duration,
));
// verify zone offset