2 Copyright © 1995-2008, 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 "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 (!strncasecmp (Dos_SubstDateTable
[t
], ptr
, strlen (Dos_SubstDateTable
[t
])))
143 days
= curr
.ds_Days
+ 1 - t
;
148 if (!strncasecmp (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 case FORMAT_DEF
: format
= "d.M.y"; break;
205 default: format
= "d-m-y"; break;
213 t
= StrToLong (ptr
, &year
);
226 t
= StrToLong (ptr
, &month
);
236 t
= StrToLong (ptr
, &days
);
248 if (!strncasecmp (Dos_MonthTable
[t
], ptr
,
249 strlen (Dos_MonthTable
[t
])))
258 ptr
+= strlen (Dos_MonthTable
[t
]);
275 /* kprintf ("Year=%ld, Month=%ld, Days=%ld\n",
276 year, month, days); */
278 /* Days go from 1..x */
281 /* First year must be 1978 */
285 /* Is this year a leap year ? */
286 leap
= (((year
% 400) == 0) ||
287 (((year
% 4) == 0) && !((year
% 100) == 0)));
289 /* Add the days for all years (without leap years) */
290 days
+= (year
- 1978) * 365;
293 /* stegerg: we do *not* want a day to be added for *this*
294 year, if it is a leap year. Only the previous years
295 are the ones we want to be taken into account. */
301 days
+= ((year
/ 4) - (year
/ 100) + (year
/ 400)
304 //kprintf("strtodate: days1 = %d\n", days);
305 /* Add days of months */
306 days
+= Dos_DayTable
[month
-1];
307 //kprintf("strtodate: days2 = %d\n", days);
310 In Dos_DayTable, February has 29 days. Correct this in
311 non-leap years and if the day has not yet been reached.
315 /* stegerg: if this year is *no* leap year, then Dos_DayTable
316 is wrong by one day when accessing
317 Dos_DayTable[March..Dec] */
319 if (!leap
&& (month
>= 3)) days
--;
321 if (month
>= 2 || (leap
&& month
< 2))
325 //kprintf("strtodate: days3 = %d\n", days);
329 } /* Not "Tomorrow", "Today" or "Yesterday" */
331 datetime
->dat_Stamp
.ds_Days
= days
;
333 } /* Convert date ? */
335 if ((ptr
= datetime
->dat_StrTime
))
337 len
= StrToLong (ptr
, &t
);
339 if ((len
== -1) || (t
< 0) || (t
> 23))
349 len
= StrToLong (ptr
, &t
);
351 if ((len
== -1) || (t
< 0) || (t
> 59))
363 len
= StrToLong (ptr
, &t
);
365 if ((len
== -1) || (t
< 0) || (t
> 59))
368 tick
= t
* TICKS_PER_SECOND
;
373 datetime
->dat_Stamp
.ds_Minute
= min
;
374 datetime
->dat_Stamp
.ds_Tick
= tick
;
385 int main (int argc
, char ** argv
)
390 char daybuf
[LEN_DATSTRING
];
391 char datebuf
[LEN_DATSTRING
];
392 char timebuf
[LEN_DATSTRING
];
404 dt
.dat_StrDate
= date
;
405 dt
.dat_StrTime
= time
;
407 dt
.dat_Format
= FORMAT_CDN
;
409 if (!StrToDate (&dt
))
411 printf ("Cannot convert date/time\n");
416 printf ("Result: Days=%ld, Minute=%ld, Ticks=%ld\n"
417 , dt
.dat_Stamp
.ds_Days
418 , dt
.dat_Stamp
.ds_Minute
419 , dt
.dat_Stamp
.ds_Tick
422 dt
.dat_StrDay
= daybuf
;
423 dt
.dat_StrDate
= datebuf
;
424 dt
.dat_StrTime
= timebuf
;
428 printf ("Gives: %s, %s %s\n", daybuf
, datebuf
, timebuf
);
430 dt
.dat_Flags
= DTF_SUBST
;
434 printf ("(With DTF_SUBST): %s, %s %s\n", daybuf
, datebuf
, timebuf
);