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:
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;
+};