Skip to content

Commit d797a93

Browse files
committed
FEAT: support to date! integer! and to integer! date! using unixtime as an integer value
resolves: Oldes/Rebol-issues#2456
1 parent 85de1db commit d797a93

File tree

3 files changed

+39
-12
lines changed

3 files changed

+39
-12
lines changed

src/core/t-date.c

+36
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,8 @@
3232

3333
#include "sys-core.h"
3434

35+
static const REBI64 DAYS_OF_JAN_1ST_1970 = 719468; // number of days for 1st January 1970
36+
3537

3638
/***********************************************************************
3739
**
@@ -309,6 +311,36 @@
309311
}
310312

311313

314+
/***********************************************************************
315+
**
316+
*/ REBCNT Date_To_Timestamp(REBVAL *date)
317+
/*
318+
** Return the unix time stamp for a specific date value.
319+
**
320+
***********************************************************************/
321+
{
322+
REBDAT d = VAL_DATE(date);
323+
REBI64 epoch = (Days_Of_Date(d.date.day, d.date.month, d.date.year) - DAYS_OF_JAN_1ST_1970) * SECS_IN_DAY;
324+
return epoch + ((VAL_TIME(date) + 500000000) / SEC_SEC);
325+
}
326+
327+
/***********************************************************************
328+
**
329+
*/ void Timestamp_To_Date(REBVAL *date, REBI64 epoch)
330+
/*
331+
** Set Rebol date from the unix time stamp epoch.
332+
**
333+
***********************************************************************/
334+
{
335+
REBI64 days = (epoch / SECS_IN_DAY) + DAYS_OF_JAN_1ST_1970;
336+
337+
VAL_SET(date, REB_DATE);
338+
Date_Of_Days(days, &VAL_DATE(date));
339+
VAL_TIME(date) = TIME_SEC((epoch % 86400));
340+
VAL_ZONE(date) = 0;
341+
}
342+
343+
312344
/***********************************************************************
313345
**
314346
*/ void Normalize_Time(REBI64 *sp, REBINT *dp)
@@ -883,6 +915,10 @@
883915
return R_RET;
884916
}
885917
}
918+
else if (IS_INTEGER(arg)) {
919+
Timestamp_To_Date(D_RET, VAL_INT64(arg));
920+
return R_RET;
921+
}
886922
// else if (IS_NONE(arg)) {
887923
// secs = nsec = day = month = year = tz = 0;
888924
// goto fixTime;

src/core/t-integer.c

+1
Original file line numberDiff line numberDiff line change
@@ -245,6 +245,7 @@
245245
else if (IS_CHAR(val))
246246
num = VAL_CHAR(val);
247247
// else if (IS_NONE(val)) num = 0;
248+
else if (IS_DATE(val)) num = Date_To_Timestamp(val);
248249
else if (IS_TIME (val)) num = SECS_IN(VAL_TIME(val));
249250
else goto is_bad;
250251
break;

src/mezz/codec-unixtime.reb

+2-12
Original file line numberDiff line numberDiff line change
@@ -26,12 +26,7 @@ register-codec [
2626
][
2727
if string? epoch [ epoch: debase epoch 16 ]
2828
if binary? epoch [ epoch: to integer! epoch ]
29-
days: to integer! tmp: epoch / 86400
30-
hours: to integer! time: (tmp - days) * 24
31-
minutes: to integer! tmp: (time - hours) * 60
32-
seconds: to integer! 0.5 + ((tmp - minutes) * 60)
33-
time: to time! ((((hours * 60) + minutes) * 60) + seconds)
34-
result: 1-Jan-1970 + days + time
29+
result: to date! epoch
3530
unless utc [
3631
result: result + now/zone
3732
result/zone: now/zone
@@ -44,12 +39,7 @@ register-codec [
4439
date [date!]
4540
/as type [word! datatype!] {one of: [string! binary! integer!]}
4641
][
47-
time: any [date/time 0:0:0]
48-
unix: ((date - 1-1-1970) * 86400)
49-
+ (time/hour * 3600)
50-
+ (time/minute * 60)
51-
+ time/second
52-
- to integer! (any [date/zone 0])
42+
unix: to integer! date
5343
if as [
5444
type: to word! type
5545
binary/write bin: #{} [ui32 :unix]

0 commit comments

Comments
 (0)