mactime.c
资源名称:unzip540.zip [点击查看]
上传用户:andy_li
上传日期:2007-01-06
资源大小:1019k
文件大小:10k
源码类别:
压缩解压
开发平台:
MultiPlatform
- /* -----------------------------------------------------------------------------
- The original functions (Metrowerks Codewarrior pro 3.0) gmtime, localtime,
- mktime and time do not work correctly. The supplied link library mactime.c
- contains replacement functions for them.
- * Caveat: On a Mac, we only know the GMT and DST offsets for
- * the current time, not for the time in question.
- * Mac has no support for DST handling.
- * DST changeover is all manually set by the user.
- ------------------------------------------------------------------------------*/
- /*****************************************************************************/
- /* Includes */
- /*****************************************************************************/
- #include <string.h>
- #include <stdlib.h>
- #include <stdio.h>
- #include <time.h>
- #include <OSUtils.h>
- #include "mactime.h"
- /*
- The MacOS function GetDateTime returns the
- number of seconds elapsed since midnight, January 1, 1904.
- */
- const unsigned long MacOS_2_Unix = 2082844800L;
- /*****************************************************************************/
- /* Macros, typedefs */
- /*****************************************************************************/
- #ifndef TEST_TIME_LIB
- #define my_gmtime gmtime
- #define my_localtime localtime
- #define my_mktime mktime
- #define my_time time
- #endif
- /*****************************************************************************/
- /* Prototypes */
- /*****************************************************************************/
- /* internal prototypes */
- static void clear_tm(struct tm * tm);
- static long GMTDelta(void);
- static Boolean DaylightSaving(void);
- static time_t GetTimeMac(void);
- static time_t Mactime(time_t *timer);
- static void normalize(int *i,int *j,int norm);
- static struct tm *time2tm(const time_t *timer);
- static time_t tm2time(struct tm *tp);
- /* Because serial port and SLIP conflict with ReadXPram calls,
- we cache the call here so we don't hang on calling ReadLocation() */
- static void myReadLocation(MachineLocation * loc);
- /* prototypes for STD lib replacement functions */
- struct tm *my_gmtime(const time_t *t);
- struct tm *my_localtime(const time_t *t);
- time_t my_mktime(struct tm *tp);
- time_t my_time(time_t *t);
- /*****************************************************************************/
- /* Functions */
- /*****************************************************************************/
- /*
- * Mac file times are based on 1904 Jan 1 00:00 local time,
- * not 1970 Jan 1 00:00 UTC.
- * So we have to convert the time stamps into UNIX UTC
- * compatible values.
- */
- time_t MacFtime2UnixFtime(unsigned long macftime)
- {
- long UTCoffset;
- GetGMToffsetMac(macftime, &UTCoffset);
- MACOS_TO_UNIX(macftime);
- macftime -= UTCoffset;
- return macftime;
- }
- /*
- * Mac file times are based on 1904 Jan 1 00:00 local time,
- * not 1970 Jan 1 00:00 UTC.
- * So we have to convert the time stamps into MacOS local
- * compatible values.
- */
- unsigned long UnixFtime2MacFtime(time_t unxftime)
- {
- long UTCoffset;
- unsigned long macftime = unxftime;
- UNIX_TO_MACOS(macftime);
- GetGMToffsetMac(macftime, &UTCoffset);
- macftime += UTCoffset;
- return macftime;
- }
- /*
- * This function convert a file-localtime to an another
- * file-localtime.
- */
- time_t AdjustForTZmoveMac(unsigned long macloctim, long s_gmtoffs)
- {
- time_t MacGMTTime;
- long UTCoffset;
- /* convert macloctim into corresponding UTC value */
- MacGMTTime = macloctim - s_gmtoffs;
- GetGMToffsetMac(macloctim, &UTCoffset);
- return (MacGMTTime + UTCoffset);
- } /* AdjustForTZmove() */
- /*
- * This function calculates the difference between the supplied Mac
- * ftime value (local time) and the corresponding UTC time in seconds.
- */
- Boolean GetGMToffsetMac(unsigned long mactime, long *UTCoffset)
- {
- mactime = mactime;
- /*
- * Caveat: On a Mac, we only know the GMT and DST offsets for
- * the current time, not for the time in question.
- * Mac has no support for DST handling.
- * DST changeover is all manually set by the user.
- May be later I can include a support of GMT offset calculation for the
- time in question here.
- */
- *UTCoffset = GMTDelta();
- return true;
- }
- /*****************************************************************************
- * Standard Library Replacement Functions
- * gmtime(), mktime(), localtime(), time()
- *
- * The unix epoch is used here.
- * These functions gmtime(), mktime(), localtime() and time()
- * expects and returns unix times.
- *
- * At midnight Jan. 1, 1970 GMT, the local time was
- * midnight Jan. 1, 1970 + GMTDelta().
- *
- *
- *****************************************************************************/
- struct tm *my_gmtime(const time_t *timer)
- {
- return time2tm(timer);
- }
- struct tm *my_localtime(const time_t *timer)
- {
- time_t maclocal;
- maclocal = *timer;
- maclocal += GMTDelta();
- return time2tm(&maclocal);
- }
- time_t my_mktime(struct tm *tp)
- {
- time_t maclocal;
- maclocal = tm2time(tp);
- maclocal -= GMTDelta();
- return maclocal;
- }
- time_t my_time(time_t *time)
- {
- time_t tmp_time;
- GetDateTime(&tmp_time);
- MACOS_TO_UNIX(tmp_time);
- if (time)
- {
- *time = tmp_time;
- }
- return tmp_time;
- }
- /*****************************************************************************/
- /* static module level functions
- /*****************************************************************************/
- /*
- * The geographic location and time zone information of a Mac
- * are stored in extended parameter RAM. The ReadLocation
- * produdure uses the geographic location record, MachineLocation,
- * to read the geographic location and time zone information in
- * extended parameter RAM.
- *
- * Because serial port and SLIP conflict with ReadXPram calls,
- * we cache the call here.
- *
- * Caveat: this caching will give the wrong result if a session
- * extend across the DST changeover time, but
- * this function resets itself every 2 hours.
- */
- static void myReadLocation(MachineLocation * loc)
- {
- static MachineLocation storedLoc; /* InsideMac, OSUtilities, page 4-20 */
- static time_t first_call = 0, last_call = 86400;
- if ((last_call - first_call) > 7200)
- {
- GetDateTime(&first_call);
- ReadLocation(&storedLoc);
- }
- GetDateTime(&last_call);
- *loc = storedLoc;
- }
- static Boolean DaylightSaving(void)
- {
- MachineLocation loc;
- unsigned char dlsDelta;
- myReadLocation(&loc);
- dlsDelta = loc.u.dlsDelta;
- return (dlsDelta != 0);
- }
- /* current local time = GMTDelta() + GMT
- GMT = local time - GMTDelta() */
- static long GMTDelta(void)
- {
- MachineLocation loc;
- long gmtDelta;
- myReadLocation(&loc);
- /*
- * On a Mac, the GMT value is in seconds east of GMT. For example,
- * San Francisco is at -28,800 seconds (8 hours * 3600 seconds per hour)
- * east of GMT. The gmtDelta field is a 3-byte value contained in a
- * long word, so you must take care to get it properly.
- */
- gmtDelta = loc.u.gmtDelta & 0x00FFFFFF;
- if ((gmtDelta & 0x00800000) != 0)
- {
- gmtDelta |= 0xFF000000;
- }
- return gmtDelta;
- }
- /* This routine simulates stdclib time(), time in seconds since 1.1.1970
- The time is in GMT */
- static time_t GetTimeMac(void)
- {
- unsigned long maclocal;
- /*
- * Get the current time expressed as the number of seconds
- * elapsed since the Mac epoch, midnight, Jan. 1, 1904 (local time).
- * On a Mac, current time accuracy is up to a second.
- */
- GetDateTime(&maclocal); /* Get Mac local time */
- maclocal -= GMTDelta(); /* Get Mac GMT */
- MACOS_TO_UNIX(maclocal);
- return maclocal; /* return unix GMT */
- }
- /*
- * clear_tm - sets a broken-down time to the equivalent of 1970/1/1 00:00:00
- */
- static void clear_tm(struct tm * tm)
- {
- tm->tm_sec = 0;
- tm->tm_min = 0;
- tm->tm_hour = 0;
- tm->tm_mday = 1;
- tm->tm_mon = 0;
- tm->tm_year = 0;
- tm->tm_wday = 1;
- tm->tm_yday = 0;
- tm->tm_isdst = -1;
- }
- static void normalize(int *i,int *j,int norm)
- {
- while(*i < 0)
- {
- *i += norm;
- (*j)--;
- }
- while(*i >= norm)
- {
- *i -= norm;
- (*j)++;
- }
- }
- /* Returns the GMT times */
- static time_t Mactime(time_t *timer)
- {
- time_t t = GetTimeMac();
- if (timer != NULL)
- *timer = t;
- return t;
- }
- static struct tm *time2tm(const time_t *timer)
- {
- DateTimeRec dtr;
- MachineLocation loc;
- time_t macLocal = *timer;
- static struct tm statictime;
- static const short monthday[12] =
- {0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334};
- /* macLocal -= GMTDelta(); */
- UNIX_TO_MACOS(macLocal);
- SecondsToDate(macLocal, &dtr);
- statictime.tm_sec = dtr.second; /* second, from 0 to 59 */
- statictime.tm_min = dtr.minute; /* minute, from 0 to 59 */
- statictime.tm_hour = dtr.hour; /* hour, from 0 to 23 */
- statictime.tm_mday = dtr.day; /* day of the month, from 1 to 31 */
- statictime.tm_mon = dtr.month - 1; /* month, 1= January and 12 = December */
- statictime.tm_year = dtr.year - 1900; /* year, ranging from 1904 to 2040 */
- statictime.tm_wday = dtr.dayOfWeek - 1; /* day of the week, 1 = Sun, 7 = Sat */
- statictime.tm_yday = monthday[statictime.tm_mon]
- + statictime.tm_mday - 1;
- if (2 < statictime.tm_mon && !(statictime.tm_year & 3))
- {
- ++statictime.tm_yday;
- }
- myReadLocation(&loc);
- statictime.tm_isdst = DaylightSaving();
- return(&statictime);
- }
- static time_t tm2time(struct tm *tp)
- {
- time_t intMacTime;
- DateTimeRec dtr;
- normalize(&tp->tm_sec, &tp->tm_min, 60);
- normalize(&tp->tm_min, &tp->tm_hour,60);
- normalize(&tp->tm_hour,&tp->tm_mday,24);
- normalize(&tp->tm_mon, &tp->tm_year,12);
- dtr.year = tp->tm_year + 1900; /* years since 1900 */
- dtr.month = tp->tm_mon + 1; /* month, 0 = January and 11 = December */
- dtr.day = tp->tm_mday; /* day of the month, from 1 to 31 */
- dtr.hour = tp->tm_hour; /* hour, from 0 to 23 */
- dtr.minute = tp->tm_min; /* minute, from 0 to 59 */
- dtr.second = tp->tm_sec; /* second, from 0 to 59 */
- DateToSeconds(&dtr, &intMacTime);
- MACOS_TO_UNIX(intMacTime);
- /* intMacTime -= GMTDelta(); */
- return intMacTime;
- }