hare

The Hare programming language
git clone https://git.torresjrjr.com/hare.git
Log | Files | Refs | README | LICENSE

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:
Mdatetime/chronology.ha | 18+++++++++---------
Mdatetime/datetime.ha | 12++++++++++++
Mdatetime/timezone.ha | 16++++------------
Mstdlib.mk | 4++--
Mtime/chrono/timezone.ha | 25++++++++++---------------
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; };