commit c5f72d0cb5a18f3bdbe63cb8cdf2beb69a5fe376
parent 4acb316c08e1354f8b213900695f1159836714d9
Author: Byron Torres <b@torresjrjr.com>
Date: Fri, 28 Jan 2022 17:35:04 +0000
s/localize/transform/; prepare new() zone lookup
Signed-off-by: Byron Torres <b@torresjrjr.com>
Diffstat:
5 files changed, 37 insertions(+), 38 deletions(-)
diff --git a/datetime/chronology.ha b/datetime/chronology.ha
@@ -4,7 +4,7 @@ use time::chrono;
// Returns a [[datetime]]'s number of days since the calendar epoch 0000-01-01
export fn epochal(dt: *datetime) chrono::epochal = {
- const ldt = localize(*dt);
+ const ldt = transform(*dt, dt.zone.zoffset);
return ldt.date - EPOCHAL_GREGORIAN;
};
@@ -24,7 +24,7 @@ export fn era(dt: *datetime) int = {
// Returns a [[datetime]]'s year
export fn year(dt: *datetime) int = {
- const ldt = localize(*dt);
+ const ldt = transform(*dt, dt.zone.zoffset);
match (dt.year) {
case void =>
const ymd = calc_ymd(ldt.date: chrono::epochal);
@@ -39,7 +39,7 @@ export fn year(dt: *datetime) int = {
// Returns a [[datetime]]'s month of the year
export fn month(dt: *datetime) int = {
- const ldt = localize(*dt);
+ const ldt = transform(*dt, dt.zone.zoffset);
match (dt.month) {
case void =>
const ymd = calc_ymd(ldt.date: chrono::epochal);
@@ -54,7 +54,7 @@ export fn month(dt: *datetime) int = {
// Returns a [[datetime]]'s day of the month
export fn day(dt: *datetime) int = {
- const ldt = localize(*dt);
+ const ldt = transform(*dt, dt.zone.zoffset);
match (dt.day) {
case void =>
const ymd = calc_ymd(ldt.date: chrono::epochal);
@@ -69,7 +69,7 @@ export fn day(dt: *datetime) int = {
// Returns a [[datetime]]'s day of the week
export fn weekday(dt: *datetime) int = {
- const ldt = localize(*dt);
+ const ldt = transform(*dt, dt.zone.zoffset);
match (dt.weekday) {
case void =>
dt.weekday = calc_weekday(ldt.date: chrono::epochal);
@@ -181,7 +181,7 @@ export fn isoweek(dt: *datetime) int = {
// Returns a [[datetime]]'s hour of the day
export fn hour(dt: *datetime) int = {
- const ldt = localize(*dt);
+ const ldt = transform(*dt, dt.zone.zoffset);
match (dt.hour) {
case void =>
const hmsn = calc_hmsn(ldt.time: time::duration);
@@ -197,7 +197,7 @@ export fn hour(dt: *datetime) int = {
// Returns a [[datetime]]'s minute of the hour
export fn min(dt: *datetime) int = {
- const ldt = localize(*dt);
+ const ldt = transform(*dt, dt.zone.zoffset);
match (dt.min) {
case void =>
const hmsn = calc_hmsn(ldt.time: time::duration);
@@ -213,7 +213,7 @@ export fn min(dt: *datetime) int = {
// Returns a [[datetime]]'s second of the minute
export fn sec(dt: *datetime) int = {
- const ldt = localize(*dt);
+ const ldt = transform(*dt, dt.zone.zoffset);
match (dt.sec) {
case void =>
const hmsn = calc_hmsn(ldt.time: time::duration);
@@ -229,7 +229,7 @@ export fn sec(dt: *datetime) int = {
// Returns a [[datetime]]'s nanosecond of the second
export fn nsec(dt: *datetime) int = {
- const ldt = localize(*dt);
+ const ldt = transform(*dt, dt.zone.zoffset);
match (dt.nsec) {
case void =>
const hmsn = calc_hmsn(ldt.time: time::duration);
diff --git a/datetime/datetime.ha b/datetime/datetime.ha
@@ -109,6 +109,18 @@ export fn new(
calc_time_from_hmsn(hour, min, sec, nsec)?,
if (loc is void) chrono::local else loc: *chrono::timezone,
);
+
+ // 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;
+ } else {
+ // just perform a zone lookup, then try that zone and the
+ // neighboring zones.
+ void;
+ };
+
return from_moment(m);
};
diff --git a/datetime/timezone.ha b/datetime/timezone.ha
@@ -9,18 +9,10 @@ export fn in(loc: chrono::locality, dt: datetime) datetime = {
return new_dt;
};
-// Returns a fictitious [[datetime]] which is adjusted and normalized as if its
-// locality was the normal locality. Its fields are adjusted by its current
-// [[chrono::zone]]'s offset.
-//
-// This is a utility function for use by other modules's internal calculations.
-// You probably shouldn't use this directly.
-//
-// TODO: Rename [[localize]] to something less confusing and more dangerous
-// sounding? Perhaps not export it? It's use is special case and often not
-// what users want.
-export fn localize(dt: datetime) datetime = {
- return from_moment(chrono::localize(to_moment(dt)));
+// Returns a fictitious [[datetime]] which is shifted in time by a zone offset.
+// This is a utility function. Use with caution.
+export fn transform(dt: datetime, zo: time::duration) datetime = {
+ return from_moment(chrono::transform(to_moment(dt), zo));
};
// Finds and returns a [[datetime]]'s currently observed zone
diff --git a/stdlib.mk b/stdlib.mk
@@ -1811,7 +1811,7 @@ $(HARECACHE)/time/chrono/time_chrono-any.ssa: $(stdlib_time_chrono_any_srcs) $(s
stdlib_time_olson_any_srcs= \
$(STDLIB)/time/olson/olson.ha
-$(HARECACHE)/time/olson/time_olson-any.ssa: $(stdlib_time_olson_any_srcs) $(stdlib_rt) $(stdlib_time_$(PLATFORM)) $(stdlib_time_chrono_$(PLATFORM)) $(stdlib_datetime_$(PLATFORM))
+$(HARECACHE)/time/olson/time_olson-any.ssa: $(stdlib_time_olson_any_srcs) $(stdlib_rt) $(stdlib_endian_$(PLATFORM)) $(stdlib_errors_$(PLATFORM)) $(stdlib_fs_$(PLATFORM)) $(stdlib_io_$(PLATFORM)) $(stdlib_os_$(PLATFORM)) $(stdlib_path_$(PLATFORM)) $(stdlib_strings_$(PLATFORM)) $(stdlib_time_$(PLATFORM)) $(stdlib_time_chrono_$(PLATFORM))
@printf 'HAREC \t$@\n'
@mkdir -p $(HARECACHE)/time/olson
@HARECACHE=$(HARECACHE) $(HAREC) $(HAREFLAGS) -o $@ -Ntime::olson \
@@ -3820,7 +3820,7 @@ $(TESTCACHE)/time/chrono/time_chrono-any.ssa: $(testlib_time_chrono_any_srcs) $(
testlib_time_olson_any_srcs= \
$(STDLIB)/time/olson/olson.ha
-$(TESTCACHE)/time/olson/time_olson-any.ssa: $(testlib_time_olson_any_srcs) $(testlib_rt) $(testlib_time_$(PLATFORM)) $(testlib_time_chrono_$(PLATFORM)) $(testlib_datetime_$(PLATFORM))
+$(TESTCACHE)/time/olson/time_olson-any.ssa: $(testlib_time_olson_any_srcs) $(testlib_rt) $(testlib_endian_$(PLATFORM)) $(testlib_errors_$(PLATFORM)) $(testlib_fs_$(PLATFORM)) $(testlib_io_$(PLATFORM)) $(testlib_os_$(PLATFORM)) $(testlib_path_$(PLATFORM)) $(testlib_strings_$(PLATFORM)) $(testlib_time_$(PLATFORM)) $(testlib_time_chrono_$(PLATFORM))
@printf 'HAREC \t$@\n'
@mkdir -p $(TESTCACHE)/time/olson
@HARECACHE=$(TESTCACHE) $(HAREC) $(TESTHAREFLAGS) -o $@ -Ntime::olson \
diff --git a/time/chrono/timezone.ha b/time/chrono/timezone.ha
@@ -64,29 +64,24 @@ type tzname = struct {
dst_endtime: str,
};
-// Transforms and creates a new [[moment]] in a different [[locality]]
+// Converts a [[moment]] to one in a different [[locality]]
export fn in(loc: locality, m: moment) moment = {
return new(m.date, m.time, loc); // resets .zone
};
-// Returns a fictitious [[moment]] which is adjusted and normalized as if its
-// locality was the normal locality. Its fields are adjusted by its current
-// [[zone]]'s offset.
-//
-// This is a utility function for use by other modules's internal calculations.
-// You probably shouldn't use this directly.
-export fn localize(m: moment) moment = {
- const zone = lookupzone(&m);
+// Returns a fictitious [[moment]] which is shifted in time by a zone offset.
+// This is a utility function for external modules. Use with caution.
+export fn transform(m: moment, zo: time::duration) moment = {
const daylen = m.loc.daylength;
- const tnew = m.time + zone.zoffset;
- const t = (if (tnew >= 0) tnew else tnew + daylen) % daylen;
+ const t = m.time + zo;
+ const mtime = (if (t >= 0) t else t + daylen) % daylen;
- const dnew = (tnew / daylen): int;
- const d = m.date + (if (tnew >= 0) dnew else dnew - 1);
+ const d = (t / daylen): int;
+ const mdate = m.date + (if (t >= 0) d else d - 1);
- m.time = t;
- m.date = d;
+ m.time = mtime;
+ m.date = mdate;
return m;
};