2 Copyright © 1995-2013, The AROS Development Team. All rights reserved.
5 Desc: Converts a string into a date
9 #include "dos_intern.h"
12 # include <proto/dos.h>
17 # define AROS_LH1(ret,name,arg,type,base,offset,libname) \
19 # define AROS_LHA(type,name,reg) type name
21 const ULONG Dos_DayTable
[]=
23 0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335
26 const char *const Dos_MonthTable
[]=
28 "Jan", "Feb", "Mar", "Apr", "May", "Jun",
29 "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
32 const char *const Dos_WeekTable
[]=
34 "Sunday", "Monday", "Tuesday", "Wednesday",
35 "Thursday", "Friday", "Saturday"
38 const char *const Dos_SubstDateTable
[]=
40 "Future", "Tomorrow", "Today", "Yesterday"
46 /*****************************************************************************
49 #include <dos/datetime.h>
50 #include <proto/dos.h>
52 AROS_LH1(BOOL
, StrToDate
,
55 AROS_LHA(struct DateTime
*, datetime
, D1
),
58 struct DosLibrary
*, DOSBase
, 125, Dos
)
61 Converts a human readable ASCII string into an AmigaDOS
65 DateTime - a pointer to an initialized DateTime structure.
66 The structure should be initialized as follows:
68 dat_Stamp: The converted date will be written here
70 dat_Format: How to convert the datestamp into
71 dat_StrDate. Can be any of the following:
73 FORMAT_DOS: AmigaDOS format (dd-mmm-yy). This
74 is the default if you specify something other
75 than any entry in this list.
77 FORMAT_INT: International format (yy-mmm-dd).
79 FORMAT_USA: American format (mm-dd-yy).
81 FORMAT_CDN: Canadian format (dd-mm-yy).
83 FORMAT_DEF: default format for locale.
86 dat_Flags: Modifies dat_Format. The only flag
87 used by this function is DTF_FUTURE. If set, then
88 a string like "Monday" refers to the next monday.
89 Otherwise it refers to the last monday.
93 dat_StrDate: Pointer to valid string representing the
94 date. This can be a "DTF_SUBST" style string such
95 as "Today" "Tomorrow" "Monday", or it may be a
96 string as specified by the dat_Format byte. This
97 will be converted to the ds_Days portion of the
98 DateStamp. If this pointer is NULL,
99 DateStamp->ds_Days will not be affected.
101 dat_StrTime: Pointer to a buffer which contains the
102 time in the ASCII format hh:mm:ss. This will be
103 converted to the ds_Minutes and ds_Ticks portions
104 of the DateStamp. If this pointer is NULL,
105 ds_Minutes and ds_Ticks will be unchanged.
109 A zero return indicates that a conversion could not be performed. A
110 non-zero return indicates that the DateTime.dat_Stamp variable
111 contains the converted values.
120 DateStamp(), DateToStr()
124 *****************************************************************************/
127 struct DateStamp curr
;
128 LONG days
, min
, tick
, len
, t
, year
, month
;
130 UBYTE
* ptr
, * format
;
132 if ((ptr
= datetime
->dat_StrDate
))
138 if (!Strnicmp (Dos_SubstDateTable
[t
+ 1], ptr
, strlen (Dos_SubstDateTable
[t
+ 1])))
143 days
= curr
.ds_Days
+ 1 - t
;
148 if (!Strnicmp (Dos_WeekTable
[t
], ptr
, strlen (Dos_WeekTable
[t
])))
159 diffdays
= t
- (days
% 7);
161 if (datetime
->dat_Flags
& DTF_FUTURE
)
169 days
+= 7 + diffdays
;
180 days
+= diffdays
- 7;
193 if (datetime
->dat_Flags
& DTF_FUTURE
)
199 switch (datetime
->dat_Format
)
201 case FORMAT_INT
: format
= "y-M-d"; break;
202 case FORMAT_USA
: format
= "m-d-y"; break;
203 case FORMAT_CDN
: format
= "d-m-y"; break;
204 default: format
= "d-M-y"; break;
212 t
= StrToLong (ptr
, &year
);
225 t
= StrToLong (ptr
, &month
);
235 t
= StrToLong (ptr
, &days
);
247 if (!Strnicmp (Dos_MonthTable
[t
], ptr
,
248 strlen (Dos_MonthTable
[t
])))
257 ptr
+= strlen (Dos_MonthTable
[t
]);
274 /* kprintf ("Year=%ld, Month=%ld, Days=%ld\n",
275 year, month, days); */
277 /* Days go from 1..x */
280 /* First year must be 1978 */
284 /* Is this year a leap year ? */
285 leap
= (((year
% 400) == 0) ||
286 (((year
% 4) == 0) && !((year
% 100) == 0)));
288 /* Add the days for all years (without leap years) */
289 days
+= (year
- 1978) * 365;
292 /* stegerg: we do *not* want a day to be added for *this*
293 year, if it is a leap year. Only the previous years
294 are the ones we want to be taken into account. */
300 days
+= ((year
/ 4) - (year
/ 100) + (year
/ 400)
303 //kprintf("strtodate: days1 = %d\n", days);
304 /* Add days of months */
305 days
+= Dos_DayTable
[month
-1];
306 //kprintf("strtodate: days2 = %d\n", days);
309 In Dos_DayTable, February has 29 days. Correct this in
310 non-leap years and if the day has not yet been reached.
314 /* stegerg: if this year is *no* leap year, then Dos_DayTable
315 is wrong by one day when accessing
316 Dos_DayTable[March..Dec] */
318 if (!leap
&& (month
>= 3)) days
--;
320 if (month
>= 2 || (leap
&& month
< 2))
324 //kprintf("strtodate: days3 = %d\n", days);
328 } /* Not "Tomorrow", "Today" or "Yesterday" */
330 datetime
->dat_Stamp
.ds_Days
= days
;
332 } /* Convert date ? */
334 if ((ptr
= datetime
->dat_StrTime
))
336 len
= StrToLong (ptr
, &t
);
338 if ((len
== -1) || (t
< 0) || (t
> 23))
348 len
= StrToLong (ptr
, &t
);
350 if ((len
== -1) || (t
< 0) || (t
> 59))
362 len
= StrToLong (ptr
, &t
);
364 if ((len
== -1) || (t
< 0) || (t
> 59))
367 tick
= t
* TICKS_PER_SECOND
;
372 datetime
->dat_Stamp
.ds_Minute
= min
;
373 datetime
->dat_Stamp
.ds_Tick
= tick
;
384 int main (int argc
, char ** argv
)
389 char daybuf
[LEN_DATSTRING
];
390 char datebuf
[LEN_DATSTRING
];
391 char timebuf
[LEN_DATSTRING
];
403 dt
.dat_StrDate
= date
;
404 dt
.dat_StrTime
= time
;
406 dt
.dat_Format
= FORMAT_CDN
;
408 if (!StrToDate (&dt
))
410 printf ("Cannot convert date/time\n");
415 printf ("Result: Days=%ld, Minute=%ld, Ticks=%ld\n"
416 , dt
.dat_Stamp
.ds_Days
417 , dt
.dat_Stamp
.ds_Minute
418 , dt
.dat_Stamp
.ds_Tick
421 dt
.dat_StrDay
= daybuf
;
422 dt
.dat_StrDate
= datebuf
;
423 dt
.dat_StrTime
= timebuf
;
427 printf ("Gives: %s, %s %s\n", daybuf
, datebuf
, timebuf
);
429 dt
.dat_Flags
= DTF_SUBST
;
433 printf ("(With DTF_SUBST): %s, %s %s\n", daybuf
, datebuf
, timebuf
);