コード例 #1
0
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;
}
コード例 #2
0
int
dt_print_to_buffer (char *buf, caddr_t arg, int mode)
{
  int res = 0;
  int arg_dt_type = DT_DT_TYPE (arg);
  TIMESTAMP_STRUCT ts;
  if (0 == ((DT_PRINT_MODE_YMD | DT_PRINT_MODE_HMS) & mode))
    mode |= ((DT_TYPE_TIME == arg_dt_type) ? DT_PRINT_MODE_HMS :
      ((DT_TYPE_DATE == arg_dt_type) ? DT_PRINT_MODE_YMD : (DT_PRINT_MODE_YMD | DT_PRINT_MODE_HMS)) );
  if ((DT_PRINT_MODE_YMD & mode) && (DT_TYPE_TIME == arg_dt_type))
    sqlr_new_error ("22023", "SR592", "Bit 4 in print mode requires DATE or DATETIME argument, not TIME");
  if ((DT_PRINT_MODE_HMS & mode) && (DT_TYPE_DATE == arg_dt_type))
    sqlr_new_error ("22023", "SR593", "Bit 2 in print mode requires TIME or DATETIME argument, not DATE");
  dt_to_GMTimestamp_struct (arg, &ts);
  if (DT_PRINT_MODE_YMD & mode)
    res += sprintf (buf, "%04d-%02d-%02d", ts.year, ts.month, ts.day);
  if ((DT_PRINT_MODE_YMD & mode) && (DT_PRINT_MODE_HMS & mode))
    buf[res++] = ((DT_PRINT_MODE_XML & mode) ? 'T' : ' ');
  if (DT_PRINT_MODE_HMS & mode)
    {
      res += sprintf (buf + res, "%02d:%02d:%02d", ts.hour, ts.minute, ts.second);
      if (ts.fraction)
        {
          if (ts.fraction % 1000)
            res += sprintf (buf + res, ".%09d", (int)ts.fraction);
          else if (ts.fraction % 1000000)
            res += sprintf (buf + res, ".%06d", (int)(ts.fraction / 1000));
          else
            res += sprintf (buf + res, ".%03d", (int)(ts.fraction / 1000000));
        }
    }
  if (DT_PRINT_MODE_XML & mode)
    {
      strcpy (buf + res, "Z");
      return res + 1;
    }
  else
    {
      strcpy (buf + res, " GMT");
      return res + 4;
    }
}
コード例 #3
0
caddr_t
arithm_dt_add_num (ccaddr_t box1, ccaddr_t box2, int subtraction, caddr_t *err_ret)
{
  int dt_type = DT_DT_TYPE (box1);
  dtp_t dtp2 = DV_TYPE_OF (box2);
  boxint whole_seconds = 0;
  boxint nanoseconds = 0;
  TIMESTAMP_STRUCT ts;
  caddr_t res;
  switch (dtp2)
    {
    case DV_LONG_INT:
      whole_seconds = unbox (box2);
      break;
    case DV_DOUBLE_FLOAT:
      {
        double n = unbox_double (box2);
        double rest;
        whole_seconds = (n >= 0.0) ? floor(n + 0.5) : ceil(n - 0.5);
        rest = n - whole_seconds;
        if (abs(rest/n) > (3 * DBL_EPSILON))
          nanoseconds = (n - whole_seconds) * 1000000000L;
        break;
      }
    case DV_NUMERIC:
      {
        numeric_t n = (numeric_t)box2;
        if (NUMERIC_STS_SUCCESS != numeric_to_int64 (n, &whole_seconds))
          {
            err_ret[0] = srv_make_new_error ("22003", "SR087", "Wrong arguments for datetime arithmetic: decimal is out of range.");
            return NULL;
          }
        if (n->n_scale > 0)
          {
            char *nptr = n->n_value + n->n_len;
            int ctr;
            int mult = 1;
            for (ctr = 9; ctr > n->n_scale; ctr--) mult *= 10;
            while (ctr--)
              {
                nanoseconds += mult * nptr[ctr];
                mult *= 10;
              }
          }
        break;
      }
    default:
      return NULL;
    }
  DT_AUDIT_FIELDS (dt);
  dt_to_GMTimestamp_struct (box1, &ts);
  ts_add (&ts, (subtraction ? -whole_seconds : whole_seconds), "second");
  if (nanoseconds)
    ts_add (&ts, (subtraction ? -nanoseconds : nanoseconds), "nanosecond");
  res = dk_alloc_box (DT_LENGTH, DV_DATETIME);
  GMTimestamp_struct_to_dt (&ts, res);
  DT_SET_TZ (res, DT_TZ (box1));
  if ((DT_TYPE_DATE == dt_type) && (0 == (((whole_seconds * 1000000000L) + nanoseconds) % (SPERDAY * 1000000000L))))
    DT_SET_DT_TYPE (res, dt_type);
  DT_AUDIT_FIELDS (dt);
  return res;
}