Implement most of the builtin time module (#82)

* Implement builtin `time.add_date` method

* Implement builtin `time.clock` method

* Implement builtin `time.date` method

* Implement builtin `time.diff` method

* Implement builtin `time.format` method

* Migrate `time.now_ns` to `chrono`

* Implement builtin `time.parse_ns` method

* Implement builtin `time.parse_rfc3339_ns` method

* Implement builtin `time.weekday` method

* Add conditional `test` module for OPA tests

* Cache result of `time.now_ns`

* Fail in strict mode if timestamp is outside of range

* Add `ensure_i32` util

* Move `diff_between_datetimes` into its own file and include appropriate license
This commit is contained in:
Burak
2024-01-01 01:07:39 +00:00
committed by GitHub
parent 2292774446
commit d2eb3ecd1f
14 changed files with 1002 additions and 12 deletions
@@ -0,0 +1,253 @@
# Copyright (c) Microsoft Corporation.
# Licensed under the MIT License.
cases:
- note: adding-nothing
data: {}
modules:
- |
package test
a := time.add_date(1703444325734390000, 0, 0, 0)
query: data.test
want_result:
a: 1703444325734390000
- note: adding-years
data: {}
modules:
- |
package test
a := time.add_date(1703444325734390000, 1, 0, 0)
b := time.add_date(1703444325734390000, 60, 0, 0)
query: data.test
want_result:
a: 1735066725734390000
b: 3596900325734390000
- note: subtracting-years
data: {}
modules:
- |
package test
a := time.add_date(1703444325734390000, -1, 0, 0)
b := time.add_date(1703444325734390000, -60, 0, 0)
query: data.test
want_result:
a: 1671908325734390000
b: -190011674265610000
- note: adding-overflowing-years
data: {}
modules:
- |
package test
a := time.add_date(1703444325734390000, 2147483647, 0, 0)
query: data.test
want_result: {}
- note: subtracting-overflowing-years
data: {}
modules:
- |
package test
a := time.add_date(1703444325734390000, -2147483647, 0, 0)
query: data.test
want_result: {}
- note: adding-months
data: {}
modules:
- |
package test
a := time.add_date(1703444325734390000, 0, 1, 0)
b := time.add_date(1703444325734390000, 0, 12, 0)
query: data.test
want_result:
a: 1706122725734390000
b: 1735066725734390000
- note: subtracting-months
data: {}
modules:
- |
package test
a := time.add_date(1703444325734390000, 0, -1, 0)
b := time.add_date(1703444325734390000, 0, -12, 0)
query: data.test
want_result:
a: 1700852325734390000
b: 1671908325734390000
- note: adding-overflowing-months
data: {}
modules:
- |
package test
a := time.add_date(1703444325734390000, 0, 15, 0)
b := time.add_date(1703444325734390000, 0, 19, 0)
query: data.test
want_result:
a: 1742842725734390000
b: 1753383525734390000
- note: subtracting-overflowing-months
data: {}
modules:
- |
package test
a := time.add_date(1703444325734390000, 0, -15, 0)
b := time.add_date(1703444325734390000, 0, -19, 0)
query: data.test
want_result:
a: 1664045925734390000
b: 1653418725734390000
- note: adding-days
data: {}
modules:
- |
package test
a := time.add_date(1703444325734390000, 0, 0, 5)
b := time.add_date(1703444325734390000, 0, 0, 16)
query: data.test
want_result:
a: 1703876325734390000
b: 1704826725734390000
- note: subtracting-days
data: {}
modules:
- |
package test
a := time.add_date(1703444325734390000, 0, 0, -5)
b := time.add_date(1703444325734390000, 0, 0, -16)
query: data.test
want_result:
a: 1703012325734390000
b: 1702061925734390000
- note: adding-overflowing-days
data: {}
modules:
- |
package test
a := time.add_date(1703444325734390000, 0, 0, 31)
b := time.add_date(1703444325734390000, 0, 0, 37)
query: data.test
want_result:
a: 1706122725734390000
b: 1706641125734390000
- note: subtracting-overflowing-days
data: {}
modules:
- |
package test
a := time.add_date(1703444325734390000, 0, 0, -31)
b := time.add_date(1703444325734390000, 0, 0, -37)
query: data.test
want_result:
a: 1700765925734390000
b: 1700247525734390000
- note: adding-mixed
data: {}
modules:
- |
package test
a := time.add_date(1703444325734390000, 213, 6, 5)
b := time.add_date(1703444325734390000, 5, 0, 6)
c := time.add_date(1703444325734390000, 0, 3, 16)
d := time.add_date(1703444325734390000, 7, 3, 0)
e := time.add_date(1703444325734390000, 10, 2, 16)
f := time.add_date(1703444325734390000, 10, 14, 16)
g := time.add_date(1703444325734390000, 10, 14, 75)
query: data.test
want_result:
a: 8441261925734390000
b: 1861815525734390000
c: 1712689125734390000
d: 1932145125734390000
e: 2025802725734390000
f: 2057338725734390000
g: 2062436325734390000
- note: subtracting-mixed
data: {}
modules:
- |
package test
a := time.add_date(1703444325734390000, -213, -6, -5)
b := time.add_date(1703444325734390000, -5, 0, -6)
c := time.add_date(1703444325734390000, 0, -3, -16)
d := time.add_date(1703444325734390000, -7, -3, 0)
e := time.add_date(1703444325734390000, -10, -2, -16)
f := time.add_date(1703444325734390000, -10, -14, -16)
g := time.add_date(1703444325734390000, -10, -14, -75)
query: data.test
want_result:
a: -5034459674265610000
b: 1545159525734390000
c: 1694199525734390000
d: 1474743525734390000
e: 1381258725734390000
f: 1349722725734390000
g: 1344625125734390000
- note: mixed-operations
data: {}
modules:
- |
package test
a := time.add_date(1703444325734390000, -213, 6, -5)
b := time.add_date(1703444325734390000, 5, 0, -6)
c := time.add_date(1703444325734390000, 0, -3, -16)
d := time.add_date(1703444325734390000, 8, -3, 0)
e := time.add_date(1703444325734390000, -10, 2, 16)
f := time.add_date(1703444325734390000, -10, 14, -16)
g := time.add_date(1703444325734390000, 10, 14, -75)
query: data.test
want_result:
a: -5002923674265610000
b: 1860778725734390000
c: 1694199525734390000
d: 1948042725734390000
e: 1394650725734390000
f: 1423421925734390000
g: 2049476325734390000
- note: missing-arguments
data: {}
modules:
- |
package test
a := time.add_date()
query: data.test
error: '`time.add_date` expects 4 arguments'
- note: invalid-type
data: {}
modules:
- |
package test
a := time.add_date("1703444325734390000", 0, 0, 0)
query: data.test
error: '`time.add_date` expects `ns` to be a `number` or `array[number, string]`. Got `"1703444325734390000"` instead'
@@ -0,0 +1,71 @@
# Copyright (c) Microsoft Corporation.
# Licensed under the MIT License.
cases:
- note: without-timezone
data: {}
modules:
- |
package test
a := time.clock(1703444325734390000)
query: data.test
want_result:
a:
- 18
- 58
- 45
- note: with-utc-timezone
data: {}
modules:
- |
package test
a := time.clock([1703444325734390000, "UTC"])
b := time.clock([1703444325734390000, ""])
query: data.test
want_result:
a:
- 18
- 58
- 45
b:
- 18
- 58
- 45
- note: with-cet-timezone
data: {}
modules:
- |
package test
a := time.clock([1703444325734390000, "CET"])
query: data.test
want_result:
a:
- 19
- 58
- 45
- note: with-local-timezone
data: {}
modules:
- |
package test
a := time.clock([1703444325734390000, "Local"]) != null
query: data.test
want_result:
a: true
- note: invalid-type
data: {}
modules:
- |
package test
a := time.clock("1703444325734390000")
query: data.test
error: '`time.clock` expects `ns` to be a `number` or `array[number, string]`. Got `"1703444325734390000"` instead'
@@ -0,0 +1,46 @@
# Copyright (c) Microsoft Corporation.
# Licensed under the MIT License.
cases:
- note: without-timezone
data: {}
modules:
- |
package test
a := time.date(1703444325734390000)
query: data.test
want_result:
a:
- 2023
- 12
- 24
- note: with-utc-timezone
data: {}
modules:
- |
package test
a := time.date([1257894000000000000, "UTC"])
b := time.date([1703896119423491000, ""])
query: data.test
want_result:
a:
- 2009
- 11
- 10
b:
- 2023
- 12
- 30
- note: invalid-type
data: {}
modules:
- |
package test
a := time.date("1703444325734390000")
query: data.test
error: '`time.date` expects `ns` to be a `number` or `array[number, string]`. Got `"1703444325734390000"` instead'
@@ -0,0 +1,64 @@
# Copyright (c) Microsoft Corporation.
# Licensed under the MIT License.
cases:
- note: without-timezone
data: {}
modules:
- |
package test
a := time.diff(1703444325734390000, 1257894000000000000)
query: data.test
want_result:
a:
- 14
- 1
- 13
- 19
- 58
- 45
- note: with-timezone
data: {}
modules:
- |
package test
a := time.diff([1703444325734390000, "UTC"], [1257894000000000000, ""])
query: data.test
want_result:
a:
- 14
- 1
- 13
- 19
- 58
- 45
- note: tz1-greater-than-tz2
data: {}
modules:
- |
package test
a := time.diff(1257894000000000000, 1703444325734390000)
query: data.test
want_result:
a:
- 14
- 1
- 13
- 19
- 58
- 45
- note: invalid-type
data: {}
modules:
- |
package test
a := time.diff("1703444325734390000", 1257894000000000000)
query: data.test
error: '`time.diff` expects `ns` to be a `number` or `array[number, string]`. Got `"1703444325734390000"` instead'
@@ -0,0 +1,52 @@
# Copyright (c) Microsoft Corporation.
# Licensed under the MIT License.
cases:
- note: without-timezone-and-format
data: {}
modules:
- |
package test
a := time.format(1703444325734390000)
b := time.format(1257894000000000000)
query: data.test
want_result:
a: "2023-12-24T18:58:45.734390Z"
b: "2009-11-10T23:00:00Z"
- note: with-timezone-and-no-format
data: {}
modules:
- |
package test
a := time.format([1703444325734390000, "UTC"])
b := time.format([1257894000000000000, ""])
query: data.test
want_result:
a: "2023-12-24T18:58:45.734390Z"
b: "2009-11-10T23:00:00Z"
- note: with-timezone-and-format
data: {}
modules:
- |
package test
a := time.format([1703444325734390000, "UTC", "%Y-%m-%dT%H:%M:%S"])
b := time.format([1257894000000000000, "", "%d/%m/%Y %H:%M"])
query: data.test
want_result:
a: "2023-12-24T18:58:45"
b: "10/11/2009 23:00"
- note: invalid-type
data: {}
modules:
- |
package test
a := time.format([1703444325734390000, "UTC", 42])
query: data.test
error: '`time.format` expects 3rd element of `ns` to be a `string`. Got `42` instead'
@@ -0,0 +1,29 @@
# Copyright (c) Microsoft Corporation.
# Licensed under the MIT License.
cases:
- note: now-is-greater-than-2009
data: {}
modules:
- |
package test
a := time.now_ns() > 1257894000000000000
query: data.test
want_result:
a: true
- note: now-is-cached
data: {}
modules:
- |
package test
a := res {
first := time.now_ns()
second := time.now_ns()
res := second == first
}
query: data.test
want_result:
a: true
@@ -0,0 +1,40 @@
# Copyright (c) Microsoft Corporation.
# Licensed under the MIT License.
cases:
- note: parse
data: {}
modules:
- |
package test
a := time.parse_ns("%Y-%m-%dT%H:%M:%S", "2006-01-02T15:04:05")
b := time.parse_ns("%Y-%m-%d %H:%M:%S", "2015-09-05 23:56:04")
query: data.test
want_result:
a: 1136214245000000000
b: 1441497364000000000
- note: format-and-parse-back
data: {}
modules:
- |
package test
a := res {
date := time.format([1703444325734390000, "UTC", "%Y-%m-%dT%H:%M:%S%.f"])
res := time.parse_ns("%Y-%m-%dT%H:%M:%S%.f", date)
}
query: data.test
want_result:
a: 1703444325734390000
- note: invalid-type
data: {}
modules:
- |
package test
a := time.parse_ns("%Y-%m-%dT%H:%M:%S%.f", 1703444325734390000)
query: data.test
error: '`time.parse_ns` expects string argument. Got `1703444325734390000` instead'
@@ -0,0 +1,27 @@
# Copyright (c) Microsoft Corporation.
# Licensed under the MIT License.
cases:
- note: parse-rfc3339
data: {}
modules:
- |
package test
a := time.parse_rfc3339_ns("1985-04-12T23:20:50.52Z")
b := time.parse_rfc3339_ns("1996-12-19T16:39:57-08:00")
query: data.test
want_result:
a: 482196050520000000
b: 851042397000000000
- note: invalid-type
data: {}
modules:
- |
package test
a := time.parse_rfc3339_ns(482196050520000000)
query: data.test
error: '`time.parse_rfc3339_ns` expects string argument. Got `482196050520000000` instead'
@@ -0,0 +1,39 @@
# Copyright (c) Microsoft Corporation.
# Licensed under the MIT License.
cases:
- note: without-timezone
data: {}
modules:
- |
package test
a := time.weekday(1703444325734390000)
b := time.weekday(1257894000000000000)
query: data.test
want_result:
a: "Sunday"
b: "Tuesday"
- note: with-timezone
data: {}
modules:
- |
package test
a := time.weekday([1703444325734390000, "UTC"])
b := time.weekday([1257894000000000000, ""])
query: data.test
want_result:
a: "Sunday"
b: "Tuesday"
- note: invalid-type
data: {}
modules:
- |
package test
a := time.weekday("1703444325734390000")
query: data.test
error: '`time.weekday` expects `ns` to be a `number` or `array[number, string]`. Got `"1703444325734390000"` instead'