TimeADT time_in(char *str) { int32_t typmod = 0; TimeADT result; fsec_t fsec; struct tm tt, *tm = &tt; int tz; int nf; int dterr; char workbuf[MAXDATELEN + 1]; char *field[MAXDATEFIELDS]; int dtype; int ftype[MAXDATEFIELDS]; dterr = ParseDateTime(str, workbuf, sizeof(workbuf), field, ftype, MAXDATEFIELDS, &nf); if (dterr == 0) dterr = DecodeTimeOnly(field, ftype, nf, &dtype, tm, &fsec, &tz); if (dterr != 0) DateTimeParseError(dterr, str, "time"); tm2time(tm, fsec, &result); AdjustTimeForTypmod(&result, typmod); return result; }
time_t my_mktime(struct tm *tp) { time_t maclocal; maclocal = tm2time(tp); maclocal -= GMTDelta(); return maclocal; }
int str2time_t (const char *str, time_t *t) { const char *p; struct tm tm, tm2; memset (&tm, 0, sizeof (tm)); memset (&tm2, 0, sizeof (tm2)); while(isspace((unsigned char)*str)) str++; if (str[0] == '+') { str++; *t = parse_time(str, "month"); if (*t < 0) return -1; *t += time(NULL); return 0; } if(strcasecmp(str, "never") == 0) { *t = 0; return 0; } if(strcasecmp(str, "now") == 0) { *t = time(NULL); return 0; } p = strptime (str, "%Y-%m-%d", &tm); if (p == NULL) return -1; while(isspace((unsigned char)*p)) p++; /* XXX this is really a bit optimistic, we should really complain if there was a problem parsing the time */ if(p[0] != '\0' && strptime (p, "%H:%M:%S", &tm2) != NULL) { tm.tm_hour = tm2.tm_hour; tm.tm_min = tm2.tm_min; tm.tm_sec = tm2.tm_sec; } else { /* Do it on the end of the day */ tm.tm_hour = 23; tm.tm_min = 59; tm.tm_sec = 59; } *t = tm2time (tm, 0); return 0; }
/* Check *PT and convert it to time_t. If it is incompletely specified, use DEFAULT_TIME to fill it out. Use localtime if PT->zone is the special value TM_LOCAL_ZONE. Yield -1 on failure. ISO 8601 day-of-year and week numbers are not yet supported. */ static time_t maketime (struct partime const *pt, time_t default_time) { int localzone, wday, year; struct tm tm; struct tm *tm0 = 0; time_t r; int use_ordinal_day; tm0 = 0; /* Keep gcc -Wall happy. */ localzone = pt->zone == TM_LOCAL_ZONE; tm = pt->tm; year = tm.tm_year; wday = tm.tm_wday; use_ordinal_day = (!TM_DEFINED (tm.tm_mday) && TM_DEFINED (wday) && TM_DEFINED (pt->wday_ordinal)); if (use_ordinal_day || TM_DEFINED (pt->ymodulus) || !TM_DEFINED (year)) { /* Get tm corresponding to default time. */ tm0 = time2tm (default_time, localzone); if (!localzone) adjzone (tm0, pt->zone); } if (use_ordinal_day) tm.tm_mday = (tm0->tm_mday + ((wday - tm0->tm_wday + 7) % 7 + 7 * (pt->wday_ordinal - (pt->wday_ordinal != 0)))); if (TM_DEFINED (pt->ymodulus)) { /* Yield a year closest to the default that has the given modulus. */ int year0 = tm0->tm_year + TM_YEAR_ORIGIN; int y0 = MOD (year0, pt->ymodulus); int d = 2 * (year - y0); year += (((year0 - y0) / pt->ymodulus + (pt->ymodulus < d ? -1 : d < -pt->ymodulus)) * pt->ymodulus); } else if (!TM_DEFINED (year)) { /* Set default year, month, day from current time. */ year = tm0->tm_year + TM_YEAR_ORIGIN; if (!TM_DEFINED (tm.tm_mon)) { tm.tm_mon = tm0->tm_mon; if (!TM_DEFINED (tm.tm_mday)) tm.tm_mday = tm0->tm_mday; } } /* Set remaining default fields to be their minimum values. */ if (!TM_DEFINED (tm.tm_mon)) tm.tm_mon = 0; if (!TM_DEFINED (tm.tm_mday)) tm.tm_mday = 1; if (!TM_DEFINED (tm.tm_hour)) tm.tm_hour = 0; if (!TM_DEFINED (tm.tm_min)) tm.tm_min = 0; if (!TM_DEFINED (tm.tm_sec)) tm.tm_sec = 0; tm.tm_year = year - TM_YEAR_ORIGIN; if ((year < tm.tm_year) != (TM_YEAR_ORIGIN < 0)) return -1; if (!localzone) { adjzone (&tm, -pt->zone); wday = tm.tm_wday; } /* Convert and fill in the rest of the tm. */ r = tm2time (&tm, localzone); if (r == -1) return r; /* Check weekday. */ if (TM_DEFINED (wday) && wday != tm.tm_wday) return -1; /* Add relative time, except for seconds. We handle seconds separately, at the end, so that leap seconds are handled properly. */ if (pt->tmr.tm_year | pt->tmr.tm_mon | pt->tmr.tm_mday | pt->tmr.tm_hour | pt->tmr.tm_min) { int years = tm.tm_year + pt->tmr.tm_year; int mons = tm.tm_mon + pt->tmr.tm_mon; int mdays = tm.tm_mday + pt->tmr.tm_mday; int hours = tm.tm_hour + pt->tmr.tm_hour; int mins = tm.tm_min + pt->tmr.tm_min; int carried_hours = DIV (mins, 60); int hours1 = hours + carried_hours; int carried_days = DIV (hours1, 24); int mdays1 = mdays + carried_days; int mon0 = MOD (mons, 12); int carried_years0 = DIV (mons, 12); int year0 = years + carried_years0; int yday0 = (month_yday[mon0] - (mon0 < 2 || !isleap (year0 + TM_YEAR_ORIGIN))); int yday1 = yday0 + mdays1; int carried_years1 = DIV (yday1, Y400_DAYS) * 400; int year1 = year0 + carried_years1; int yday2 = MOD (yday1, Y400_DAYS); int leap; if (overflow_sum_sign (tm.tm_year, pt->tmr.tm_year, years) | overflow_sum_sign (tm.tm_mon, pt->tmr.tm_mon, mons) | overflow_sum_sign (tm.tm_mday, pt->tmr.tm_mday, mdays) | overflow_sum_sign (tm.tm_hour, pt->tmr.tm_hour, hours) | overflow_sum_sign (tm.tm_min, pt->tmr.tm_min, mins) | overflow_sum_sign (hours, carried_hours, hours1) | overflow_sum_sign (mdays, carried_days, mdays1) | overflow_sum_sign (years, carried_years0, year0) | overflow_sum_sign (yday0, mdays1, yday1) | overflow_sum_sign (year0, carried_years1, year1)) return -1; for (;;) { int days_per_year = 365 + (leap = isleap (year1 + TM_YEAR_ORIGIN)); if (yday2 < days_per_year) break; yday2 -= days_per_year; year1++; } tm.tm_year = year1; { int mon; for (mon = 11; (tm.tm_mday = (yday2 - month_yday[mon] + (mon < 2 || !leap))) <= 0; mon--) continue; tm.tm_mon = mon; } tm.tm_hour = MOD (hours1, 24); tm.tm_min = MOD (mins, 60); r = tm2time (&tm, localzone); if (r == -1) return r; } /* Add the seconds' part of relative time. */ { time_t rs = r + pt->tmr.tm_sec; if ((pt->tmr.tm_sec < 0) != (rs < r)) return -1; return rs; } }