1 /*****************************************************************************/
2 /* */
3 /* (C) Copyright 1995-1997 Alberto Pasquale */
4 /* Portions (C) Copyright 1999 Per Lundberg */
5 /* */
6 /* A L L R I G H T S R E S E R V E D */
7 /* */
8 /*****************************************************************************/
9 /* */
10 /* How to contact the author: Alberto Pasquale of 2:332/504@fidonet */
11 /* Viale Verdi 106 */
12 /* 41100 Modena */
13 /* Italy */
14 /* */
15 /*****************************************************************************/
16
17 #include "apgenlib.hpp"
18 #include <string.h>
19
20
21 #define YEAR(t) (((t & 0xFE00) >> 9) + 1980)
22 #define MONTH(t) ((t & 0x01E0) >> 5)
23 #define DAY(t) (t & 0x001F)
24 #define HOUR(t) ((t & 0xF800) >> 11)
25 #define MINUTE(t) ((t & 0x07E0) >> 5)
26 #define SECOND(t) ((t & 0x001F) << 1)
27
28
dosdatimetounix(ushort date,ushort time)29 time_t dosdatimetounix (ushort date, ushort time)
30 {
31 if ((date == 0) && (time == 0))
32 return 0;
33
34 struct tm tm;
35
36 tm.tm_sec = SECOND (time);
37 tm.tm_min = MINUTE (time);
38 tm.tm_hour = HOUR (time);
39 tm.tm_mday = DAY (date);
40 tm.tm_mon = MONTH (date) - 1;
41 tm.tm_year = YEAR (date) - 1900;
42 tm.tm_isdst = -1; // compute this field
43
44 return mktime (&tm);
45 }
46
47 /*
48 time_t DosDatime2Unix (const dosdate_t *ddate, const dostime_t *dtime)
49 {
50 tm tm;
51
52 memset (&tm, 0, sizeof (tm));
53
54 tm.tm_mday = ddate->day;
55 tm.tm_mon = ddate->month - 1;
56 tm.tm_year = ddate->year - 1900;
57 tm.tm_isdst = -1;
58
59 if (dtime) {
60 tm.tm_hour = dtime->hour;
61 tm.tm_min = dtime->minute;
62 tm.tm_sec = dtime->second;
63 }
64
65 return mktime (&tm);
66 }
67 */
68
69
stamptounix(_stamp * stamp)70 time_t stamptounix (_stamp *stamp)
71 {
72 return dosdatimetounix (((_dos_st *)stamp)->date, ((_dos_st *)stamp)->time);
73 }
74
75
76
77
unix2dosdatime(time_t utime,ushort * date,ushort * time)78 void unix2dosdatime (time_t utime, ushort *date, ushort *time)
79 {
80 _stamp datime;
81 unix2stamp (utime, &datime);
82 *date = MKushort (datime.date);
83 *time = MKushort (datime.time);
84 }
85
86 /*
87 void Unix2DosDatime (time_t utime, dosdate_t *ddate, dostime_t *dtime)
88 {
89 tm *tm;
90 tm = localtime (&utime);
91
92 if (ddate) {
93 ddate->day = tm.tm_mday;
94 ddate->month = tm.tm_mon + 1;
95 ddate->year = tm.tm_year + 1900;
96 ddate->dayofweek = tm.tm_wday;
97 }
98
99 if (dtime) {
100 dtime->hour = tm.tm_hour;
101 dtime->minute = tm.tm_min;
102 dtime->second = tm.tm_sec;
103 dtime->hsecond = 0;
104 }
105
106 }
107 */
108
109
unix2stamp(time_t utime,_stamp * datime)110 void unix2stamp (time_t utime, _stamp *datime)
111 {
112 if (utime == 0) {
113 ((_dos_st *)datime)->date = 0;
114 ((_dos_st *)datime)->time = 0;
115 return;
116 }
117
118 struct tm *tm;
119
120 tm = localtime (&utime);
121 datime->date.da = (word) tm->tm_mday;
122 datime->date.mo = (word) (tm->tm_mon + 1);
123 datime->date.yr = (word) (tm->tm_year-80);
124 datime->time.ss = (word) (tm->tm_sec/2);
125 datime->time.mm = (word) tm->tm_min;
126 datime->time.hh = (word) tm->tm_hour;
127 }
128
129
130
131 byte DateFormat = DF_USA;
132
133 static char *datefs[4] = { "%m-%d-%y", "%d-%m-%y", "%y-%m-%d", "%y%m%d" };
134
135
unix2dates(time_t utime,char * dates,byte DFovr)136 char *unix2dates (time_t utime, char *dates, byte DFovr)
137 {
138 if (DFovr == DF_DEFAULT)
139 DFovr = DateFormat;
140
141 static char datestat[9];
142 char *d = dates ? dates : datestat;
143 if (utime)
144 strftime (d, 9, datefs[DFovr], localtime (&utime));
145 else
146 strcpy (d, "(nodate)");
147 return d;
148 }
149
150
stamp2dates(_stamp * stamp,char * dates,byte DFovr)151 char *stamp2dates (_stamp *stamp, char *dates, byte DFovr)
152 {
153 return unix2dates (stamptounix (stamp), dates, DFovr);
154 }
155
156
dates2unix(char * dates,byte DFovr)157 time_t dates2unix (char *dates, byte DFovr)
158 {
159 if (DFovr == DF_DEFAULT)
160 DFovr = DateFormat;
161
162 word tok[3];
163
164 if (DFovr == DF_SCIENT) {
165 if (strlen (dates) != 6)
166 return 0;
167 if (sscanf (dates, "%2hu%2hu%2hu", &tok[0], &tok[1], &tok[2]) != 3)
168 return 0;
169 } else {
170 if (strlen (dates) != 8)
171 return 0;
172 char sep[3];
173 if (sscanf (dates, "%2hu%c%2hu%c%2hu", &tok[0], &sep[0], &tok[1], &sep[1], &tok[2]) != 5)
174 return 0;
175 sep[2] = '\0';
176 if (strspn (sep, ".-/") != 2) // invalid separation char
177 return 0;
178 }
179
180 word da, mo, yr;
181
182 switch (DFovr) {
183 case DF_USA:
184 mo = tok[0];
185 da = tok[1];
186 yr = tok[2];
187 break;
188 case DF_EURO:
189 da = tok[0];
190 mo = tok[1];
191 yr = tok[2];
192 break;
193 case DF_JAPAN:
194 case DF_SCIENT:
195 default: // use scientific as default
196 yr = tok[0];
197 mo = tok[1];
198 da = tok[2];
199 break;
200 }
201
202 if ((mo < 1) || (mo > 12))
203 return 0;
204
205 if (da < 1)
206 return 0;
207
208 switch (mo) {
209 case 2:
210 if (da > ((yr % 4) ? 28 : 29)) // valid til 2099
211 return 0;
212 break;
213 case 4:
214 case 6:
215 case 9:
216 case 11:
217 if (da > 30)
218 return 0;
219 break;
220 default:
221 if (da > 31)
222 return 0;
223 }
224
225 _stamp st;
226
227 ((_dos_st *)(&st))->time = 0;
228
229 st.date.da = da;
230 st.date.mo = mo;
231 st.date.yr = (word) ((yr >= 80) ? (yr - 80) : (yr + 20)); // valid till 2079
232
233 return stamptounix (&st);
234 }
235