commit 3d3b1b2d34e1ed8fc4d9719efeb8032ec0ca3715
parent c5f72d0cb5a18f3bdbe63cb8cdf2beb69a5fe376
Author: Byron Torres <b@torresjrjr.com>
Date: Fri, 28 Jan 2022 19:16:40 +0000
make new() use given zoffset
Signed-off-by: Byron Torres <b@torresjrjr.com>
Diffstat:
4 files changed, 94 insertions(+), 35 deletions(-)
diff --git a/datetime/chronology.ha b/datetime/chronology.ha
@@ -2,14 +2,58 @@ use errors;
use time;
use time::chrono;
+// Fucntions renamed here to avoid namespace conflict, like in the parameters of
+// the [[new]] function.
+
// Returns a [[datetime]]'s number of days since the calendar epoch 0000-01-01
-export fn epochal(dt: *datetime) chrono::epochal = {
+export fn epochal(dt: *datetime) chrono::epochal = _epochal(dt);
+
+// Returns a [[datetime]]'s era
+export fn era(dt: *datetime) int = _era(dt);
+
+// Returns a [[datetime]]'s year
+export fn year(dt: *datetime) int = _year(dt);
+
+// Returns a [[datetime]]'s month of the year
+export fn month(dt: *datetime) int = _month(dt);
+
+// Returns a [[datetime]]'s day of the month
+export fn day(dt: *datetime) int = _day(dt);
+
+// Returns a [[datetime]]'s day of the week
+export fn weekday(dt: *datetime) int = _weekday(dt);
+
+// Returns a [[datetime]]'s ordinal day of the year
+export fn yearday(dt: *datetime) int = _yearday(dt);
+
+// Returns a [[datetime]]'s ISO week-numbering year
+export fn isoweekyear(dt: *datetime) int = _isoweekyear(dt);
+
+// Returns a [[datetime]]'s Gregorian week
+export fn week(dt: *datetime) int = _week(dt);
+
+// Returns a [[datetime]]'s ISO week
+export fn isoweek(dt: *datetime) int = _isoweek(dt);
+
+// Returns a [[datetime]]'s hour of the day
+export fn hour(dt: *datetime) int = _hour(dt);
+
+// Returns a [[datetime]]'s minute of the hour
+export fn min(dt: *datetime) int = _min(dt);
+
+// Returns a [[datetime]]'s second of the minute
+export fn sec(dt: *datetime) int = _sec(dt);
+
+// Returns a [[datetime]]'s nanosecond of the second
+export fn nsec(dt: *datetime) int = _nsec(dt);
+
+
+fn _epochal(dt: *datetime) chrono::epochal = {
const ldt = transform(*dt, dt.zone.zoffset);
return ldt.date - EPOCHAL_GREGORIAN;
};
-// Returns a [[datetime]]'s era
-export fn era(dt: *datetime) int = {
+fn _era(dt: *datetime) int = {
match (dt.era) {
case void =>
if (dt.year is void) {
@@ -22,8 +66,7 @@ export fn era(dt: *datetime) int = {
};
};
-// Returns a [[datetime]]'s year
-export fn year(dt: *datetime) int = {
+fn _year(dt: *datetime) int = {
const ldt = transform(*dt, dt.zone.zoffset);
match (dt.year) {
case void =>
@@ -37,8 +80,7 @@ export fn year(dt: *datetime) int = {
};
};
-// Returns a [[datetime]]'s month of the year
-export fn month(dt: *datetime) int = {
+fn _month(dt: *datetime) int = {
const ldt = transform(*dt, dt.zone.zoffset);
match (dt.month) {
case void =>
@@ -52,8 +94,7 @@ export fn month(dt: *datetime) int = {
};
};
-// Returns a [[datetime]]'s day of the month
-export fn day(dt: *datetime) int = {
+fn _day(dt: *datetime) int = {
const ldt = transform(*dt, dt.zone.zoffset);
match (dt.day) {
case void =>
@@ -67,8 +108,7 @@ export fn day(dt: *datetime) int = {
};
};
-// Returns a [[datetime]]'s day of the week
-export fn weekday(dt: *datetime) int = {
+fn _weekday(dt: *datetime) int = {
const ldt = transform(*dt, dt.zone.zoffset);
match (dt.weekday) {
case void =>
@@ -79,8 +119,7 @@ export fn weekday(dt: *datetime) int = {
};
};
-// Returns a [[datetime]]'s ordinal day of the year
-export fn yearday(dt: *datetime) int = {
+fn _yearday(dt: *datetime) int = {
match (dt.yearday) {
case void =>
if (dt.year is void) {
@@ -103,8 +142,7 @@ export fn yearday(dt: *datetime) int = {
};
};
-// Returns a [[datetime]]'s ISO week-numbering year
-export fn isoweekyear(dt: *datetime) int = {
+fn _isoweekyear(dt: *datetime) int = {
match (dt.isoweekyear) {
case void =>
if (dt.year is void) {
@@ -131,8 +169,7 @@ export fn isoweekyear(dt: *datetime) int = {
};
};
-// Returns a [[datetime]]'s Gregorian week
-export fn week(dt: *datetime) int = {
+fn _week(dt: *datetime) int = {
match (dt.week) {
case void =>
if (dt.yearday is void) {
@@ -151,8 +188,7 @@ export fn week(dt: *datetime) int = {
};
};
-// Returns a [[datetime]]'s ISO week
-export fn isoweek(dt: *datetime) int = {
+fn _isoweek(dt: *datetime) int = {
match (dt.isoweek) {
case void =>
if (dt.year is void) {
@@ -179,8 +215,7 @@ export fn isoweek(dt: *datetime) int = {
};
};
-// Returns a [[datetime]]'s hour of the day
-export fn hour(dt: *datetime) int = {
+fn _hour(dt: *datetime) int = {
const ldt = transform(*dt, dt.zone.zoffset);
match (dt.hour) {
case void =>
@@ -195,8 +230,7 @@ export fn hour(dt: *datetime) int = {
};
};
-// Returns a [[datetime]]'s minute of the hour
-export fn min(dt: *datetime) int = {
+fn _min(dt: *datetime) int = {
const ldt = transform(*dt, dt.zone.zoffset);
match (dt.min) {
case void =>
@@ -211,8 +245,7 @@ export fn min(dt: *datetime) int = {
};
};
-// Returns a [[datetime]]'s second of the minute
-export fn sec(dt: *datetime) int = {
+fn _sec(dt: *datetime) int = {
const ldt = transform(*dt, dt.zone.zoffset);
match (dt.sec) {
case void =>
@@ -227,8 +260,7 @@ export fn sec(dt: *datetime) int = {
};
};
-// Returns a [[datetime]]'s nanosecond of the second
-export fn nsec(dt: *datetime) int = {
+fn _nsec(dt: *datetime) int = {
const ldt = transform(*dt, dt.zone.zoffset);
match (dt.nsec) {
case void =>
diff --git a/datetime/datetime.ha b/datetime/datetime.ha
@@ -81,7 +81,9 @@ fn init() datetime = datetime {
// the local time 02:30 was observed twice (00:30 UTC & 01:30 UTC),
// as the clock jumped back 1 hour from 03:00 CEST to 02:00 CET.
//
-// TODO: implement as described.
+// TODO: Implement as described.
+// TODO: Allow and correct for overflowing units like Golang? Most likely not.
+// Defeats the purpose of validation at creation. I see little benefit.
export fn new(
year: int,
month: int,
@@ -101,10 +103,14 @@ export fn new(
// TODO: should this be `nullable *chrono::timezone`?
// would interface better with other code, i presume.
loc: (*chrono::timezone | void),
+
+// TODO: improve variety of errors.
+// `invaliddatetime = !void` ?
+// `invaliddatetime = !datetime::builder` ?
) (datetime | errors::invalid) = {
// TODO: set the correct values according to the given zoffset and
// locality/timezone.
- const m = chrono::new(
+ let m = chrono::new(
calc_epochal_from_ymd(year, month, day)?,
calc_time_from_hmsn(hour, min, sec, nsec)?,
if (loc is void) chrono::local else loc: *chrono::timezone,
@@ -112,16 +118,33 @@ export fn new(
// figuring out what zone this moment observes
if (zoffset is time::duration) {
- // transform inversely to the moment that would transform to the
- // current moment, then perform a zone lookup.
- void;
+ // transform inversely to the moment that would transform back
+ // to the current moment, then perform a zone lookup.
+ m = chrono::transform(m, -(zoffset as time::duration));
+ chrono::lookupzone(&m);
} else {
// just perform a zone lookup, then try that zone and the
- // neighboring zones.
+ // zones that are observed before and after.
+ //const z0 = chrono::lookupzone(*m);
+ //m = chrono::transform(m, -z0.zoffset);
void;
};
- return from_moment(m);
+ const dt = from_moment(m);
+ if (
+ year == _year(&dt)
+ && month == _month(&dt)
+ && day == _day(&dt)
+ && hour == _hour(&dt)
+ && min == _min(&dt)
+ && sec == _sec(&dt)
+ && nsec == _nsec(&dt)
+ ) {
+ void;
+ } else {
+ return errors::invalid;
+ };
+ return dt;
};
// Returns a [[datetime]] of the immediate system time
diff --git a/time/chrono/chronology.ha b/time/chrono/chronology.ha
@@ -26,6 +26,10 @@ export type moment = struct {
export type epochal = i64;
// Creates a new [[moment]]
+//
+// TODO: Check for `time` value bounds overflow. Should we:
+// a. Return an error?
+// b. "Correct" by overflowing? See datetime::new();
export fn new(date: epochal, time: time::duration, loc: locality) moment = {
const m = moment {
date = date,
diff --git a/time/chrono/timezone.ha b/time/chrono/timezone.ha
@@ -129,7 +129,7 @@ export fn lookupzone(m: *moment) zone = {
// if we've reached the end of the locality's transitions, try its
// posix_extend string
//
- // TODO: important
+ // TODO: Unfinished; complete.
if (lo == len(m.loc.transitions) - 1 && m.loc.posix_extend != "") {
void;
};