Skip to content

Commit 8fe060a

Browse files
committed
FEAT: adding /TIMEZONE to DATE values which adjust the time
`/timezome` was first introduced in Red language and it can be used to change the time zone with adjusting the time, while `/zone` keeps time unmodified. Any date can be now easily converted to UTC just setting the `timezone` to zero.
1 parent 679d4e2 commit 8fe060a

File tree

2 files changed

+33
-6
lines changed

2 files changed

+33
-6
lines changed

src/core/t-date.c

+16-6
Original file line numberDiff line numberDiff line change
@@ -500,7 +500,7 @@
500500
REBINT i;
501501
REBINT n;
502502
REBI64 secs;
503-
REBINT tz;
503+
REBINT tz, tzp;
504504
REBDAT date;
505505
REBINT day, month, year;
506506
REBINT num;
@@ -525,6 +525,7 @@
525525
case SYM_HOUR: i = 9; break;
526526
case SYM_MINUTE: i = 10; break;
527527
case SYM_SECOND: i = 11; break;
528+
case SYM_TIMEZONE: i = 12; break;
528529
default: return PE_BAD_SELECT;
529530
}
530531
}
@@ -565,7 +566,8 @@
565566
*val = *data;
566567
VAL_SET(val, REB_TIME);
567568
return PE_USE;
568-
case 4:
569+
case 4: // zone
570+
case 12: // timezone
569571
if (secs == NO_TIME) return PE_NONE;
570572
*val = *data;
571573
VAL_TIME(val) = (i64)tz * ZONE_MINS * MIN_SEC;
@@ -612,7 +614,10 @@
612614

613615
} else {
614616

615-
if (IS_INTEGER(val) || IS_DECIMAL(val)) n = Int32s(val, 0);
617+
if (IS_INTEGER(val) || IS_DECIMAL(val)) {
618+
// allow negative time zone
619+
n = (i == 4 || i == 12) ? Int32(val) : Int32s(val, 0);
620+
}
616621
else if (IS_NONE(val)) n = 0;
617622
else if (IS_TIME(val) && (i == 3 || i == 4));
618623
else if (IS_DATE(val) && (i == 3 || i == 5));
@@ -643,13 +648,18 @@
643648
secs = DEC_TO_SECS(VAL_DECIMAL(val));
644649
else return PE_BAD_SET_TYPE;
645650
break;
646-
case 4:
647-
// zone
651+
case 4: // zone
652+
case 12: // timezone
653+
tzp = tz;
648654
if (IS_TIME(val)) tz = (REBINT)(VAL_TIME(val) / (ZONE_MINS * MIN_SEC));
649655
else if (IS_DATE(val)) tz = VAL_ZONE(val);
650656
else tz = n * (60 / ZONE_MINS);
651-
if (tz > MAX_ZONE || tz < -MAX_ZONE) return PE_BAD_RANGE;
657+
if (i == 4 && (tz > MAX_ZONE || tz < -MAX_ZONE)) return PE_BAD_RANGE;
652658
if (secs == NO_TIME) secs = 0;
659+
if (i == 12) {
660+
//Adjust_Date_Zone(val, FALSE);
661+
secs += ((i64)(tz - tzp) * ((i64)ZONE_SECS * SEC_SEC));
662+
}
653663
break;
654664
case 5:
655665
// date

src/tests/units/date-test.r3

+17
Original file line numberDiff line numberDiff line change
@@ -91,5 +91,22 @@ Rebol [
9191

9292
===end-group===
9393

94+
===start-group=== "DATE/TIMEZONE"
95+
--test-- "set timezone"
96+
;@@ https://github.com/rebol/rebol-issues/issues/2370
97+
d: 1-Jan-2000
98+
d/zone: 2
99+
--assert "1-Jan-2000/0:00+2:00" = mold d
100+
d/timezone: 2
101+
--assert "1-Jan-2000/0:00+2:00" = mold d
102+
d/timezone: 4
103+
--assert "1-Jan-2000/2:00+4:00" = mold d
104+
d/timezone: -7
105+
--assert "31-Dec-1999/15:00-7:00" = mold d
106+
d/timezone: -70
107+
--assert "29-Dec-1999/0:00-6:00" = mold d
108+
109+
===end-group===
110+
94111

95112
~~~end-file~~~

0 commit comments

Comments
 (0)