1 /* Extensions for GNU date that are still missing here:
6 /* Copyright (C) 1991, 1992, 1993, 1994, 1995 Free Software Foundation, Inc.
7 This file is part of the GNU C Library.
9 The GNU C Library is free software; you can redistribute it and/or
10 modify it under the terms of the GNU Library General Public License as
11 published by the Free Software Foundation; either version 2 of the
12 License, or (at your option) any later version.
14 The GNU C Library is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 Library General Public License for more details.
19 You should have received a copy of the GNU Library General Public
20 License along with the GNU C Library; see the file COPYING.LIB. If
21 not, write to the Free Software Foundation, Inc., 675 Mass Ave,
22 Cambridge, MA 02139, USA. */
25 #include "../locale/localeinfo.h"
35 #define __tzname tzname
36 #define __daylight daylight
37 #define __timezone timezone
54 #define cpy(n, s) add((n), memcpy((PTR) p, (PTR) (s), (n)))
55 #define fmt(n, args) add((n), if (sprintf args != (n)) return 0)
57 /* Return the week in the year specified by TP,
58 with weeks starting on STARTING_DAY. */
63 DEFUN(week
, (tp
, starting_day
),
64 CONST
struct tm
*CONST tp AND
int starting_day
)
68 wday
= tp
->tm_wday
- starting_day
;
72 /* Set DL to the day in the year of the last day of the week previous to the
73 one containing the day specified in TP. If DL is negative or zero, the
74 day specified in TP is in the first week of the year. Otherwise,
75 calculate the number of complete weeks before our week (DL / 7) and
76 add any partial week at the start of the year (DL % 7). */
77 dl
= tp
->tm_yday
- wday
;
78 return dl
<= 0 ? 0 : ((dl
/ 7) + ((dl
% 7) == 0 ? 0 : 1));
82 /* Write information from TP into S according to the format
83 string FORMAT, writing no more that MAXSIZE characters
84 (including the terminating '\0') and returning number of
85 characters written. If S is NULL, nothing will be written
86 anywhere, so to determine how many characters would be
87 written, use NULL for S and (size_t) UINT_MAX for MAXSIZE. */
89 DEFUN(strftime
, (s
, maxsize
, format
, tp
),
90 char *s AND
size_t maxsize AND
91 CONST
char *format AND
register CONST
struct tm
*tp
)
93 CONST
char *CONST a_wkday
= _NL_CURRENT (LC_TIME
, ABDAY_1
+ tp
->tm_wday
);
94 CONST
char *CONST f_wkday
= _NL_CURRENT (LC_TIME
, DAY_1
+ tp
->tm_wday
);
95 CONST
char *CONST a_month
= _NL_CURRENT (LC_TIME
, ABMON_1
+ tp
->tm_mon
);
96 CONST
char *CONST f_month
= _NL_CURRENT (LC_TIME
, MON_1
+ tp
->tm_mon
);
97 size_t aw_len
= strlen(a_wkday
);
98 size_t am_len
= strlen(a_month
);
99 size_t wkday_len
= strlen(f_wkday
);
100 size_t month_len
= strlen(f_month
);
101 int hour12
= tp
->tm_hour
;
102 CONST
char *CONST ampm
= _NL_CURRENT (LC_TIME
,
103 hour12
> 12 ? PM_STR
: AM_STR
);
104 size_t ap_len
= strlen (ampm
);
105 CONST
unsigned int y_week0
= week (tp
, 0);
106 CONST
unsigned int y_week1
= week (tp
, 1);
109 register size_t i
= 0;
110 register char *p
= s
;
111 register CONST
char *f
;
113 if (tp
->tm_isdst
< 0)
120 zone
= __tzname
[tp
->tm_isdst
];
121 zonelen
= strlen(zone
);
127 if (hour12
== 0) hour12
= 12;
129 for (f
= format
; *f
!= '\0'; ++f
)
135 /* Non-ASCII, may be a multibyte. */
136 int len
= mblen(f
, strlen(f
));
159 cpy(aw_len
, a_wkday
);
163 cpy(wkday_len
, f_wkday
);
167 case 'h': /* GNU extension. */
168 cpy(am_len
, a_month
);
172 cpy(month_len
, f_month
);
176 subfmt
= _NL_CURRENT (LC_TIME
, D_T_FMT
);
179 size_t len
= strftime (p
, maxsize
- i
, subfmt
, tp
);
185 fmt (2, (p
, "%.2d", (1900 + tp
->tm_year
) / 100));
188 case 'D': /* GNU extension. */
193 fmt(2, (p
, "%.2d", tp
->tm_mday
));
196 case 'e': /* GNU extension: %d, but blank-padded. */
197 fmt(2, (p
, "%2d", tp
->tm_mday
));
201 fmt(2, (p
, "%.2d", tp
->tm_hour
));
205 fmt(2, (p
, "%.2d", hour12
));
208 case 'k': /* GNU extension. */
209 fmt(2, (p
, "%2d", tp
->tm_hour
));
212 case 'l': /* GNU extension. */
213 fmt(2, (p
, "%2d", hour12
));
217 fmt(3, (p
, "%.3d", 1 + tp
->tm_yday
));
221 fmt(2, (p
, "%.2d", tp
->tm_min
));
225 fmt(2, (p
, "%.2d", tp
->tm_mon
+ 1));
228 case 'n': /* GNU extension. */
236 case 'R': /* GNU extension. */
240 case 'r': /* GNU extension. */
241 subfmt
= "%I:%M:%S %p";
245 fmt(2, (p
, "%.2d", tp
->tm_sec
));
248 case 'T': /* GNU extenstion. */
252 case 't': /* GNU extenstion. */
257 fmt(2, (p
, "%.2u", y_week0
));
261 fmt(2, (p
, "%.2u", y_week1
));
265 fmt(2, (p
, "%.2d", tp
->tm_wday
));
269 subfmt
= _NL_CURRENT (LC_TIME
, T_FMT
);
273 subfmt
= _NL_CURRENT (LC_TIME
, D_FMT
);
277 fmt(4, (p
, "%.4d", 1900 + tp
->tm_year
));
281 fmt(2, (p
, "%.2d", tp
->tm_year
% 100));