hare

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

commit 19e380ccb7dfe2bcab5f94e6bd03004e3e2c6005
parent 4d909ad613a6d2c8552ab14ed0c8639439c348cd
Author: Byron Torres <b@torresjrjr.com>
Date:   Tue, 24 May 2022 04:00:29 +0100

time::chrono: make in() handle multiple timescales

The following now works properly:

	const earth = datetime::now();
	const mars = datetime::in(chrono::MTC, earth);

Fixes: https://todo.sr.ht/~sircmpwn/hare/618
Signed-off-by: Byron Torres <b@torresjrjr.com>

Diffstat:
Mtime/chrono/timezone.ha | 23+++++++++++++++++++++++
1 file changed, 23 insertions(+), 0 deletions(-)

diff --git a/time/chrono/timezone.ha b/time/chrono/timezone.ha @@ -71,7 +71,30 @@ type tzname = struct { }; // Creates an equivalent [[moment]] with a different [[locality]]. +// +// If the old and new localities have different timescales, a direct conversion +// between them will be tried, and will abort if unsuccessful. To avoid this, +// consider manually converting moments to instants, and those instants between +// timescales. export fn in(loc: locality, m: moment) moment = { + if (m.loc.timescale != loc.timescale) { + const i = to_instant(m); + const i = match (m.loc.timescale.to_tai(i)) { + case let i: time::instant => + yield i; + case time::error => + abort("time::chrono::in(): direct timescale conversion failed"); + }; + const i = match (loc.timescale.from_tai(i)) { + case let i: time::instant => + yield i; + case time::error => + abort("time::chrono::in(): direct timescale conversion failed"); + }; + const m = from_instant(i, loc); + return m; + }; + assert(m.time < loc.daylength, "Internal error: time excedes daylength"); return new(loc, m.date, m.time)!; // resets .zone };