11 /* This 'date' command supports only 2 time setting formats,
12 all the GNU strftime stuff (its in libc, lets use it),
13 setting time using UTC and displaying int, as well as
14 an RFC 822 complient date output for shell scripting
17 const char date_usage[] = "date [-uR] [+FORMAT|+%f] [ [-s|-d] MMDDhhmm[[CC]YY]\n"
18 "| [[[[CCYY.]MM.DD-]hh:mm[:ss]]]] ]";
20 //static const char date_usage[] = "Usage: date [OPTION]... [+FORMAT]\n"
21 //"or: date [OPTION] [MMDDhhmm[[CC]YY][.ss]]\n"
22 //"Display the current time in the given FORMAT, or set the system date.\n";
25 static struct option const long_options[] =
27 {"date", required_argument, NULL, 'd'},
28 /* {"rfc-822", no_argument, NULL, 'R'},
29 {"set", required_argument, NULL, 's'},
30 {"uct", no_argument, NULL, 'u'},
31 {"utc", no_argument, NULL, 'u'},
32 {"universal", no_argument, NULL, 'u'}, */
38 /* Input parsing code is always bulky - used heavy duty libc stuff as
39 much as possible, missed out a lot of bounds checking */
41 /* Default input handling to save suprising some people */
44 date_conv_time(struct tm *tm_time, const char *t_string) {
47 nr = sscanf(t_string, "%2d%2d%2d%2d%d",
54 if(nr < 4 || nr > 5) {
55 fprintf(stderr, "date: invalid date `%s'\n", t_string);
59 /* correct for century - minor Y2K problem here? */
60 if(tm_time->tm_year >= 1900)
61 tm_time->tm_year -= 1900;
70 /* The new stuff for LRP */
73 date_conv_ftime(struct tm *tm_time, const char *t_string) {
74 struct tm itm_time, jtm_time, ktm_time, \
75 ltm_time, mtm_time, ntm_time;
84 /* Parse input and assign appropriately to tm_time */
86 if(sscanf(t_string, "%d:%d:%d",
89 &itm_time.tm_sec) == 3 ) {
94 } else if (sscanf(t_string, "%d:%d",
96 &jtm_time.tm_min) == 2) {
101 } else if (sscanf(t_string, "%d.%d-%d:%d:%d",
106 &ktm_time.tm_sec) == 5) {
108 ktm_time.tm_mon -= 1; /* Adjust dates from 1-12 to 0-11 */
112 } else if (sscanf(t_string, "%d.%d-%d:%d",
116 <m_time.tm_min) == 4) {
118 ltm_time.tm_mon -= 1; /* Adjust dates from 1-12 to 0-11 */
122 } else if (sscanf(t_string, "%d.%d.%d-%d:%d:%d",
128 &mtm_time.tm_sec) == 6) {
130 mtm_time.tm_year -= 1900; /* Adjust years */
131 mtm_time.tm_mon -= 1; /* Adjust dates from 1-12 to 0-11 */
135 } else if (sscanf(t_string, "%d.%d.%d-%d:%d",
140 &ntm_time.tm_min) == 5) {
141 ntm_time.tm_year -= 1900; /* Adjust years */
142 ntm_time.tm_mon -= 1; /* Adjust dates from 1-12 to 0-11 */
148 fprintf(stderr, "date: invalid date `%s'\n", t_string);
157 fprintf(stderr, "date: only one date argument can be given at a time.\n");
162 date_main(int argc, char * * argv)
164 char *date_str = NULL;
165 char *date_fmt = NULL;
176 /* Interpret command line args */
179 while ((optc = getopt_long (argc, argv, "d:Rs:u", long_options, NULL))
191 if(date_str != NULL) date_err();
197 if (putenv ("TZ=UTC0") != 0) {
198 fprintf(stderr,"date: memory exhausted\n");
207 if(date_str != NULL) date_err();
212 fprintf(stderr, "Usage: %s", date_usage);
218 n_args = argc - optind;
221 switch(argv[optind][0]) {
223 /* Date format strings */
224 if(date_fmt != NULL) {
225 fprintf(stderr, "date: only one date format can be given.\n");
228 date_fmt = &argv[optind][1];
235 /* Anything left over must be a date string to set the time */
237 if(date_str != NULL) date_err();
238 date_str = argv[optind];
245 /* Now we have parsed all the information except the date format
246 which depends on whether the clock is being set or read */
249 memcpy(&tm_time, localtime(&tm), sizeof(tm_time));
250 /* Zero out fields - take her back to midnight!*/
251 if(date_str != NULL) {
257 /* Process any date input to UNIX time since 1 Jan 1970 */
258 if(date_str != NULL) {
260 if(strchr(date_str, ':') != NULL) {
261 date_conv_ftime(&tm_time, date_str);
263 date_conv_time(&tm_time, date_str);
266 /* Correct any day of week and day of year etc fields */
267 tm = mktime(&tm_time);
269 fprintf(stderr, "date: invalid date `%s'\n", date_str);
273 /* if setting time, set it */
275 if( stime(&tm) < 0) {
276 fprintf(stderr, "date: can't set date.\n");
284 /* Deal with format string */
285 if(date_fmt == NULL) {
288 ? "%a, %_d %b %Y %H:%M:%S GMT"
289 : "%a, %_d %b %Y %H:%M:%S %z")
290 : "%a %b %e %H:%M:%S %Z %Y");
292 } else if ( *date_fmt == '\0' ) {
293 /* Imitate what GNU 'date' does with NO format string! */
298 /* Handle special conversions */
300 if( strncmp( date_fmt, "%f", 2) == 0 ) {
301 date_fmt = "%Y.%m.%d-%H:%M:%S";
304 /* Print OUTPUT (after ALL that!) */
305 t_buff = malloc(201);
306 strftime(t_buff, 200, date_fmt, &tm_time);
307 printf("%s\n", t_buff);