gmt_mktime.c revision 505d05c73a6e56769f263d4803b22eddd168ee24
f38cb554a534c6df738be3f4d23327e69888e634John Wren Kennedy/*
f38cb554a534c6df738be3f4d23327e69888e634John Wren Kennedy * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
f38cb554a534c6df738be3f4d23327e69888e634John Wren Kennedy * Use is subject to license terms.
f38cb554a534c6df738be3f4d23327e69888e634John Wren Kennedy */
f38cb554a534c6df738be3f4d23327e69888e634John Wren Kennedy
f38cb554a534c6df738be3f4d23327e69888e634John Wren Kennedy#pragma ident "%Z%%M% %I% %E% SMI"
f38cb554a534c6df738be3f4d23327e69888e634John Wren Kennedy
f38cb554a534c6df738be3f4d23327e69888e634John Wren Kennedy/* This code placed in the public domain by Mark W. Eichin */
f38cb554a534c6df738be3f4d23327e69888e634John Wren Kennedy
f38cb554a534c6df738be3f4d23327e69888e634John Wren Kennedy#include <stdio.h>
f38cb554a534c6df738be3f4d23327e69888e634John Wren Kennedy#include <k5-int.h>
f38cb554a534c6df738be3f4d23327e69888e634John Wren Kennedy
f38cb554a534c6df738be3f4d23327e69888e634John Wren Kennedy#ifdef HAVE_SYS_TYPES_H
f38cb554a534c6df738be3f4d23327e69888e634John Wren Kennedy#include <sys/types.h>
f38cb554a534c6df738be3f4d23327e69888e634John Wren Kennedy#endif
f38cb554a534c6df738be3f4d23327e69888e634John Wren Kennedy#ifdef HAVE_SYS_TIME_H
f38cb554a534c6df738be3f4d23327e69888e634John Wren Kennedy#include <sys/time.h>
f38cb554a534c6df738be3f4d23327e69888e634John Wren Kennedy#ifdef TIME_WITH_SYS_TIME
f38cb554a534c6df738be3f4d23327e69888e634John Wren Kennedy#include <time.h>
f38cb554a534c6df738be3f4d23327e69888e634John Wren Kennedy#endif
f38cb554a534c6df738be3f4d23327e69888e634John Wren Kennedy#else
f38cb554a534c6df738be3f4d23327e69888e634John Wren Kennedy#include <time.h>
f38cb554a534c6df738be3f4d23327e69888e634John Wren Kennedy#endif
f38cb554a534c6df738be3f4d23327e69888e634John Wren Kennedy
f38cb554a534c6df738be3f4d23327e69888e634John Wren Kennedy/* take a struct tm, return seconds from GMT epoch */
f38cb554a534c6df738be3f4d23327e69888e634John Wren Kennedy/* like mktime, this ignores tm_wday and tm_yday. */
f38cb554a534c6df738be3f4d23327e69888e634John Wren Kennedy/* unlike mktime, this does not set them... it only passes a return value. */
1d32ba663e202c24a5a1f2e5aef83fffb447cb7fJohn Wren Kennedy
f38cb554a534c6df738be3f4d23327e69888e634John Wren Kennedystatic const int days_in_month[12] = {
f38cb554a534c6df738be3f4d23327e69888e634John Wren Kennedy0, /* jan 31 */
f38cb554a534c6df738be3f4d23327e69888e634John Wren Kennedy31, /* feb 28 */
f38cb554a534c6df738be3f4d23327e69888e634John Wren Kennedy59, /* mar 31 */
f38cb554a534c6df738be3f4d23327e69888e634John Wren Kennedy90, /* apr 30 */
f38cb554a534c6df738be3f4d23327e69888e634John Wren Kennedy120, /* may 31 */
f38cb554a534c6df738be3f4d23327e69888e634John Wren Kennedy151, /* jun 30 */
f38cb554a534c6df738be3f4d23327e69888e634John Wren Kennedy181, /* jul 31 */
f38cb554a534c6df738be3f4d23327e69888e634John Wren Kennedy212, /* aug 31 */
f38cb554a534c6df738be3f4d23327e69888e634John Wren Kennedy243, /* sep 30 */
f38cb554a534c6df738be3f4d23327e69888e634John Wren Kennedy273, /* oct 31 */
f38cb554a534c6df738be3f4d23327e69888e634John Wren Kennedy304, /* nov 30 */
f38cb554a534c6df738be3f4d23327e69888e634John Wren Kennedy334 /* dec 31 */
f38cb554a534c6df738be3f4d23327e69888e634John Wren Kennedy};
f38cb554a534c6df738be3f4d23327e69888e634John Wren Kennedy
f38cb554a534c6df738be3f4d23327e69888e634John Wren Kennedy#define hasleapday(year) (year%400?(year%100?(year%4?0:1):0):1)
f38cb554a534c6df738be3f4d23327e69888e634John Wren Kennedy
1d32ba663e202c24a5a1f2e5aef83fffb447cb7fJohn Wren Kennedytime_t gmt_mktime(struct tm *t)
f38cb554a534c6df738be3f4d23327e69888e634John Wren Kennedy{
f38cb554a534c6df738be3f4d23327e69888e634John Wren Kennedy time_t accum;
f38cb554a534c6df738be3f4d23327e69888e634John Wren Kennedy
f38cb554a534c6df738be3f4d23327e69888e634John Wren Kennedy#define assert_time(cnd) if(!(cnd)) return (time_t) -1
/*
* For 32-bit signed time_t centered on 1/1/1970, the range is:
* time 0x80000000 -> Fri Dec 13 16:45:52 1901
* time 0x7fffffff -> Mon Jan 18 22:14:07 2038
*
* So years 1901 and 2038 are allowable, but we can't encode all
* dates in those years, and we're not doing overflow/underflow
* checking for such cases.
*/
assert_time(t->tm_year>=1);
assert_time(t->tm_year<=138);
assert_time(t->tm_mon>=0);
assert_time(t->tm_mon<=11);
assert_time(t->tm_mday>=1);
assert_time(t->tm_mday<=31);
assert_time(t->tm_hour>=0);
assert_time(t->tm_hour<=23);
assert_time(t->tm_min>=0);
assert_time(t->tm_min<=59);
assert_time(t->tm_sec>=0);
assert_time(t->tm_sec<=62);
#undef assert_time
accum = t->tm_year - 70;
accum *= 365; /* 365 days/normal year */
/* add in leap day for all previous years */
if (t->tm_year >= 70)
accum += (t->tm_year - 69) / 4;
else
accum -= (72 - t->tm_year) / 4;
/* add in leap day for this year */
if(t->tm_mon >= 2) /* march or later */
if(hasleapday((t->tm_year + 1900))) accum += 1;
accum += days_in_month[t->tm_mon];
accum += t->tm_mday-1; /* days of month are the only 1-based field */
accum *= 24; /* 24 hour/day */
accum += t->tm_hour;
accum *= 60; /* 60 minute/hour */
accum += t->tm_min;
accum *= 60; /* 60 seconds/minute */
accum += t->tm_sec;
return accum;
}