|
|
1.1 ! root 1: /* datewrap.c */ ! 2: ! 3: /* Wrappers for Borland getdate() and gettime() functions */ ! 4: ! 5: /* $Id: datewrap.c,v 1.26 2006/05/31 07:35:32 deuce Exp $ */ ! 6: ! 7: /**************************************************************************** ! 8: * @format.tab-size 4 (Plain Text/Source Code File Header) * ! 9: * @format.use-tabs true (see http://www.synchro.net/ptsc_hdr.html) * ! 10: * * ! 11: * Copyright 2005 Rob Swindell - http://www.synchro.net/copyright.html * ! 12: * * ! 13: * This library is free software; you can redistribute it and/or * ! 14: * modify it under the terms of the GNU Lesser General Public License * ! 15: * as published by the Free Software Foundation; either version 2 * ! 16: * of the License, or (at your option) any later version. * ! 17: * See the GNU Lesser General Public License for more details: lgpl.txt or * ! 18: * http://www.fsf.org/copyleft/lesser.html * ! 19: * * ! 20: * Anonymous FTP access to the most recent released source is available at * ! 21: * ftp://vert.synchro.net, ftp://cvs.synchro.net and ftp://ftp.synchro.net * ! 22: * * ! 23: * Anonymous CVS access to the development source and modification history * ! 24: * is available at cvs.synchro.net:/cvsroot/sbbs, example: * ! 25: * cvs -d :pserver:[email protected]:/cvsroot/sbbs login * ! 26: * (just hit return, no password is necessary) * ! 27: * cvs -d :pserver:[email protected]:/cvsroot/sbbs checkout src * ! 28: * * ! 29: * For Synchronet coding style and modification guidelines, see * ! 30: * http://www.synchro.net/source.html * ! 31: * * ! 32: * You are encouraged to submit any modifications (preferably in Unix diff * ! 33: * format) via e-mail to [email protected] * ! 34: * * ! 35: * Note: If this box doesn't appear square, then you need to fix your tabs. * ! 36: ****************************************************************************/ ! 37: ! 38: #include "string.h" /* memset */ ! 39: #include "genwrap.h" ! 40: #include "datewrap.h" /* xpDateTime_t */ ! 41: ! 42: /* Compensates for struct tm "weirdness" */ ! 43: time_t sane_mktime(struct tm* tm) ! 44: { ! 45: if(tm->tm_year>=1900) ! 46: tm->tm_year-=1900; ! 47: if(tm->tm_mon) /* Month is zero-based */ ! 48: tm->tm_mon--; ! 49: tm->tm_isdst=-1; /* Auto-adjust for DST */ ! 50: ! 51: return mktime(tm); ! 52: } ! 53: ! 54: /**************************************/ ! 55: /* Cross-platform date/time functions */ ! 56: /**************************************/ ! 57: ! 58: xpDateTime_t xpDateTime_create(unsigned year, unsigned month, unsigned day ! 59: ,unsigned hour, unsigned minute, float second ! 60: ,xpTimeZone_t zone) ! 61: { ! 62: xpDateTime_t xpDateTime; ! 63: ! 64: xpDateTime.date.year = year; ! 65: xpDateTime.date.month = month; ! 66: xpDateTime.date.day = day; ! 67: xpDateTime.time.hour = hour; ! 68: xpDateTime.time.minute = minute; ! 69: xpDateTime.time.second = second; ! 70: xpDateTime.zone = zone; ! 71: ! 72: return xpDateTime; ! 73: } ! 74: ! 75: xpDateTime_t xpDateTime_now(void) ! 76: { ! 77: #if defined(_WIN32) ! 78: SYSTEMTIME systime; ! 79: ! 80: GetLocalTime(&systime); ! 81: return(xpDateTime_create(systime.wYear,systime.wMonth,systime.wDay ! 82: ,systime.wHour,systime.wMinute,(float)systime.wSecond+(systime.wMilliseconds*0.001F) ! 83: ,xpTimeZone_local())); ! 84: #else /* !Win32 (e.g. Unix) */ ! 85: struct tm tm; ! 86: struct timeval tv; ! 87: time_t t; ! 88: ! 89: gettimeofday(&tv, NULL); ! 90: t=tv.tv_sec; ! 91: localtime_r(&t,&tm); ! 92: ! 93: return xpDateTime_create(1900+tm.tm_year,1+tm.tm_mon,tm.tm_mday ! 94: ,tm.tm_hour,tm.tm_min,(float)tm.tm_sec+(tv.tv_usec*0.00001) ! 95: ,xpTimeZone_local()); ! 96: #endif ! 97: } ! 98: ! 99: xpTimeZone_t xpTimeZone_local(void) ! 100: { ! 101: #if defined(__NetBSD__) || defined(__OpenBSD__) || defined(__FreeBSD__) || defined(__DARWIN__) ! 102: struct tm tm; ! 103: time_t t; ! 104: ! 105: localtime_r(&t, &tm); ! 106: return(tm.tm_gmtoff/60); ! 107: #else ! 108: #if defined(__BORLANDC__) || defined(__CYGWIN__) ! 109: #define timezone _timezone ! 110: #endif ! 111: ! 112: /* Converts (_)timezone from seconds west of UTC to minutes east of UTC */ ! 113: return -timezone/60; ! 114: #endif ! 115: } ! 116: ! 117: time_t xpDateTime_to_time(xpDateTime_t xpDateTime) ! 118: { ! 119: struct tm tm; ! 120: ! 121: ZERO_VAR(tm); ! 122: ! 123: if(xpDateTime.date.year==0) ! 124: return(0); ! 125: ! 126: tm.tm_year = xpDateTime.date.year; ! 127: tm.tm_mon = xpDateTime.date.month; ! 128: tm.tm_mday = xpDateTime.date.day; ! 129: ! 130: tm.tm_hour = xpDateTime.time.hour; ! 131: tm.tm_min = xpDateTime.time.minute; ! 132: tm.tm_sec = (int)xpDateTime.time.second; ! 133: ! 134: return sane_mktime(&tm); ! 135: ! 136: } ! 137: ! 138: xpDateTime_t time_to_xpDateTime(time_t ti) ! 139: { ! 140: xpDateTime_t never; ! 141: struct tm tm; ! 142: ! 143: memset(&never,0,sizeof(never)); ! 144: if(ti==0) ! 145: return(never); ! 146: ! 147: ZERO_VAR(tm); ! 148: if(gmtime_r(&ti,&tm)==NULL) ! 149: return(never); ! 150: ! 151: return xpDateTime_create(1900+tm.tm_year,1+tm.tm_mon,tm.tm_mday ! 152: ,tm.tm_hour,tm.tm_min,(float)tm.tm_sec,xpTimeZone_local()); ! 153: } ! 154: ! 155: /**********************************************/ ! 156: /* Decimal-coded ISO-8601 date/time functions */ ! 157: /**********************************************/ ! 158: ! 159: isoDate_t xpDateTime_to_isoDateTime(xpDateTime_t xpDateTime, isoTime_t* isoTime) ! 160: { ! 161: if(isoTime!=NULL) ! 162: *isoTime=0; ! 163: ! 164: if(xpDateTime.date.year==0) ! 165: return(0); ! 166: ! 167: if(isoTime!=NULL) ! 168: *isoTime=isoTime_create(xpDateTime.time.hour,xpDateTime.time.minute,xpDateTime.time.second); ! 169: ! 170: return isoDate_create(xpDateTime.date.year,xpDateTime.date.month,xpDateTime.date.day); ! 171: } ! 172: ! 173: xpDateTime_t isoDateTime_to_xpDateTime(isoDate_t date, isoTime_t ti) ! 174: { ! 175: return xpDateTime_create(isoDate_year(date),isoDate_month(date),isoDate_day(date) ! 176: ,isoTime_hour(ti),isoTime_minute(ti),(float)isoTime_second(ti),xpTimeZone_local()); ! 177: } ! 178: ! 179: isoDate_t time_to_isoDateTime(time_t ti, isoTime_t* isoTime) ! 180: { ! 181: struct tm tm; ! 182: ! 183: if(isoTime!=NULL) ! 184: *isoTime=0; ! 185: ! 186: if(ti==0) ! 187: return(0); ! 188: ! 189: ZERO_VAR(tm); ! 190: if(gmtime_r(&ti,&tm)==NULL) ! 191: return(0); ! 192: ! 193: if(isoTime!=NULL) ! 194: *isoTime=isoTime_create(tm.tm_hour,tm.tm_min,tm.tm_sec); ! 195: ! 196: return isoDate_create(1900+tm.tm_year,1+tm.tm_mon,tm.tm_mday); ! 197: } ! 198: ! 199: isoTime_t time_to_isoTime(time_t ti) ! 200: { ! 201: isoTime_t isoTime; ! 202: ! 203: time_to_isoDateTime(ti,&isoTime); ! 204: ! 205: return isoTime; ! 206: } ! 207: ! 208: time_t isoDateTime_to_time(isoDate_t date, isoTime_t ti) ! 209: { ! 210: struct tm tm; ! 211: ! 212: ZERO_VAR(tm); ! 213: ! 214: if(date==0) ! 215: return(0); ! 216: ! 217: tm.tm_year = isoDate_year(date); ! 218: tm.tm_mon = isoDate_month(date); ! 219: tm.tm_mday = isoDate_day(date); ! 220: ! 221: tm.tm_hour = isoTime_hour(ti); ! 222: tm.tm_min = isoTime_minute(ti); ! 223: tm.tm_sec = isoTime_second(ti); ! 224: ! 225: return sane_mktime(&tm); ! 226: } ! 227: ! 228: BOOL isoTimeZone_parse(const char* str, xpTimeZone_t* zone) ! 229: { ! 230: unsigned hour=0,minute=0; ! 231: ! 232: switch(*str) { ! 233: case 0: /* local time-zone */ ! 234: *zone = xpTimeZone_local(); ! 235: return TRUE; ! 236: case 'Z': /* UTC */ ! 237: *zone = 0; ! 238: return TRUE; ! 239: case '+': ! 240: case '-': /* "+/- HH[:]MM" */ ! 241: if(sscanf(str+1,"%2u%*s%2u",&hour,&minute)>=1) { ! 242: *zone = (hour*60) + minute; ! 243: if(*str=='-') ! 244: *zone = -(*zone); ! 245: return TRUE; ! 246: } ! 247: break; ! 248: } ! 249: return FALSE; ! 250: } ! 251: ! 252: xpDateTime_t isoDateTime_parse(const char* str) ! 253: { ! 254: char zone[16]; ! 255: xpDateTime_t xpDateTime; ! 256: ! 257: zone[0]=0; ! 258: ZERO_VAR(xpDateTime); ! 259: ! 260: if((sscanf(str,"%4u-%2u-%2uT%2u:%2u:%f%6s" /* CCYY-MM-DDThh:MM:ss�hhmm */ ! 261: ,&xpDateTime.date.year ! 262: ,&xpDateTime.date.month ! 263: ,&xpDateTime.date.day ! 264: ,&xpDateTime.time.hour ! 265: ,&xpDateTime.time.minute ! 266: ,&xpDateTime.time.second ! 267: ,zone)>=2 ! 268: || sscanf(str,"%4u%2u%2uT%2u%2u%f%6s" /* CCYYMMDDThhmmss�hhmm */ ! 269: ,&xpDateTime.date.year ! 270: ,&xpDateTime.date.month ! 271: ,&xpDateTime.date.day ! 272: ,&xpDateTime.time.hour ! 273: ,&xpDateTime.time.minute ! 274: ,&xpDateTime.time.second ! 275: ,zone)>=4 ! 276: || sscanf(str,"%4u%2u%2u%2u%2u%f%6s" /* CCYYMMDDhhmmss�hhmm */ ! 277: ,&xpDateTime.date.year ! 278: ,&xpDateTime.date.month ! 279: ,&xpDateTime.date.day ! 280: ,&xpDateTime.time.hour ! 281: ,&xpDateTime.time.minute ! 282: ,&xpDateTime.time.second ! 283: ,zone)>=1 ! 284: ) && isoTimeZone_parse(zone,&xpDateTime.zone)) ! 285: return xpDateTime; ! 286: ! 287: return xpDateTime; ! 288: } ! 289: ! 290: /***********************************/ ! 291: /* Borland DOS date/time functions */ ! 292: /***********************************/ ! 293: ! 294: #if !defined(__BORLANDC__) ! 295: ! 296: #if defined(_WIN32) ! 297: #include <windows.h> /* SYSTEMTIME and GetLocalTime() */ ! 298: #else ! 299: #include <sys/time.h> /* stuct timeval, gettimeofday() */ ! 300: #endif ! 301: ! 302: #include "datewrap.h" /* struct defs, verify prototypes */ ! 303: ! 304: void xp_getdate(struct date* nyd) ! 305: { ! 306: time_t tim; ! 307: struct tm dte; ! 308: ! 309: tim=time(NULL); ! 310: localtime_r(&tim,&dte); ! 311: nyd->da_year=dte.tm_year+1900; ! 312: nyd->da_day=dte.tm_mday; ! 313: nyd->da_mon=dte.tm_mon+1; ! 314: } ! 315: ! 316: void gettime(struct time* nyt) ! 317: { ! 318: #if defined(_WIN32) ! 319: SYSTEMTIME systime; ! 320: ! 321: GetLocalTime(&systime); ! 322: nyt->ti_hour=(unsigned char)systime.wHour; ! 323: nyt->ti_min=(unsigned char)systime.wMinute; ! 324: nyt->ti_sec=(unsigned char)systime.wSecond; ! 325: nyt->ti_hund=systime.wMilliseconds/10; ! 326: #else /* !Win32 (e.g. Unix) */ ! 327: struct tm dte; ! 328: time_t t; ! 329: struct timeval tim; ! 330: ! 331: gettimeofday(&tim, NULL); ! 332: t=tim.tv_sec; ! 333: localtime_r(&t,&dte); ! 334: nyt->ti_min=dte.tm_min; ! 335: nyt->ti_hour=dte.tm_hour; ! 336: nyt->ti_sec=dte.tm_sec; ! 337: nyt->ti_hund=tim.tv_usec/10000; ! 338: #endif ! 339: } ! 340: ! 341: #endif /* !Borland */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.