1 /* Extensions for GNU date that are still missing here:
6 /* Copyright (C) 1991, 1992, 1993, 1994 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 <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 = _time_info->abbrev_wkday[tp->tm_wday];
94 CONST char *CONST f_wkday = _time_info->full_wkday[tp->tm_wday];
95 CONST char *CONST a_month = _time_info->abbrev_month[tp->tm_mon];
96 CONST char *CONST f_month = _time_info->full_month[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 = _time_info->ampm[hour12 >= 12];
103 size_t ap_len = strlen(ampm);
104 CONST unsigned int y_week0 = week(tp, 0);
105 CONST unsigned int y_week1 = week(tp, 1);
108 register size_t i = 0;
109 register char *p = s;
110 register CONST char *f;
112 if (tp->tm_isdst < 0)
119 zone = __tzname[tp->tm_isdst];
120 zonelen = strlen(zone);
126 if (hour12 == 0) hour12 = 12;
128 for (f = format; *f != '\0'; ++f)
134 /* Non-ASCII, may be a multibyte. */
135 int len = mblen(f, strlen(f));
158 cpy(aw_len, a_wkday);
162 cpy(wkday_len, f_wkday);
166 case 'h': /* GNU extension. */
167 cpy(am_len, a_month);
171 cpy(month_len, f_month);
175 subfmt = _time_info->date_time;
178 size_t len = strftime (p, maxsize - i, subfmt, tp);
184 fmt (2, (p, "%.2d", (1900 + tp->tm_year) / 100));
187 case 'D': /* GNU extension. */
192 fmt(2, (p, "%.2d", tp->tm_mday));
195 case 'e': /* GNU extension: %d, but blank-padded. */
196 fmt(2, (p, "%2d", tp->tm_mday));
200 fmt(2, (p, "%.2d", tp->tm_hour));
204 fmt(2, (p, "%.2d", hour12));
207 case 'k': /* GNU extension. */
208 fmt(2, (p, "%2d", tp->tm_hour));
211 case 'l': /* GNU extension. */
212 fmt(2, (p, "%2d", hour12));
216 fmt(3, (p, "%.3d", 1 + tp->tm_yday));
220 fmt(2, (p, "%.2d", tp->tm_min));
224 fmt(2, (p, "%.2d", tp->tm_mon + 1));
227 case 'n': /* GNU extension. */
235 case 'R': /* GNU extension. */
239 case 'r': /* GNU extension. */
240 subfmt = "%I:%M:%S %p";
244 fmt(2, (p, "%.2d", tp->tm_sec));
247 case 'T': /* GNU extenstion. */
251 case 't': /* GNU extenstion. */
256 fmt(2, (p, "%.2u", y_week0));
260 fmt(2, (p, "%.2u", y_week1));
264 fmt(2, (p, "%.2d", tp->tm_wday));
268 subfmt = _time_info->time;
272 subfmt = _time_info->date;
276 fmt(4, (p, "%.4d", 1900 + tp->tm_year));
280 fmt(2, (p, "%.2d", tp->tm_year));