*/ REBINT PD_Date(REBPVS *pvs) /* ***********************************************************************/ { REBVAL *data = pvs->value; REBVAL *arg = pvs->select; REBVAL *val = pvs->setval; REBINT i; REBINT n; REBI64 secs; REBINT tz; REBDAT date; REBCNT day, month, year; REBINT num; REBVAL dat; REB_TIMEF time; // !zone! - adjust date by zone (unless /utc given) if (IS_WORD(arg)) { //!!! change this to an array!? switch (VAL_WORD_CANON(arg)) { case SYM_YEAR: i = 0; break; case SYM_MONTH: i = 1; break; case SYM_DAY: i = 2; break; case SYM_TIME: i = 3; break; case SYM_ZONE: i = 4; break; case SYM_DATE: i = 5; break; case SYM_WEEKDAY: i = 6; break; case SYM_JULIAN: case SYM_YEARDAY: i = 7; break; case SYM_UTC: i = 8; break; case SYM_HOUR: i = 9; break; case SYM_MINUTE: i = 10; break; case SYM_SECOND: i = 11; break; default: return PE_BAD_SELECT; } } else if (IS_INTEGER(arg)) { i = Int32(arg) - 1; if (i < 0 || i > 8) return PE_BAD_SELECT; } else return PE_BAD_SELECT; if (IS_DATE(data)) { dat = *data; // recode! data = &dat; if (i != 8) Adjust_Date_Zone(data, FALSE); // adjust for timezone date = VAL_DATE(data); day = VAL_DAY(data) - 1; month = VAL_MONTH(data) - 1; year = VAL_YEAR(data); secs = VAL_TIME(data); tz = VAL_ZONE(data); if (i > 8) Split_Time(secs, &time); } else { Trap_Arg_DEAD_END(data); // this should never happen } if (val == 0) { val = pvs->store; switch(i) { case 0: num = year; break; case 1: num = month + 1; break; case 2: num = day + 1; break; case 3: if (secs == NO_TIME) return PE_NONE; *val = *data; VAL_SET(val, REB_TIME); return PE_USE; case 4: if (secs == NO_TIME) return PE_NONE; *val = *data; VAL_TIME(val) = (i64)tz * ZONE_MINS * MIN_SEC; VAL_SET(val, REB_TIME); return PE_USE; case 5: // date *val = *data; VAL_TIME(val) = NO_TIME; VAL_ZONE(val) = 0; return PE_USE; case 6: // weekday num = Week_Day(date); break; case 7: // yearday num = (REBINT)Julian_Date(date); break; case 8: // utc *val = *data; VAL_ZONE(val) = 0; return PE_USE; case 9: num = time.h; break; case 10: num = time.m; break; case 11: if (time.n == 0) num = time.s; else { SET_DECIMAL(val, (REBDEC)time.s + (time.n * NANO)); return PE_USE; } break; default: return PE_NONE; } SET_INTEGER(val, num); return PE_USE; } else { if (IS_INTEGER(val) || IS_DECIMAL(val)) n = Int32s(val, 0); else if (IS_NONE(val)) n = 0; else if (IS_TIME(val) && (i == 3 || i == 4)); else if (IS_DATE(val) && (i == 3 || i == 5)); else return PE_BAD_SET_TYPE; switch(i) { case 0: year = n; break; case 1: month = n - 1; break; case 2: day = n - 1; break; case 3: // time if (IS_NONE(val)) { secs = NO_TIME; tz = 0; break; } else if (IS_TIME(val) || IS_DATE(val)) secs = VAL_TIME(val); else if (IS_INTEGER(val)) secs = n * SEC_SEC; else if (IS_DECIMAL(val)) secs = DEC_TO_SECS(VAL_DECIMAL(val)); else return PE_BAD_SET_TYPE; break; case 4: // zone if (IS_TIME(val)) tz = (REBINT)(VAL_TIME(val) / (ZONE_MINS * MIN_SEC)); else if (IS_DATE(val)) tz = VAL_ZONE(val); else tz = n * (60 / ZONE_MINS); if (tz > MAX_ZONE || tz < -MAX_ZONE) return PE_BAD_RANGE; break; case 5: // date if (!IS_DATE(val)) return PE_BAD_SET_TYPE; date = VAL_DATE(val); goto setDate; case 9: time.h = n; secs = Join_Time(&time, FALSE); break; case 10: time.m = n; secs = Join_Time(&time, FALSE); break; case 11: if (IS_INTEGER(val)) { time.s = n; time.n = 0; } else { //if (f < 0.0) Trap_Range_DEAD_END(val); time.s = (REBINT)VAL_DECIMAL(val); time.n = (REBINT)((VAL_DECIMAL(val) - time.s) * SEC_SEC); } secs = Join_Time(&time, FALSE); break; default: return PE_BAD_SET; } Normalize_Time(&secs, &day); date = Normalize_Date(day, month, year, tz); setDate: data = pvs->value; VAL_SET(data, REB_DATE); VAL_DATE(data) = date; VAL_TIME(data) = secs; Adjust_Date_Zone(data, TRUE); return PE_USE; } }
*/ REBI64 Make_Time(REBVAL *val) /* ** Returns NO_TIME if error. ** ***********************************************************************/ { REBI64 secs = 0; if (IS_TIME(val)) { secs = VAL_TIME(val); } else if (IS_STRING(val)) { REBYTE *bp; REBCNT len; bp = Qualify_String(val, 30, &len, FALSE); // can trap, ret diff str if (!Scan_Time(bp, len, val)) goto no_time; secs = VAL_TIME(val); } else if (IS_INTEGER(val)) { if (VAL_INT64(val) < -MAX_SECONDS || VAL_INT64(val) > MAX_SECONDS) Trap_Range_DEAD_END(val); secs = VAL_INT64(val) * SEC_SEC; } else if (IS_DECIMAL(val)) { if (VAL_DECIMAL(val) < (REBDEC)(-MAX_SECONDS) || VAL_DECIMAL(val) > (REBDEC)MAX_SECONDS) Trap_Range_DEAD_END(val); secs = DEC_TO_SECS(VAL_DECIMAL(val)); } else if (ANY_BLOCK(val) && VAL_BLK_LEN(val) <= 3) { REBFLG neg = FALSE; REBI64 i; val = VAL_BLK_DATA(val); if (!IS_INTEGER(val)) goto no_time; i = Int32(val); if (i < 0) i = -i, neg = TRUE; secs = i * 3600; if (secs > MAX_SECONDS) goto no_time; if (NOT_END(++val)) { if (!IS_INTEGER(val)) goto no_time; if ((i = Int32(val)) < 0) goto no_time; secs += i * 60; if (secs > MAX_SECONDS) goto no_time; if (NOT_END(++val)) { if (IS_INTEGER(val)) { if ((i = Int32(val)) < 0) goto no_time; secs += i; if (secs > MAX_SECONDS) goto no_time; } else if (IS_DECIMAL(val)) { if (secs + (REBI64)VAL_DECIMAL(val) + 1 > MAX_SECONDS) goto no_time; // added in below } else goto no_time; } } secs *= SEC_SEC; if (IS_DECIMAL(val)) secs += DEC_TO_SECS(VAL_DECIMAL(val)); if (neg) secs = -secs; } else no_time: return NO_TIME; return secs; }
// // Make_Time: C // // Returns NO_TIME if error. // REBI64 Make_Time(REBVAL *val) { REBI64 secs = 0; if (IS_TIME(val)) { secs = VAL_TIME(val); } else if (IS_STRING(val)) { REBYTE *bp; REBCNT len; bp = Temp_Byte_Chars_May_Fail(val, MAX_SCAN_TIME, &len, FALSE); if (!Scan_Time(bp, len, val)) goto no_time; secs = VAL_TIME(val); } else if (IS_INTEGER(val)) { if (VAL_INT64(val) < -MAX_SECONDS || VAL_INT64(val) > MAX_SECONDS) fail (Error_Out_Of_Range(val)); secs = VAL_INT64(val) * SEC_SEC; } else if (IS_DECIMAL(val)) { if (VAL_DECIMAL(val) < (REBDEC)(-MAX_SECONDS) || VAL_DECIMAL(val) > (REBDEC)MAX_SECONDS) fail (Error_Out_Of_Range(val)); secs = DEC_TO_SECS(VAL_DECIMAL(val)); } else if (ANY_ARRAY(val) && VAL_BLK_LEN(val) <= 3) { REBFLG neg = FALSE; REBI64 i; val = VAL_BLK_DATA(val); if (!IS_INTEGER(val)) goto no_time; i = Int32(val); if (i < 0) i = -i, neg = TRUE; secs = i * 3600; if (secs > MAX_SECONDS) goto no_time; if (NOT_END(++val)) { if (!IS_INTEGER(val)) goto no_time; if ((i = Int32(val)) < 0) goto no_time; secs += i * 60; if (secs > MAX_SECONDS) goto no_time; if (NOT_END(++val)) { if (IS_INTEGER(val)) { if ((i = Int32(val)) < 0) goto no_time; secs += i; if (secs > MAX_SECONDS) goto no_time; } else if (IS_DECIMAL(val)) { if (secs + (REBI64)VAL_DECIMAL(val) + 1 > MAX_SECONDS) goto no_time; // added in below } else goto no_time; } } secs *= SEC_SEC; if (IS_DECIMAL(val)) secs += DEC_TO_SECS(VAL_DECIMAL(val)); if (neg) secs = -secs; } else no_time: return NO_TIME; return secs; }