static caddr_t bif_extract (caddr_t * qst, caddr_t * err_ret, state_slot_t ** args) { caddr_t unit = bif_string_arg (qst, args, 0, "extract"); caddr_t dt = bif_date_arg (qst, args, 1, "extract"); TIMESTAMP_STRUCT ts; dt_to_timestamp_struct (dt, &ts); if (!stricmp (unit, "SECOND")) return box_num (ts.second); else if (!stricmp (unit, "MINUTE")) return box_num (ts.minute); else if (!stricmp (unit, "HOUR")) return box_num (ts.hour); else if (!stricmp (unit, "DAY")) return box_num (ts.day); else if (!stricmp (unit, "MONTH")) return box_num (ts.month); else if (!stricmp (unit, "YEAR")) return box_num (ts.year); else { *err_ret = srv_make_new_error ("22015", "DT005", "Bad interval in extract."); return NULL; } }
caddr_t bif_nasa_tjd_number (caddr_t * qst, caddr_t * err_ret, state_slot_t ** args) { caddr_t arg = bif_date_arg (qst, args, 0, "nasa_tjd_number"); long n = DT_DAY (arg) - NASA_TJD_OFFSET; return box_num (n); }
caddr_t bif_nasa_tjd_fraction (caddr_t * qst, caddr_t * err_ret, state_slot_t ** args) { caddr_t arg = bif_date_arg (qst, args, 0, "nasa_tjd_fraction"); double f = (((DT_HOUR (arg) * (boxint)60 + DT_MINUTE (arg)) * (boxint)60 + DT_SECOND (arg)) * (boxint)1000000 + DT_FRACTION (arg)) / (60*60*24*1000000.0); return box_double (f); }
caddr_t bif_dayofweek (caddr_t * qst, caddr_t * err_ret, state_slot_t ** args) { caddr_t arg = bif_date_arg (qst, args, 0, "dayofweek"); return box_num (dayofweek (arg)); }
caddr_t bif_dateadd (caddr_t * qst, caddr_t * err_ret, state_slot_t ** args) { caddr_t res; caddr_t part = bif_string_arg (qst, args, 0, "dateadd"); boxint n = bif_long_arg (qst, args, 1, "dateadd"); caddr_t dt = bif_date_arg (qst, args, 2, "dateadd"); TIMESTAMP_STRUCT ts; int dt_type = DT_DT_TYPE (dt); int year_or_month_tz_tweak = (((!strcmp ("year", part)) || (!strcmp ("month", part))) ? DT_TZ (dt) : 0); DT_AUDIT_FIELDS (dt); dt_to_GMTimestamp_struct (dt, &ts); if (year_or_month_tz_tweak) ts_add (&ts, year_or_month_tz_tweak, "minute"); ts_add (&ts, n, part); if (year_or_month_tz_tweak) ts_add (&ts, -year_or_month_tz_tweak, "minute"); res = dk_alloc_box (DT_LENGTH, DV_DATETIME); GMTimestamp_struct_to_dt (&ts, res); DT_SET_TZ (res, DT_TZ (dt)); if (DT_TYPE_DATE == dt_type && (0 == stricmp (part, "year") || 0 == stricmp (part, "month") || 0 == stricmp (part, "day"))) DT_SET_DT_TYPE (res, dt_type); DT_AUDIT_FIELDS (dt); return res; }
caddr_t bif_date_string (caddr_t * qst, caddr_t * err_ret, state_slot_t ** args) { char temp[100]; caddr_t arg = bif_date_arg (qst, args, 0, "datestring"); dt_to_string (arg, temp, sizeof (temp)); return (box_dv_short_string (temp)); }
caddr_t bif_date_diff (caddr_t * qst, caddr_t * err_ret, state_slot_t ** args) { caddr_t unit = bif_string_arg (qst, args, 0, "datediff"); caddr_t dt1 = bif_date_arg (qst, args, 1, "datediff"); caddr_t dt2 = bif_date_arg (qst, args, 2, "datediff"); boxint s1 = (boxint)DT_DAY (dt1) * 24 * 60 * 60 + (boxint)DT_HOUR (dt1) * 60 * 60 + (boxint)DT_MINUTE (dt1) * 60 + DT_SECOND (dt1); boxint s2 = (boxint)DT_DAY (dt2) * 24 * 60 * 60 + (boxint)DT_HOUR (dt2) * 60 * 60 + (boxint)DT_MINUTE (dt2) * 60 + DT_SECOND (dt2); int frac1, frac2; int diffyear, diffmonth; if (0 == stricmp (unit, "day")) return box_num ((boxint)DT_DAY (dt2) - (boxint)DT_DAY (dt1)); if (0 == stricmp (unit, "hour")) return box_num ((s2 - s1) / (60 * 60)); if (0 == stricmp (unit, "minute")) return box_num ((s2 - s1) / 60); if (0 == stricmp (unit, "second")) return box_num (s2 - s1); diffyear = !stricmp (unit, "year"); diffmonth = (diffyear ? 0 : !stricmp (unit, "month")); if (diffyear || diffmonth) { TIMESTAMP_STRUCT ts1; TIMESTAMP_STRUCT ts2; int tz_tweak = DT_TZ (dt1); dt_to_GMTimestamp_struct (dt2, &ts2); dt_to_GMTimestamp_struct (dt1, &ts1); ts_add (&ts1, tz_tweak, "minute"); ts_add (&ts2, tz_tweak, "minute"); if (diffyear) return box_num ((boxint)ts2.year - (boxint)ts1.year); if (diffmonth) return box_num ((boxint)(ts2.year * 12 + ts2.month) - (boxint)(ts1.year * 12 + ts1.month)); } frac1 = DT_FRACTION(dt1); frac2 = DT_FRACTION(dt2); if (0 == stricmp (unit, "millisecond")) return box_num ((s2 - s1) * (boxint)1000 + (frac2 / 1000000 - frac1 / 1000000)); if (0 == stricmp (unit, "microsecond")) return box_num ((s2 - s1) * (boxint)1000000 + (frac2 / 1000 - frac1 / 1000)); if (0 == stricmp (unit, "nanosecond")) return box_num ((s2 - s1) * (boxint)1000000000 + (frac2 - frac1)); sqlr_new_error ("22023", "DT002", "Bad unit in datediff: %s.", unit); return NULL; }
caddr_t bif_dt_set_tz (caddr_t * qst, caddr_t * err_ret, state_slot_t ** args) { caddr_t arg = bif_date_arg (qst, args, 0, "dt_set_tz"); long tz = (long) bif_long_arg (qst, args, 1, "dt_set_tz"); caddr_t res = box_copy (arg); DT_SET_TZ (res, tz); return res; }
caddr_t bif_date_string_GMT (caddr_t * qst, caddr_t * err_ret, state_slot_t ** args) { char temp[100]; caddr_t arg = bif_date_arg (qst, args, 0, "datestring"); char dt2[DT_LENGTH]; memcpy (dt2, arg, DT_LENGTH); DT_SET_TZ (dt2, 0); dt_to_string (dt2, temp, sizeof (temp)); return (box_dv_short_string (temp)); }
caddr_t bif_week (caddr_t * qst, caddr_t * err_ret, state_slot_t ** args) { caddr_t arg = bif_date_arg (qst, args, 0, "week"); TIMESTAMP_STRUCT ts; uint32 nowadays, new_year; dt_to_timestamp_struct (arg, &ts); nowadays = date2num (ts.year, ts.month, ts.day); new_year = date2num (ts.year, 1, 1); return (box_num ((nowadays - new_year) / 7 + 1)); }
caddr_t bif_timestampdiff (caddr_t * qst, caddr_t * err_ret, state_slot_t ** args) { ptrlong long_unit = bif_long_arg (qst, args, 0, "timestampdiff"); caddr_t dt1 = bif_date_arg (qst, args, 1, "timestampdiff"); caddr_t dt2 = bif_date_arg (qst, args, 2, "timestampdiff"); GMTIMESTAMP_STRUCT ts1, ts2; /* BELOW OVERFLOWS on 32 bit long. Numbers used for computing difference, * hence this works when difference below 2**21 = 34 years */ boxint s1 = (boxint)DT_DAY (dt1) * 24 * 60 * 60 + DT_HOUR (dt1) * 60 * 60 + DT_MINUTE (dt1) * 60 + DT_SECOND (dt1); boxint s2 = (boxint)DT_DAY (dt2) * 24 * 60 * 60 + DT_HOUR (dt2) * 60 * 60 + DT_MINUTE (dt2) * 60 + DT_SECOND (dt2); char *unit = interval_odbc_to_text (long_unit, "timestampdiff"); if (0 == stricmp (unit, "day")) return box_num ((boxint)DT_DAY (dt2) - (boxint)DT_DAY (dt1)); if (0 == stricmp (unit, "hour")) return box_num ((s2 - s1) / (60 * 60)); if (0 == stricmp (unit, "minute")) return box_num ((s2 - s1) / 60); if (0 == stricmp (unit, "second")) return box_num (s2 - s1); dt_to_GMTimestamp_struct (dt2, &ts2); dt_to_GMTimestamp_struct (dt1, &ts1); if (0 == stricmp (unit, "month")) return box_num ((boxint)(ts2.year * 12 + ts2.month) - (boxint)(ts1.year * 12 + ts1.month)); if (0 == stricmp (unit, "year")) return box_num ((boxint)ts2.year - (boxint)ts1.year); sqlr_new_error ("22015", "DT004", "Bad interval in timestampdiff: %s.", unit); return NULL; }
caddr_t bif_quarter (caddr_t * qst, caddr_t * err_ret, state_slot_t ** args) { caddr_t arg = bif_date_arg (qst, args, 0, "quarter"); TIMESTAMP_STRUCT ts; int quarter; dt_to_timestamp_struct (arg, &ts); if (ts.month <= 3) quarter = 1; else if (ts.month <= 6) quarter = 2; else if (ts.month <= 9) quarter = 3; else quarter = 4; return (box_num (quarter)); }
caddr_t bif_timestampadd (caddr_t * qst, caddr_t * err_ret, state_slot_t ** args) { caddr_t res; ptrlong part = bif_long_arg (qst, args, 0, "timestampadd"); int n = (int) bif_long_arg (qst, args, 1, "timestampadd"); caddr_t dt = bif_date_arg (qst, args, 2, "timestampadd"); int saved_tz = DT_TZ (dt); GMTIMESTAMP_STRUCT ts; dt_to_GMTimestamp_struct (dt, &ts); ts_add (&ts, n, interval_odbc_to_text (part, "timestampadd")); res = dk_alloc_box (DT_LENGTH, DV_DATETIME); GMTimestamp_struct_to_dt (&ts, res); DT_SET_TZ (res, saved_tz); return res; }
caddr_t bif_timezone (caddr_t * qst, caddr_t * err_ret, state_slot_t ** args) { caddr_t arg = bif_date_arg (qst, args, 0, "timezone"); return box_num (DT_TZ (arg)); }