2 Copyright © 1995-2011, The AROS Development Team. All rights reserved.
9 #include "locale_intern.h"
10 #include <exec/types.h>
11 #include <utility/hooks.h>
12 #include <utility/date.h>
13 #include <proto/utility.h>
14 #include <clib/alib_protos.h>
18 VOID
PrintDigits(UWORD number
, char fill
, UWORD len
, const struct Hook
*hook
,
19 const struct Locale
*locale
);
20 VOID
_WriteChar(char token
, const struct Hook
*hook
,
21 const struct Locale
*locale
);
22 VOID
_WriteString(CONST_STRPTR string
, const struct Hook
*hook
,
23 const struct Locale
*locale
);
25 static const ULONG dayspermonth
[13] =
26 {0 /* not used */,0,31,59,90,120,151,181,212,243,273,304,334};
28 /*****************************************************************************
31 #include <proto/locale.h>
33 AROS_LH4(VOID
, FormatDate
,
36 AROS_LHA(const struct Locale
*, locale
, A0
),
37 AROS_LHA(CONST_STRPTR
, formatString
, A1
),
38 AROS_LHA(const struct DateStamp
*, date
, A2
),
39 AROS_LHA(const struct Hook
*, hook
, A3
),
42 struct LocaleBase
*, LocaleBase
, 10, Locale
)
46 Generate a date string based on a template. The bytes generated are sent
47 to a user specified callback function.
51 locale -- the locale to use when formatting the string or NULL
52 for the system default locale.
53 formatString -- the formatting template string; this is much like the
54 printf() formatting style, i.e. a % followed by a
55 formatting command. The following commands exist:
57 %a -- abbreviated weekday name
59 %b -- abbreviated month name
61 %c -- the same as "%a %b %d %H:%M:%S %Y"
62 %C -- the same as "%a %b %e %T %Z %Y"
63 %d -- day number with leading zeros
64 %D -- the same as "%m/%d/%y"
65 %e -- day number with leading spaces
66 %h -- abbreviated month name
67 %H -- hour using 24 hour style with leading zeros
68 %I -- hour using 12 hour style with leading zeros
70 %m -- month number with leading zeros
71 %M -- the number of minutes with leading zeros
74 %q -- hour using 24 hour style
75 %Q -- hour using 12 hour style
76 %r -- the same as "%I:%M:%S %p"
77 %R -- the same as "%H:%M"
78 %S -- the number of seconds with leading zeros
80 %T -- the same as "%H:%M:%S"
81 %U -- the week number, taking Sunday as the first day
83 %w -- the weekday number
84 %W -- the week number, taking Monday as the first day
86 %x -- the same as "%m/%d/%y"
87 %X -- the same as "%H:%M:%S"
88 %y -- the year using two digits with leading zeros
89 %Y -- the year using four digits with leading zeros
91 If the template parameter is NULL, a single null byte
92 is sent to the callback function.
94 date -- the current date
95 hook -- callback function; this is called for every character
96 generated with the following arguments:
98 * pointer to hook structure
112 ParseDate(), <libraries/locale.h>
116 *****************************************************************************/
120 struct ClockData cData
;
121 ULONG week
, days
, tmp
;
122 struct Locale
*def_locale
= NULL
;
129 locale
= OpenLocale(NULL
);
132 def_locale
= (struct Locale
*)locale
;
135 if (formatString
== NULL
)
137 _WriteChar(0, hook
, locale
);
138 CloseLocale(def_locale
);
142 /* TODO: Amiga2Date will fail around year 2114, because then the
143 * number of seconds since 1978 won't fit in a 32 bit variable anymore!
146 Amiga2Date(date
->ds_Days
* 86400 + date
->ds_Minute
* 60 +
147 date
->ds_Tick
/ 50, &cData
);
149 while (*formatString
!= 0)
151 if (*formatString
== '%')
153 switch (*(++formatString
))
156 _WriteString(GetLocaleStr(locale
, ABDAY_1
+ cData
.wday
),
161 _WriteString(GetLocaleStr(locale
, DAY_1
+ cData
.wday
), hook
,
166 _WriteString(GetLocaleStr(locale
,
167 ABMON_1
+ cData
.month
- 1), hook
, locale
);
171 _WriteString(GetLocaleStr(locale
, MON_1
+ cData
.month
- 1),
176 FormatDate(locale
, "%a %b %d %H:%M:%S %Y", date
, hook
);
180 FormatDate(locale
, "%a %b %e %T %Z %Y", date
, hook
);
184 PrintDigits(cData
.mday
, '0', 2, hook
, locale
);
189 FormatDate(locale
, "%m/%d/%y", date
, hook
);
193 PrintDigits(cData
.mday
, ' ', 2, hook
, locale
);
197 _WriteString(GetLocaleStr(locale
,
198 ABMON_1
+ cData
.month
- 1), hook
, locale
);
202 PrintDigits(cData
.hour
, '0', 2, hook
, locale
);
206 PrintDigits(cData
.hour
% 12, '0', 2, hook
, locale
);
210 /* TODO: Julian date not tested. */
211 /* Julian date is DDD (1 - 366) */
212 PrintDigits(cData
.mday
+ dayspermonth
[cData
.month
],
213 '0', 3, hook
, locale
);
217 PrintDigits(cData
.month
, '0', 2, hook
, locale
);
221 PrintDigits(cData
.min
, '0', 2, hook
, locale
);
225 _WriteChar('\n', hook
, locale
);
229 _WriteString(GetLocaleStr(locale
,
230 cData
.hour
< 12 ? AM_STR
: PM_STR
), hook
, locale
);
234 PrintDigits(cData
.hour
, -1, 2, hook
, locale
);
238 PrintDigits(cData
.hour
% 12, -1, 2, hook
, locale
);
242 FormatDate(locale
, "%I:%M:%S %p", date
, hook
);
246 FormatDate(locale
, "%H:%M", date
, hook
);
250 PrintDigits(cData
.sec
, '0', 2, hook
, locale
);
254 _WriteChar('\t', hook
, locale
);
259 FormatDate(locale
, "%H:%M:%S", date
, hook
);
262 case 'W': /* week number, Monday first day of week */
263 case 'U': /* week number, Sunday first day of week */
264 days
= cData
.mday
+ dayspermonth
[cData
.month
];
267 if (0 == (cData
.year
% 4) && cData
.month
> 2)
270 ** 1700, 1800, 1900, 2100, 2200 re not leap years.
271 ** 2000 is a leap year.
272 ** -> if a year is divisible by 100 but not by 400 then
273 ** it is not a leap year!
275 if (0 == (cData
.year
% 100) && 0 != (cData
.year
% 400))
282 ** If January 1st is a Monday then the first week
283 ** will start with a Sunday January 7th if Sunday is the first day of the week
284 ** but if Monday is the first day of the week then Jan 1st will also be the
285 ** first day of the first week.
288 ** Go to Saturday = last day of week if Sunday is first day of week
289 ** Go to Sunday = last day of week if Monday is first day of week
291 if ('U' == *formatString
)
293 /* Sunday is first day of the week */
294 tmp
= days
+ (6 - cData
.wday
);
298 /* Monday is first day of week */
300 tmp
= days
+ (7 - cData
.wday
);
309 /* cut off the few days that belong to week 0 */
311 /* Calculate the full amount of weeks */
315 PrintDigits(week
, '0', 2, hook
, locale
);
319 PrintDigits(cData
.wday
, -1, 1, hook
, locale
);
323 PrintDigits(cData
.year
% 100, '0', 2, hook
, locale
);
327 PrintDigits(cData
.year
, '0', 4, hook
, locale
);
331 /* cuurent time zone Unimplemented in 3.1 */
338 _WriteChar(*formatString
, hook
, locale
);
344 _WriteChar(*formatString
, hook
, locale
);
350 _WriteChar(0, hook
, locale
); /* Write null terminator */
352 CloseLocale(def_locale
);
358 VOID
_WriteString(CONST_STRPTR string
, const struct Hook
*hook
,
359 const struct Locale
*locale
)
363 _WriteChar(*string
++, hook
, locale
);
368 VOID
_WriteChar(char token
, const struct Hook
*hook
,
369 const struct Locale
*locale
)
371 AROS_UFC3NR(VOID
, hook
->h_Entry
,
372 AROS_UFCA(const struct Hook
*, hook
, A0
),
373 AROS_UFCA(const struct Locale
*, locale
, A2
),
374 AROS_UFCA(char, token
, A1
));
378 VOID
PrintDigits(UWORD number
, char fill
, UWORD len
,
379 const struct Hook
*hook
, const struct Locale
*locale
)
387 while ((number
|| !i
) && i
< len
)
389 *--ptr
= number
% 10 + '0';
394 while (len
- i
> 0 && (char)-1 != fill
)
397 _WriteChar(fill
, hook
, locale
);
400 _WriteString((char *)ptr
, hook
, locale
);