Пример #1
0
time64_t timestamp64(time_t (*func)(struct tm*), struct tm64* tm64) {
  time64_t time;
  struct tm tm;
  memset(&tm, 0, sizeof(tm));

  /* If this succeeds it fits in a standard struct tm */
  if(tm64_to_tm(tm64, &tm) == 0) {
    time = timestamp64_mktime(func, &tm);
    /*
     * This still would fail for 1969-12-31 23:59:59 GMT, but
     * the fallback code will properly handle that case anyway.
     */
    if(time != -1) {
      /* Copy back updated information */
      tm_to_tm64(&tm, tm64);
      return time;
    }
  }

  /*
   * Convert the struct to a year that is day compatible with
   * the current day.
   */

  int64_t year = tm64->tm_year;

  if(year < 1902) {
    /* For years below the 32 bit size time_t value we need to use
    * the lower comparable years */
    int day = day_of_week(year, tm64->tm_mon + 1, tm64->tm_mday);
    if(tm64->tm_mon == 2 && leap_year(year)) {
      tm.tm_year = lower_leap_month_table[day] - 1900;
    } else {
      tm.tm_year = lower_common_month_table[tm.tm_mon][day] - 1900;
    }
  } else if(year > 2037) {
    /* For years above the 32 bit size time_t value we need to use
     * the lower comparable years */
    int day = day_of_week(year, tm64->tm_mon + 1, tm64->tm_mday);
    if(tm64->tm_mon == 2 && leap_year(year)) {
      tm.tm_year = higher_leap_month_table[day] - 1900;
    } else {
      tm.tm_year = higher_common_month_table[tm.tm_mon][day] - 1900;
    }
  }

  time = timestamp64_mktime(func, &tm);
  tm_to_tm64(&tm, tm64);

  if(year != tm64->tm_year) {
    /* Correct for the changed year to do the mktime computation */
    time += year_diff_to_seconds(tm64->tm_year, year, day_before_leap(tm64));
  }

  tm64->tm_year = year;
  return time;
}
Пример #2
0
time64_t timestamp64(time_t (*func)(struct tm*), struct tm64* tm64) {

  struct tm tm;
  memset(&tm, 0, sizeof(tm));

  /* If this succeeds it fits in a standard struct tm */
  if(tm64_to_tm(tm64, &tm) == 0) {
    time64_t time = (time64_t)func(&tm);
    /*
     * This still would fail for 1969-12-31 23:59:59 GMT, but
     * the fallback code will properly handle that case anyway.
     */
    if(time != -1) {
      /* Copy back updated information */
      tm_to_tm64(&tm, tm64);
      return time;
    }
  }

  /*
   * Convert the struct to a year that is day compatible with
   * the current day.
   */

  int64_t year = tm64->tm_year;

  if(year < 1902) {
    /* For years below the 32 bit size time_t value we need to use
    * the lower comparable years */
    int day = day_of_week(year, tm64->tm_mon + 1, tm64->tm_mday);
    if(tm64->tm_mon == 2 && leap_year(year)) {
      tm.tm_year = lower_leap_month_table[day] - 1900;
    } else {
      tm.tm_year = lower_common_month_table[tm.tm_mon][day] - 1900;
    }
  } else if(year > 2037) {
    /* For years above the 32 bit size time_t value we need to use
     * the lower comparable years */
    int day = day_of_week(year, tm64->tm_mon + 1, tm64->tm_mday);
    if(tm64->tm_mon == 2 && leap_year(year)) {
      tm.tm_year = higher_leap_month_table[day] - 1900;
    } else {
      tm.tm_year = higher_common_month_table[tm.tm_mon][day] - 1900;
    }
  }

  time64_t time = (time64_t) func(&tm);
  if(time == -1 && errno == EINVAL) {
    // retry one time because of perhaps DST change. This invalid
    // time due to DST change only happens if time moves forward,
    // so we know we start off with DST not active.
    // This happens at least on NetBSD.
    tm.tm_isdst = 0;
    time = (time64_t) func(&tm);
  }

  tm_to_tm64(&tm, tm64);

  if(year != tm64->tm_year) {
    /* Correct for the changed year to do the mktime computation */
    time += year_diff_to_seconds(tm64->tm_year, year, day_before_leap(tm64));
  }

  tm64->tm_year = year;
  return time;
}