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