hare

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

commit cfa06dfb4a2fdfb56750aeee728e804487ae4343
parent 6cdaa5d1ba754586f64e962ae4cc8fee8a464f31
Author: Byron Torres <b@torresjrjr.com>
Date:   Wed,  3 Nov 2021 17:07:27 +0000

implement base timezones

Signed-off-by: Byron Torres <b@torresjrjr.com>

Diffstat:
Mdatetime/README | 4++--
Mdatetime/calendar.ha | 8++++++--
Mdatetime/datetime.ha | 12+++++-------
Adatetime/timezone.ha | 63+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Mscripts/gen-stdlib | 1+
Mstdlib.mk | 2++
Mtime/README | 2+-
Mtime/chrono/README | 7++++---
Mtime/chrono/chronology.ha | 2+-
Mtime/chrono/timezone.ha | 67++++++++++++++++++++++++++++++++++++++++---------------------------
10 files changed, 125 insertions(+), 43 deletions(-)

diff --git a/datetime/README b/datetime/README @@ -1,5 +1,5 @@ -The chrono::isocal submodule implements the international standard -proleptic Gregorian calendar, as per ISO 8601. +The datetime module implements the international standard proleptic +Gregorian calendar, as per ISO 8601. This module provides datetimes, timezones, offsets, and the arithmetics, formatting, parsing, serialization, and conversion thereof. diff --git a/datetime/calendar.ha b/datetime/calendar.ha @@ -134,7 +134,7 @@ export type period = struct { // sequencially, consulting period's units from largest to smallest. // // // m := 1999-05-13 12:30:45 -// isocal::hop(m, isocal::period { +// datetime::hop(m, datetime::period { // years = 22, // 2021-01-01 00:00:00 // months = -1, // 2020-11-01 00:00:00 // days = -4, // 2020-10-27 00:00:00 @@ -152,7 +152,7 @@ export fn hop(m: chrono::moment, pp: period...) chrono::moment = { // Tries to conserve relative distance from cyclical points on the calendar. // // // m := 1999-05-13 12:30:45 -// isocal::hop(m, isocal::period { +// datetime::hop(m, datetime::period { // years = 22, // 2021-05-13 00:00:00 // months = -1, // 2021-04-13 00:00:00 // days = -4, // 2020-04-09 00:00:00 @@ -171,3 +171,7 @@ export fn add(m: chrono::moment, flag: int, pp: period...) chrono::moment = { return m; }; +export type calculus = enum int { + LOGICAL, + PHYSICAL, +}; diff --git a/datetime/datetime.ha b/datetime/datetime.ha @@ -17,15 +17,13 @@ use errors; export type datetime = struct { date: localdate, time: localtime, - loc: locality, + loc: chrono::locality, }; -export type locality = chrono::locality; - // Creates a new moment // // // 1995 July 18th 09:16:00.000 -// isocal::new_moment(1995, 07, 18, 9, 16, 0, 0, isocal::local) +// datetime::new_moment(1995, 07, 18, 9, 16, 0, 0, chrono::local) // // For alternative forms, assemble a datetime manually using the desired types. export fn new_moment( @@ -36,7 +34,7 @@ export fn new_moment( min: int, sec: int, nsec: int, - loc: locality, + loc: chrono::locality, ) chrono::moment = { const dt = datetime { date = localdate { @@ -59,7 +57,7 @@ export fn new_moment( // Creates a new datetime // // // 1995 July 18th 09:16:00.000 -// isocal::new(1995, 07, 18, 9, 16, 0, 0, isocal::local) +// datetime::new(1995, 07, 18, 9, 16, 0, 0, chrono::local) // // For alternative forms, assemble a datetime manually using the desired types. export fn new_datetime( @@ -70,7 +68,7 @@ export fn new_datetime( min: int, sec: int, nsec: int, - loc: locality, + loc: chrono::locality, ) (datetime | errors::invalid) = { const dt = datetime { date = localdate { diff --git a/datetime/timezone.ha b/datetime/timezone.ha @@ -0,0 +1,63 @@ +use time; +use time::chrono; + +// Retrieves a IANA timezone object by name +export fn tzdb(name: str) chrono::timezone = { + // TODO + return chrono::timezone { ... }; +}; + + +// Europe/Amsterdam timezone +export const TZ_Europe_Amsterdam: chrono::timezone = chrono::timezone { + aliasof = &TZ_CET, + name = "Europe/Amsterdam", + ... +}; + +// Central European Time +export const TZ_CET: chrono::timezone = chrono::timezone { + aliasof = void, + scale = &chrono::UTC, + zones = [ + chrono::zone { + zoffset = 1 * time::HOUR, + name = "Central European Time", + abbrev = "CET", + dst = false, + }, + chrono::zone { + zoffset = 2 * time::HOUR, + name = "Central European Summer Time", + abbrev = "CEST", + dst = true, + }, + ], + applied = &zone_cet, + name = "CET", +}; + +fn zone_cet(m: chrono::moment) uint = { + const dt = conv_moment_datetime(m); + const dst = ( + dt.date.month: int == 3 && + dt.date.day: int == 28 && + dt.time.hour: int >= 2 + ) || ( + dt.date.month: int > 3 && dt.date.month: int < 8 + ) || ( + dt.date.month: int == 8 && + dt.date.day: int < 31 + ) || ( + dt.date.month: int == 8 && + dt.date.day: int == 31 && + dt.time.hour: int <= 3 + ); + + if (dst) { + return 1u; + } else { + return 0u; + }; +}; + diff --git a/scripts/gen-stdlib b/scripts/gen-stdlib @@ -185,6 +185,7 @@ datetime() { gen_srcs datetime \ calendar.ha \ datetime.ha \ + timezone.ha \ date.ha \ time.ha gen_ssa datetime time time::chrono diff --git a/stdlib.mk b/stdlib.mk @@ -931,6 +931,7 @@ $(HARECACHE)/crypto/curve25519/crypto_curve25519-any.ssa: $(stdlib_crypto_curve2 stdlib_datetime_any_srcs= \ $(STDLIB)/datetime/calendar.ha \ $(STDLIB)/datetime/datetime.ha \ + $(STDLIB)/datetime/timezone.ha \ $(STDLIB)/datetime/date.ha \ $(STDLIB)/datetime/time.ha @@ -2892,6 +2893,7 @@ $(TESTCACHE)/crypto/curve25519/crypto_curve25519-any.ssa: $(testlib_crypto_curve testlib_datetime_any_srcs= \ $(STDLIB)/datetime/calendar.ha \ $(STDLIB)/datetime/datetime.ha \ + $(STDLIB)/datetime/timezone.ha \ $(STDLIB)/datetime/date.ha \ $(STDLIB)/datetime/time.ha diff --git a/time/README b/time/README @@ -1,4 +1,4 @@ The time module provides basic timekeeping primitives and access to the system's clocks. -For more human abstractions of time, see the [[chrono]] module. +For more human abstractions of time, see the [[time::chrono]] module. diff --git a/time/chrono/README b/time/chrono/README @@ -1,4 +1,5 @@ -The chrono module provides the basis for chronology, namely timescales -and leap seconds, and abstracted interfaces for calendars and datetimes. +The time::chrono submodule provides the basis for chronology in Hare, +namely timescales, leap seconds, and "moments", an abstracted datetime +for calendars to interface with. -For working with the ISO calendar, see the [[chrono::isocal]] submodule. +For working with the ISO calendar, see the [[datetime]] submodule. diff --git a/time/chrono/chronology.ha b/time/chrono/chronology.ha @@ -8,7 +8,7 @@ use time; // scale: timescale, // }; -// A date & time within a chronology +// A date & time within a locality, to be contextualised in a chronology export type moment = struct { date: epochal, time: time::duration, diff --git a/time/chrono/timezone.ha b/time/chrono/timezone.ha @@ -1,48 +1,61 @@ use time; // Represents the locality of a datetime -export type locality = (local | zoffset | timezone); +export type locality = (local | zoffset | *timezone); // Represents its associated datetime as local export type local = void; -// Represents a simple, constant timezone offset +// Represents a simple, constant zone offset export type zoffset = time::duration; // Represents a conditional offset, dependant on the time of year export type zone = struct { - zoffset: zoffset, - applied: *fn(m: moment) bool, - abbrev: str, // "CET" - dst: bool, + zoffset: zoffset, // 2 * time::HOUR + name: str, // "Central European Summer Time" + abbrev: str, // "CEST" + dst: bool, // true }; // Represents a timezone; a political region with a ruleset regarding offsets export type timezone = struct { - timescale: timescale, + aliasof: (void | *timezone), + scale: *timescale, zones: []zone, + applied: *fn(m: moment) uint, name: str, // "Europe/Amsterdam" }; -// Retrieves a IANA timezone object by name -export fn tzdb(name: str) timezone = { - // TODO - return timezone { ... }; +export const TZ_UTC: timezone = timezone { + aliasof = void, + scale = &UTC, + zones = [ + zone { + zoffset = 0 * time::SECOND, + name = "Universal Coordinated Time", + abbrev = "UTC", + dst = false, + }, + ], + applied = &zone_const, + name = "Etc/UTC", }; -// export const TZ_UTC: timezone = timezone { -// timescale = UTC, -// zones = [ -// zone { -// zoffset = 0 * time::SECOND, -// applied = &zone_always, -// abbrev = "UTC", -// dst = false, -// }, -// ], -// name = "Etc/UTC", -// }; -// -// fn zone_always(m: moment) bool = { -// return true; -// }; +export const TZ_TAI: timezone = timezone { + aliasof = void, + scale = &TAI, + zones = [ + zone { + zoffset = 0 * time::SECOND, + name = "International Atomic Time", + abbrev = "TAI", + dst = false, + }, + ], + applied = &zone_const, + name = "", +}; + +fn zone_const(m: moment) uint = { + return 0u; +};