Files
zen/core/expression/tests/data/date.csv
T
stefan-gorules 39916c9d18 feat: date input (#529)
* feat: declared dates as date values

- graph format:date/date-time inputs and policy date properties arrive as
  dates that keep their original text for output, string() and string
  functions
- d() keeps the instant of offset/Z strings, resolves DST gaps and accepts
  ISO forms without offset, compact, slash-separated, YYYY-MM and YYYY
- dates compare with date strings in ==, !=, <, >, in and contains, and
  concatenate with strings; deprecated date helpers accept dates
- string(date), type() reports date, and date-to-string at string inputs

* fix: close review gaps in date inputs

- parse new date formats by exact shape; keep master formats first and
  guard DST-gap and extreme-year overflows
- text-carrying dates act as strings for object keys, in-object, index,
  slice, concatenation and bool
- deprecated helpers fall back to the date instant; time() accepts dates
- schema-less child inputs receive date text; dates satisfy string
  parameters and slicing in the type checker
- convert policy input before validation so dates are parsed once;
  share rewrite helpers between graph and policy conversion

* fix: align date text, unions, references and child inputs

- every valid date exposes a text form (original or RFC3339), so string
  functions and slicing on computed dates match the type checker
- date and string types merge to string; reference ids typed as dates
  resolve through their text
- input nodes convert declared dates and hand every other converted date
  back as its original text, following combinators only for structure
- date format checks no longer allocate
2026-09-29 09:59:44 +02:00

14 KiB

1expression (string);input (json 5);output (json 5)
2# Date function basics
3d('2023-10-15');;'2023-10-15T00:00:00Z'
4d('2023-10-15 14:30');;'2023-10-15T14:30:00Z'
5d('2023-10-15 14:30:45');;'2023-10-15T14:30:45Z'
6d('2023-10-15', 'Europe/Berlin');;'2023-10-15T00:00:00+02:00'
7d('2023-10-15 14:30', 'Europe/Berlin');;'2023-10-15T14:30:00+02:00'
8d('2023-10-15 14:30:45', 'Europe/Berlin');;'2023-10-15T14:30:45+02:00'
9d('Europe/Berlin').isValid() and d('Europe/Berlin').isToday();;true
10# ISO 8601 forms
11d('2023-10-15T14:30');;'2023-10-15T14:30:00Z'
12d('2023-10-15T14:30:45');;'2023-10-15T14:30:45Z'
13d('2023-10-15T14:30:45.123').format('%Y-%m-%d %H:%M:%S%.3f');;'2023-10-15 14:30:45.123'
14d('2023-10-15 14:30:45.5').format('%Y-%m-%d %H:%M:%S%.3f');;'2023-10-15 14:30:45.500'
15d('2023-10-15T14:30Z');;'2023-10-15T14:30:00Z'
16d('20231015T143045Z');;'2023-10-15T14:30:45Z'
17d('20231015T1430');;'2023-10-15T14:30:00Z'
18d('20231015');;'2023-10-15T00:00:00Z'
19d('2023/10/15');;'2023-10-15T00:00:00Z'
20d('2023/10/15 14:30');;'2023-10-15T14:30:00Z'
21d('2023-10');;'2023-10-01T00:00:00Z'
22d('2023');;'2023-01-01T00:00:00Z'
23d('2023-10-15T14:30', 'Europe/Berlin');;'2023-10-15T14:30:00+02:00'
24d('2023-13').isValid();;false
25d('2023-02-30').isValid();;false
26d('12345').isValid();;false
27d('202310').isValid();;false
28d('hello').isValid();;false
29d('2023105').isValid();;false
30d('2023011').isValid();;false
31d('2023101T1430').isValid();;false
32d('2023 1015').isValid();;false
33d('+2023-1').isValid();;false
34d('2023/1/5 1:2').isValid();;false
35d('2023-10-15T14:30:45 Z').isValid();;false
36d('-262143-01-01T00:00:00Z').isValid();;false
37d('-262143-01-01', 'Asia/Tokyo').isValid();;false
38# Offsets keep the instant
39d('2023-10-15T14:30+0200');;'2023-10-15T12:30:00Z'
40d('2023-10-15T14:30:45-0530');;'2023-10-15T20:00:45Z'
41d('2023-10-15T14:30:45+02');;'2023-10-15T12:30:45Z'
42d('2023-10-15T14:30:00+05:00');;'2023-10-15T09:30:00Z'
43d('2023-10-15T14:30:00+05:00').hour();;9
44d('2023-10-15T14:30:00+05:00', 'Europe/Berlin');;'2023-10-15T11:30:00+02:00'
45d(d('2023-10-15T12:00:00Z'), 'Europe/Berlin');;'2023-10-15T14:00:00+02:00'
46d('2023-10-15T14:30:00+05:00') == d('2023-10-15T09:30:00Z');;true
47# Local times inside a DST gap move forward by the gap
48d('2024-03-31 02:30', 'Europe/Berlin');;'2024-03-31T03:30:00+02:00'
49d('2024-03-31T02:30:00Z', 'Europe/Berlin');;'2024-03-31T04:30:00+02:00'
50# Dates compared with strings
51d('2023-10-15') == '2023-10-15';;true
52'2023-10-15' == d('2023-10-15');;true
53d('2023-10-15') == '2023-10-16';;false
54d('2023-10-15') != '2023-10-15';;false
55d('2023-10-15') > '2023-10-14';;true
56'2023-10-14' < d('2023-10-15');;true
57d('2023-10-15') in ['2023-10-14', '2023-10-15'];;true
58'2023-10-15' in [d('2023-10-15')];;true
59contains([d('2023-10-15')], '2023-10-15');;true
60string(d('2023-10-15'));;'2023-10-15T00:00:00Z'
61'on ' + d('2023-10-15');;'on 2023-10-15T00:00:00Z'
62year(d('2023-10-15'));;2023
63# Date manipulation
64d('2023-10-15').add('1d');;'2023-10-16T00:00:00Z'
65d('2023-10-15').add('1d 5h');;'2023-10-16T05:00:00Z'
66d('2023-10-15').add(1, 'd');;'2023-10-16T00:00:00Z'
67d('2023-10-15').sub('2d');;'2023-10-13T00:00:00Z'
68d('2023-10-15').sub(1, 'M');;'2023-09-15T00:00:00Z'
69# Date comparisons
70d('2023-10-15').isBefore(d('2023-10-16'));;true
71d('2023-10-15').isBefore(d('2023-10-15'));;false
72d('2023-10-15').isAfter(d('2023-10-14'));;true
73d('2023-10-15').isAfter(d('2023-10-15'));;false
74d('2023-10-15').isSame(d('2023-10-15'));;true
75d('2023-10-15').isSame(d('2023-10-16'));;false
76d('2023-10-15').isSameOrBefore(d('2023-10-15'));;true
77d('2023-10-15').isSameOrBefore(d('2023-10-16'));;true
78d('2023-10-15').isSameOrBefore(d('2023-10-14'));;false
79d('2023-10-15').isSameOrAfter(d('2023-10-15'));;true
80d('2023-10-15').isSameOrAfter(d('2023-10-14'));;true
81d('2023-10-15').isSameOrAfter(d('2023-10-16'));;false
82d('2025-02-01').isAfter(d('2025-01-05'), 'year');;false
83d('2025-02-01').isAfter(d('2024-12-31'), 'year');;true
84d('2025-02-01').isBefore(d('2025-03-01'), 'year');;false
85d('2025-02-01').isBefore(d('2026-01-01'), 'year');;true
86d('2025-02-01').isSame(d('2025-12-31'), 'year');;true
87d('2025-02-01').isSame(d('2026-01-01'), 'year');;false
88d('2025-02-15').isAfter(d('2025-01-05'), 'month');;true
89d('2025-02-15').isAfter(d('2025-02-05'), 'month');;false
90d('2025-02-15').isBefore(d('2025-03-01'), 'month');;true
91d('2025-02-15').isBefore(d('2025-02-28'), 'month');;false
92d('2025-02-15').isSame(d('2025-02-28'), 'month');;true
93d('2025-02-15').isSame(d('2025-03-01'), 'month');;false
94d('2025-04-15').isAfter(d('2025-01-01'), 'quarter');;true
95d('2025-02-15').isAfter(d('2025-03-31'), 'quarter');;false
96d('2025-02-15').isBefore(d('2025-04-01'), 'quarter');;true
97d('2025-02-15').isBefore(d('2025-03-31'), 'quarter');;false
98d('2025-02-15').isSame(d('2025-03-15'), 'quarter');;true
99d('2025-02-15').isSame(d('2025-04-01'), 'quarter');;false
100d('2025-02-15').isAfter(d('2025-02-14'), 'day');;true
101d('2025-02-15').isAfter(d('2025-02-15'), 'day');;false
102d('2025-02-15').isBefore(d('2025-02-16'), 'day');;true
103d('2025-02-15').isBefore(d('2025-02-15'), 'day');;false
104d('2025-02-15').isSame(d('2025-02-15 12:00:00'), 'day');;true
105d('2025-02-15').isSame(d('2025-02-16'), 'day');;false
106# Date getters
107d('2023-10-15').year();;2023
108d('2023-10-15').month();;10
109d('2023-10-15').day();;15
110d('2023-10-15').weekday();;7
111d('2023-10-16').weekday();;1
112d('2023-10-15').hour();;0
113d('2023-10-15').minute();;0
114d('2023-10-15').second();;0
115d('2023-10-15').dayOfYear();;288
116d('2023-01-01').dayOfYear();;1
117d('2023-12-31').dayOfYear();;365
118d('2024-12-31').dayOfYear();;366
119d('2023-10-15').quarter();;4
120d('2023-01-15').quarter();;1
121d('2023-04-15').quarter();;2
122d('2023-07-15').quarter();;3
123d('2023-10-15').timestamp();;1697328000000
124d('2023-10-15', 'Europe/Berlin').offsetName();;'Europe/Berlin'
125d('2023-10-15', 'America/Los_Angeles').offsetName();;'America/Los_Angeles'
126d('2023-10-15').isLeapYear();;false
127d('2024-10-15').isLeapYear();;true
128d('2000-10-15').isLeapYear();;true
129d('1900-10-15').isLeapYear();;false
130# Date setters
131d('2023-10-15').set('year', 2024);;'2024-10-15T00:00:00Z'
132d('2023-10-15').set('month', 5);;'2023-05-15T00:00:00Z'
133d('2023-10-15').set('day', 20);;'2023-10-20T00:00:00Z'
134d('2023-10-15T10:30:00Z').set('hour', 15);;'2023-10-15T15:30:00Z'
135d('2023-10-15T10:30:00Z').set('minute', 45);;'2023-10-15T10:45:00Z'
136d('2023-10-15T10:30:00Z').set('second', 30);;'2023-10-15T10:30:30Z'
137# Special date checks
138d().isSame(d(), 'day');;true
139d('2023-10-15').startOf('day');;'2023-10-15T00:00:00Z'
140d('2023-10-15T10:30:45Z').startOf('hour');;'2023-10-15T10:00:00Z'
141d('2023-10-15').endOf('day');;'2023-10-15T23:59:59Z'
142d('2023-10-15T10:30:45Z').endOf('hour');;'2023-10-15T10:59:59Z'
143d('2023-10-15').startOf('month');;'2023-10-01T00:00:00Z'
144d('2023-10-15').endOf('month');;'2023-10-31T23:59:59Z'
145d('2023-10-15').startOf('year');;'2023-01-01T00:00:00Z'
146d('2023-10-15').endOf('year');;'2023-12-31T23:59:59Z'
147d('2023-10-15').startOf('week');;'2023-10-09T00:00:00Z'
148d('2023-10-15').endOf('week');;'2023-10-15T23:59:59Z'
149d('2024-01-15').startOf('week');;'2024-01-15T00:00:00Z'
150d('2024-01-15').endOf('week');;'2024-01-21T23:59:59Z'
151d('2024-01-16').endOf('week');;'2024-01-21T23:59:59Z'
152d('2024-01-21').endOf('week');;'2024-01-21T23:59:59Z'
153d('2023-10-15').startOf('quarter');;'2023-10-01T00:00:00Z'
154d('2023-10-15').endOf('quarter');;'2023-12-31T23:59:59Z'
155d('2023-03-15').startOf('quarter');;'2023-01-01T00:00:00Z'
156d('2023-03-15').endOf('quarter');;'2023-03-31T23:59:59Z'
157d('2023-06-15').startOf('quarter');;'2023-04-01T00:00:00Z'
158d('2023-06-15').endOf('quarter');;'2023-06-30T23:59:59Z'
159d('2023-09-15').startOf('quarter');;'2023-07-01T00:00:00Z'
160d('2023-09-15').endOf('quarter');;'2023-09-30T23:59:59Z'
161# Timezone operations
162d('2023-10-15T00:00:00Z').tz('America/New_York');;'2023-10-14T20:00:00-04:00'
163d('2023-10-15T00:00:00Z').tz('Europe/London');;'2023-10-15T01:00:00+01:00'
164d('2023-10-15T00:00:00+00:00').tz('UTC');;'2023-10-15T00:00:00Z'
165d('2023-10-15T12:00:00+02:00', 'Etc/GMT-2').tz('UTC');;'2023-10-15T10:00:00Z'
166# Relative date methods
167d().sub(1, 'd').isYesterday();;true
168d().add(1, 'd').isTomorrow();;true
169d('2023-10-15').isToday();;false
170# Diff
171d('2023-10-15').diff(d('2023-10-10'), 'day');;5
172d('2023-10-15T10:00:00Z').diff(d('2023-10-15T08:30:00Z'), 'hour');;1
173d('2023-10-15').diff(d('2023-09-15'), 'month');;1
174d('2023-12-31').diff(d('2023-01-01'), 'year');;0
175d('2023-12-31').diff(d('2022-01-01'), 'year');;1
176d('2023-10-10').diff(d('2023-10-15'), 'day');;-5
177d('2023-09-15').diff(d('2023-10-15'), 'month');;-1
178d('2022-01-01').diff(d('2023-12-31'), 'year');;-1
179d('2023-10-15T10:30:00Z').diff(d('2023-10-15T10:00:00Z'), 'minute');;30
180d('2023-10-15T10:00:30Z').diff(d('2023-10-15T10:00:00Z'), 'second');;30
181d('2023-10-22').diff(d('2023-10-15'), 'week');;1
182d('2023-10-29').diff(d('2023-10-15'), 'week');;2
183d('2023-07-01').diff(d('2023-01-01'), 'quarter');;2
184d('2023-12-31').diff(d('2023-01-01'), 'quarter');;3
185d('2023-10-15').diff(d('2023-10-15'), 'day');;0
186d('2023-10-15').diff(d('2023-10-15'), 'month');;0
187d('2023-10-15').diff(d('2023-10-15'), 'year');;0
188d('2023-03-31').diff(d('2023-02-28'), 'month');;1
189d('2024-02-29').diff(d('2024-01-31'), 'month');;1
190d('2023-05-31').diff(d('2023-04-30'), 'month');;1
191d('2023-03-31').diff(d('2023-02-28'), 'month');;1
192d('2023-02-28').diff(d('2023-01-31'), 'month');;1
193d('2023-04-30').diff(d('2023-03-31'), 'month');;1
194d('2024-02-29').diff(d('2023-02-28'), 'year');;1
195d('2023-12-31').diff(d('2023-01-01'), 'year');;0
196d('2024-01-01').diff(d('2023-01-01'), 'year');;1
197d('2025-01-01').diff(d('2020-01-01'), 'year');;5
198d('2023-12-01').diff(d('2023-01-01'), 'month');;11
199d('2023-12-31').diff(d('2023-01-01'), 'day');;364
200d('2023-10-15T12:00:00Z').diff(d('2023-10-15T10:30:00Z'), 'hour');;1
201d('2023-10-16T12:00:00Z').diff(d('2023-10-15T18:00:00Z'), 'day');;0
202# Formatting
203d('2023-10-15').format('%Y-%m-%d');;'2023-10-15'
204d('2023-10-15').format('%Y/%m/%d');;'2023/10/15'
205d('2023-10-15T14:30:45Z').format('%A, %B %d %Y, %H:%M:%S');;'Sunday, October 15 2023, 14:30:45'
206d('2023-10-15T14:30:45Z').format('%a %b %d %H:%M');;'Sun Oct 15 14:30'
207d('2023-10-15T14:30:45Z').format('Day %j of year %Y');;'Day 288 of year 2023'
208d('2023-10-15T14:30:45.123Z').format('%H:%M:%S.%f');;'14:30:45.123000000'
209# Date validations
210d(null).isValid();;false
211d('foo').isValid();;false
212d('2023-13-01').isValid();;false
213d('2023-02-30').isValid();;false
214# Date comparison operators
215d('2023-10-15') == d('2023-10-15');;true
216d('2023-10-15') == d('2023-10-16');;false
217d('2023-10-15') != d('2023-10-16');;true
218d('2023-10-15') != d('2023-10-15');;false
219d('2023-10-15') < d('2023-10-16');;true
220d('2023-10-15') < d('2023-10-15');;false
221d('2023-10-15') <= d('2023-10-15');;true
222d('2023-10-16') <= d('2023-10-15');;false
223d('2023-10-16') > d('2023-10-15');;true
224d('2023-10-15') > d('2023-10-15');;false
225d('2023-10-15') >= d('2023-10-15');;true
226d('2023-10-15') >= d('2023-10-16');;false
227# Date range operators
228d('2023-10-15') in [d('2023-10-01')..d('2023-10-31')];;true
229d('2023-10-01') in [d('2023-10-01')..d('2023-10-31')];;true
230d('2023-10-31') in [d('2023-10-01')..d('2023-10-31')];;true
231d('2023-09-30') in [d('2023-10-01')..d('2023-10-31')];;false
232d('2023-11-01') in [d('2023-10-01')..d('2023-10-31')];;false
233d('2023-10-15') in (d('2023-10-01')..d('2023-10-31'));;true
234d('2023-10-01') in (d('2023-10-01')..d('2023-10-31'));;false
235d('2023-10-31') in (d('2023-10-01')..d('2023-10-31'));;false
236d('2023-10-02') in (d('2023-10-01')..d('2023-10-31'));;true
237d('2023-10-30') in (d('2023-10-01')..d('2023-10-31'));;true
238d('2023-10-15') in [d('2023-10-01')..d('2023-10-31'));;true
239d('2023-10-01') in [d('2023-10-01')..d('2023-10-31'));;true
240d('2023-10-31') in [d('2023-10-01')..d('2023-10-31'));;false
241d('2023-10-30') in [d('2023-10-01')..d('2023-10-31'));;true
242d('2023-10-15') in (d('2023-10-01')..d('2023-10-31')];;true
243d('2023-10-01') in (d('2023-10-01')..d('2023-10-31')];;false
244d('2023-10-31') in (d('2023-10-01')..d('2023-10-31')];;true
245d('2023-10-02') in (d('2023-10-01')..d('2023-10-31')];;true
246d('2023-10-15') not in [d('2023-10-01')..d('2023-10-31')];;false
247d('2023-09-30') not in [d('2023-10-01')..d('2023-10-31')];;true
248d('2023-11-01') not in [d('2023-10-01')..d('2023-10-31')];;true
249d('2023-10-01') not in (d('2023-10-01')..d('2023-10-31'));;true
250d('2023-10-31') not in (d('2023-10-01')..d('2023-10-31'));;true
251d('2023-10-15') not in (d('2023-10-01')..d('2023-10-31'));;false
252d('2023-10-31') not in [d('2023-10-01')..d('2023-10-31'));;true
253d('2023-10-01') not in (d('2023-10-01')..d('2023-10-31')];;true
254min([d('2023-01-15'), d('2023-03-20'), d('2023-02-10')]);;'2023-01-15T00:00:00Z'
255max([d('2023-01-15'), d('2023-03-20'), d('2023-02-10')]);;'2023-03-20T00:00:00Z'
256min([d('2023-10-15'), d('2023-10-01'), d('2023-10-31')]);;'2023-10-01T00:00:00Z'
257max([d('2023-10-15'), d('2023-10-01'), d('2023-10-31')]);;'2023-10-31T00:00:00Z'
258min([d('2023-10-15T10:30:00Z'), d('2023-10-15T08:15:00Z'), d('2023-10-15T14:45:00Z')]);;'2023-10-15T08:15:00Z'
259max([d('2023-10-15T10:30:00Z'), d('2023-10-15T08:15:00Z'), d('2023-10-15T14:45:00Z')]);;'2023-10-15T14:45:00Z'
260min([d('2022-12-31'), d('2023-01-01'), d('2024-01-01')]);;'2022-12-31T00:00:00Z'
261max([d('2022-12-31'), d('2023-01-01'), d('2024-01-01')]);;'2024-01-01T00:00:00Z'
262min([d('2023-10-15'), d('2023-10-15'), d('2023-10-15')]);;'2023-10-15T00:00:00Z'
263max([d('2023-10-15'), d('2023-10-15'), d('2023-10-15')]);;'2023-10-15T00:00:00Z'
264min([d('2023-10-15')]);;'2023-10-15T00:00:00Z'
265max([d('2023-10-15')]);;'2023-10-15T00:00:00Z'
266min([d('2023-10-15T10:00:00Z'), d('2023-10-15T12:00:00Z')]);;'2023-10-15T10:00:00Z'
267max([d('2023-10-15T10:00:00Z'), d('2023-10-15T12:00:00Z')]);;'2023-10-15T12:00:00Z'
268min([d('1900-01-01'), d('2000-01-01'), d('1950-06-15')]);;'1900-01-01T00:00:00Z'
269max([d('1900-01-01'), d('2000-01-01'), d('1950-06-15')]);;'2000-01-01T00:00:00Z'
270min([d('2024-02-29'), d('2023-02-28'), d('2024-03-01')]);;'2023-02-28T00:00:00Z'
271max([d('2024-02-29'), d('2023-02-28'), d('2024-03-01')]);;'2024-03-01T00:00:00Z'
272min([d('2023-01-31'), d('2023-02-28'), d('2023-03-31')]);;'2023-01-31T00:00:00Z'
273max([d('2023-01-31'), d('2023-02-28'), d('2023-03-31')]);;'2023-03-31T00:00:00Z'
274min([d('2023-10-15').add(1, 'd'), d('2023-10-15').sub(1, 'd'), d('2023-10-15')]);;'2023-10-14T00:00:00Z'
275max([d('2023-10-15').add(1, 'd'), d('2023-10-15').sub(1, 'd'), d('2023-10-15')]);;'2023-10-16T00:00:00Z'
276min([d('2023-01-01'), d('2023-12-31')]).isBefore(d('2023-06-01'));;true
277max([d('2023-01-01'), d('2023-12-31')]).isAfter(d('2023-06-01'));;true