Skip to content

Commit 1ebbbc3

Browse files
committed
FEAT: enabling T as a delimiter between date and time and Z as a zero timezone, so subset of ISO8601 datetime values are loadable from Rebol.
Example: ``` >> 2013-11-08T17:01 == 8-Nov-2013/17:01 >> 2013-11-08T17:01+0100 == 8-Nov-2013/17:01+1:00 >> 2013-11-08T17:01Z == 8-Nov-2013/17:01 ``` Related issues: metaeducation/rebol-issues#438 metaeducation/rebol-issues#2089 metaeducation/rebol-issues#2092
1 parent 035df2a commit 1ebbbc3

File tree

4 files changed

+48
-2
lines changed

4 files changed

+48
-2
lines changed

src/core/l-scan.c

+2-1
Original file line numberDiff line numberDiff line change
@@ -981,7 +981,8 @@
981981

982982
return -TOKEN_INTEGER;
983983
}
984-
if (HAS_LEX_FLAG(flags, LEX_SPECIAL_COLON)) return TOKEN_TIME; /* 12:34 */
984+
if (HAS_LEX_FLAG(flags, LEX_SPECIAL_COLON))
985+
return (HAS_LEX_FLAG(flags, LEX_SPECIAL_WORD) ? TOKEN_DATE : TOKEN_TIME); /* iso8601 datetime or 12:34 */
985986
if (HAS_LEX_FLAG(flags, LEX_SPECIAL_PERIOD)) { /* 1.2 1.2.3 1,200.3 1.200,3 1.E-2 */
986987
if (Skip_To_Char(cp, scan_state->end, 'x')) return TOKEN_PAIR;
987988
cp = Skip_To_Char(cp, scan_state->end, '.');

src/core/l-types.c

+8-1
Original file line numberDiff line numberDiff line change
@@ -525,7 +525,7 @@ bad_hex: Trap0(RE_INVALID_CHARS);
525525
VAL_TIME(value) = NO_TIME;
526526
if (cp >= end) goto end_date;
527527

528-
if (*cp == '/' || *cp == ' ') {
528+
if (*cp == '/' || *cp == 'T' || *cp == ' ') { //@@ Oldes: is the check for space really needed here?
529529
sep = *cp++;
530530
if (cp >= end) goto end_date;
531531
cp = Scan_Time(cp, 0, value);
@@ -535,12 +535,19 @@ bad_hex: Trap0(RE_INVALID_CHARS);
535535

536536
if (*cp == sep) cp++;
537537

538+
if (*cp == 'Z') {
539+
// 'Z' must be last char in the ISO8601 date (if used).
540+
if (++cp == end) goto end_date; // valid timezone 0:0
541+
else return 0;
542+
}
538543
// Time zone can be 12:30 or 1230 (optional hour indicator)
539544
if (*cp == '-' || *cp == '+') {
540545
if (cp >= end) goto end_date;
541546
ep = Grab_Int(cp+1, &num);
542547
if (ep-cp == 0) return 0;
543548
if (*ep != ':') {
549+
// An integer is assumed to be HHMM format
550+
// https://github.com/rebol/rebol-issues/issues/1411#issuecomment-170907151
544551
int h, m;
545552
if (num < -1500 || num > 1500) return 0;
546553
h = (num / 100);

src/tests/run-tests.r3

+1
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ dt [ ;- delta time
2828
wrap load %units/codecs-test.r3
2929
wrap load %units/series-test.r3
3030
wrap load %units/compress-test.r3
31+
wrap load %units/date-test.r3
3132

3233
recycle/torture
3334
recycle

src/tests/units/date-test.r3

+37
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
Rebol [
2+
Title: "Rebol3 date test script"
3+
Author: "Oldes, Peter W A Wood"
4+
File: %date-test.r3
5+
Tabs: 4
6+
Needs: [%../quick-test-module.r3]
7+
]
8+
9+
~~~start-file~~~ "date"
10+
11+
===start-group=== "ISO88601 subset"
12+
--test-- "ISO88601 basic load"
13+
--assert 8-Nov-2013/17:01 = load "2013-11-08T17:01"
14+
--assert 8-Nov-2013/17:01 = load "2013-11-08T17:01Z"
15+
--assert 8-Nov-2013/17:01+1:00 = load "2013-11-08T17:01+0100"
16+
--assert 8-Nov-2013/17:01-1:00 = load "2013-11-08T17:01-0100"
17+
--assert 8-Nov-2013/17:01+1:00 = load "2013-11-08T17:01+01:00"
18+
--test-- "basic load of not fully standard ISO88601"
19+
--assert 8-Nov-2013/17:01 = load "2013/11/08T17:01"
20+
--assert 8-Nov-2013/17:01 = load "2013/11/08T17:01Z"
21+
--assert 8-Nov-2013/17:01+1:00 = load "2013/11/08T17:01+0100"
22+
--assert 8-Nov-2013/17:01+1:00 = load "2013/11/08T17:01+01:00"
23+
--test-- "Invalid ISO88601 dates"
24+
--assert error? try [load "2013-11-08T17:01Z0100"]
25+
--assert error? try [load "2013/11/08T17:01Z0100"]
26+
27+
--test-- "Using ISO88601 datetime in a path"
28+
;@@ https://github.com/rebol/rebol-issues/issues/2089
29+
b: [8-Nov-2013/17:01 "foo"]
30+
--assert "foo" = b/2013-11-08T17:01
31+
32+
===end-group===
33+
34+
35+
===end-group===
36+
37+
~~~end-file~~~

0 commit comments

Comments
 (0)