|
|
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.