Пример #1
0
int main(void)
{
    struct TM d;
    Time64_T time = 1202380093LL;

    d.tm_year = 90;

    while(d.tm_year < 800) {
        gmtime64_r(&time, &d);
        printf("%"PRId64" %d %d %d %d %d %"PRId64" %d %d %d\n",
                time,
                d.tm_sec,
                d.tm_min,
                d.tm_hour,
                d.tm_mday,
                d.tm_mon,
                (Year)d.tm_year,
                d.tm_wday,
                d.tm_yday,
                d.tm_isdst
        );
        
        time += 60 * 60 * 11 + 1;
    }
    return(0);
}
Пример #2
0
  struct tm64 Time::get_tm() {
    time64_t seconds = seconds_;
    struct tm64 tm = {0};

    if(Fixnum* off = try_as<Fixnum>(offset_)) {
      seconds += off->to_long_long();
      gmtime64_r(&seconds, &tm);
    } else if(CBOOL(is_gmt_)) {
      gmtime64_r(&seconds, &tm);
    } else {
      tzset();
      localtime64_r(&seconds, &tm);
    }

    return tm;
  }
Пример #3
0
DOMText* EppUtil::createTextNode( DOMDocument& doc, const time_t cal, bool dateOnly )
{
	char buf[128];
	struct tm tmp;

#if	   EPP_SUPPORT_UNSIGNED_TIME_T		/* { */

	long long t = (long long) ((unsigned int) cal);
	(void) gmtime64_r(&t, &tmp);

#else	/* EPP_SUPPORT_UNSIGNED_TIME_T	*/	/* } */

#if       defined(win32)      /* { */
	struct tm * p = gmtime(&cal);
	tmp = *p;
#else  /* defined(win32) */   /* } { */
	(void) gmtime_r(&cal, &tmp);
#endif /* defined(win32) */   /* } */

#endif	/* EPP_SUPPORT_UNSIGNED_TIME_T	*/	/* } */

	const char * fmt = dateOnly ? "%Y-%m-%d" : "%Y-%m-%dT%H:%M:%S.0Z";
	buf[0] = '\0';
	(void) strftime(buf, sizeof(buf), fmt, &tmp);

	return doc.createTextNode(XS(buf));
}
Пример #4
0
time64_t pivotal_timestamp ()
{
    time_t t_classic = time (NULL);
    time64_t ltime;
    struct tm mytime = *gmtime (&t_classic);
    gmtime64_r(&ltime, &mytime);
    return ltime;
}
Пример #5
0
/* Date stuff */
static PyObject* datetime_from_millis(long long millis) {
    int microseconds = (millis % 1000) * 1000;
    Time64_T seconds = millis / 1000;
    struct TM timeinfo;
    gmtime64_r(&seconds, &timeinfo);

    return PyDateTime_FromDateAndTime(timeinfo.tm_year + 1900,
                                      timeinfo.tm_mon + 1,
                                      timeinfo.tm_mday,
                                      timeinfo.tm_hour,
                                      timeinfo.tm_min,
                                      timeinfo.tm_sec,
                                      microseconds);
}
Пример #6
0
void DateHolder::load(){
    m_year=1970;
    m_month=1;
    m_day=1;
    const Time64_T  t= m_datetime/1000; // number of seconds since beginning of the Unix Epoch.
    /*
    TL;DR

    The gmttime in standard libray on windows platform cannot represent the date before Unix Epoch.
    http://msdn.microsoft.com/en-us/library/0z9czt0w(v=vs.100).aspx

    """
    Both the 32-bit and 64-bit versions of gmtime, mktime, mkgmtime, and localtime all use one tm structure per thread for the conversion.
    Each call to one of these functions destroys the result of any previous call.
    If timer represents a date before midnight, January 1, 1970, gmtime returns NULL.  There is no error return.

    _gmtime64, which uses the __time64_t structure, enables dates to be expressed up through 23:59:59, December 31, 3000, UTC,
    whereas _gmtime32 only represent dates through 03:14:07 January 19, 2038, UTC.
    Midnight, January 1, 1970, is the lower bound of the date range for both of these functions.

    gmtime is an inline function that evaluates to _gmtime64 and time_t is equivalent to __time64_t unless _USE_32BIT_TIME_T is defined.
    """

    An alternative could be boost date_time libraray.

    ```
    #include <boost/date_time/posix_time/posix_time.hpp>
    using namespace boost::posix_time;
    ptime pt = from_time_t(t);
    struct tm d = to_tm(pt);
    ```

    Howerver, boost date_time library still has year 2038 problem which is still not fixed.
    https://svn.boost.org/trac/boost/ticket/4543
    One reason is that the library converts the 64-bit`time_t t` into `seconds` type to get posix time.
    But boost uses `long` to represent `seconds`, which is 4 bytes on windows platform,
    http://msdn.microsoft.com/en-us/library/s3f49ktz.aspx

    We eventually choose the third-party MIT-licensed library written with ANSI C.
    https://github.com/schwern/y2038
    */
    struct TM d;
    gmtime64_r(&t,&d);
    m_year=1900 + static_cast<int32_t>(d.tm_year);
    m_month=d.tm_mon + 1;
    m_day=d.tm_mday;
}
Пример #7
0
void DateTimeHolder::load(){
    m_year=1970;
    m_month=1;
    m_day=1;
    m_hr=0;
    m_min=0;
    m_sec=0;
    m_msec=0;

    const Time64_T  t=m_datetime/1000; // number of seconds since beginning of the Unix Epoch.

    struct TM dt;
    gmtime64_r(&t,&dt);

    m_year=1900 + dt.tm_year;
    m_month=dt.tm_mon + 1;
    m_day=dt.tm_mday;
    m_hr=dt.tm_hour;
    m_min=dt.tm_min;
    m_sec=dt.tm_sec;
    m_msec=m_datetime%1000;

}
Пример #8
0
struct tm64* localtime64_r(const time64_t* time64, struct tm64* tm64) {
  if(*time64 >= LONG_MIN && *time64 <= LONG_MAX) {
    struct tm tm;
    memset(&tm, 0, sizeof(tm));
    time_t time = (time_t) *time64;

    if(localtime_r(&time, &tm)) {
      tm_to_tm64(&tm, tm64);
#ifndef HAVE_TM_ZONE
#if HAVE_TZNAME && HAVE_DAYLIGHT
      tm64->tm_zone = tzname[daylight && tm64->tm_isdst];
#else
      tm64->tm_zone = NULL;
#endif
#endif
      return tm64;
    }
  }

  /*
   * First determine the (approximate) year that this timestamp
   * is in using the gmtime64_r function. We then use this so
   * we are able to map this to a year that should be compatible
   * with the system localtime_r
   */

  struct tm64 gm;
  gmtime64_r(time64, &gm);

  int64_t gm_year = gm.tm_year;

  if(gm_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(gm_year, gm.tm_mon + 1, gm.tm_mday);
    if(gm.tm_mon == 2 && leap_year(gm_year)) {
      gm.tm_year = lower_leap_month_table[day];
    } else {
      gm.tm_year = lower_common_month_table[gm.tm_mon][day];
    }
  } else if(gm_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(gm_year, gm.tm_mon + 1, gm.tm_mday);
    if(gm.tm_mon == 2 && leap_year(gm_year)) {
      gm.tm_year = higher_leap_month_table[day];
    } else {
      gm.tm_year = higher_common_month_table[gm.tm_mon][day];
    }
  }

  /*
   * Get the timestamp for the safe date that we mapped the
   * large date to.
   */
  time_t time = (time_t)timegm64(&gm);
  struct tm tm;
  memset(&tm, 0, sizeof(tm));

  localtime_r(&time, &tm);
  tm_to_tm64(&tm, tm64);
  tm64->tm_year = gm_year;

  /*
   * We need to correct here for the case where the timezone difference
   * results in the dates occuring in two different years.
   */
  int month_diff = tm64->tm_mon - gm.tm_mon;
  if(month_diff == 11) {
    tm64->tm_year--;
  } else if(month_diff == -11) {
    tm64->tm_year++;
  }

  /* If the gm year is a leap year, but the local isn't and we're on
   * December 31st in the local year, this is marked as day 365 because
   * the gm year is a leap year. Therefore we need to substract 1.
   */
  if(!leap_year(tm64->tm_year) && tm64->tm_yday == 365 ) {
    tm64->tm_yday--;
  }

#ifndef HAVE_TM_ZONE
#if HAVE_TZNAME && HAVE_DAYLIGHT
  tm64->tm_zone = tzname[daylight && tm64->tm_isdst];
#else
  tm64->tm_zone = NULL;
#endif
#endif

  return tm64;
}
Пример #9
0
struct TM *gmtime64(const Time64_T *time) {
    return gmtime64_r(time, &Static_Return_Date);
}
Пример #10
0
struct TM *localtime64_r (const Time64_T *time, struct TM *local_tm)
{
    time_t safe_time;
    struct tm safe_date;
    struct TM gm_tm;
    Year orig_year;
    int month_diff;

    assert(local_tm != NULL);

    /* Use the system localtime() if time_t is small enough */
    if( SHOULD_USE_SYSTEM_LOCALTIME(*time) ) {
        safe_time = *time;

        TRACE1("Using system localtime for %lld\n", *time);

        LOCALTIME_R(&safe_time, &safe_date);

        copy_tm_to_TM(&safe_date, local_tm);
        assert(check_tm(local_tm));

        return local_tm;
    }

    if( gmtime64_r(time, &gm_tm) == NULL ) {
        TRACE1("gmtime64_r returned null for %lld\n", *time);
        return NULL;
    }

    orig_year = gm_tm.tm_year;

    if (gm_tm.tm_year > (2037 - 1900) ||
        gm_tm.tm_year < (1970 - 1900)
       )
    {
        TRACE1("Mapping tm_year %lld to safe_year\n", (Year)gm_tm.tm_year);
        gm_tm.tm_year = safe_year((Year)(gm_tm.tm_year + 1900)) - 1900;
    }

    safe_time = timegm64(&gm_tm);
    if( LOCALTIME_R(&safe_time, &safe_date) == NULL ) {
        TRACE1("localtime_r(%d) returned NULL\n", (int)safe_time);
        return NULL;
    }

    copy_tm_to_TM(&safe_date, local_tm);

    local_tm->tm_year = orig_year;
    if( local_tm->tm_year != orig_year ) {
        TRACE2("tm_year overflow: tm_year %lld, orig_year %lld\n",
              (Year)local_tm->tm_year, (Year)orig_year);

#ifdef EOVERFLOW
        errno = EOVERFLOW;
#endif
        return NULL;
    }


    month_diff = local_tm->tm_mon - gm_tm.tm_mon;

    /*  When localtime is Dec 31st previous year and
        gmtime is Jan 1st next year.
    */
    if( month_diff == 11 ) {
        local_tm->tm_year--;
    }

    /*  When localtime is Jan 1st, next year and
        gmtime is Dec 31st, previous year.
    */
    if( month_diff == -11 ) {
        local_tm->tm_year++;
    }

    /* GMT is Jan 1st, xx01 year, but localtime is still Dec 31st
       in a non-leap xx00.  There is one point in the cycle
       we can't account for which the safe xx00 year is a leap
       year.  So we need to correct for Dec 31st comming out as
       the 366th day of the year.
    */
    if( !IS_LEAP(local_tm->tm_year) && local_tm->tm_yday == 365 )
        local_tm->tm_yday--;

    assert(check_tm(local_tm));

    return local_tm;
}