1 /* $OpenBSD: date.c,v 1.26 2003/10/15 15:58:22 mpech Exp $ */
2 /* $NetBSD: date.c,v 1.11 1995/09/07 06:21:05 jtc Exp $ */
5 * Copyright (c) 1985, 1987, 1988, 1993
6 * The Regents of the University of California. All rights reserved.
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 * 3. Neither the name of the University nor the names of its contributors
17 * may be used to endorse or promote products derived from this software
18 * without specific prior written permission.
20 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
21 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
24 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33 #include <sys/param.h>
47 __COPYRIGHT("@(#) Copyright (c) 1985, 1987, 1988, 1993\n\
48 The Regents of the University of California. All rights reserved.\n");
49 __SCCSID("@(#)date.c 8.2 (Berkeley) 4/28/95");
50 __RCSID("$MirOS: src/bin/date/date.c,v 1.9 2016/01/02 21:32:56 tg Exp $");
52 extern const char *__progname
;
59 #define TM_YEAR_BASE 1900
62 static void setthetime(char *);
63 static __dead
void badformat(void);
64 static __dead
void usage(void);
67 main(int argc
, char *argv
[])
71 const char *format
= NULL
;
75 tz
.tz_dsttime
= tz
.tz_minuteswest
= 0;
77 while ((ch
= getopt(argc
, argv
, "ad:nRr:ut:")) != -1)
82 case 'd': /* daylight saving time */
83 tz
.tz_dsttime
= atoi(optarg
) ? 1 : 0;
85 case 'n': /* don't set network */
87 case 'R': /* RFC 2822 format */
90 case 'r': /* user specified seconds */
94 case 'u': /* do everything in UTC */
95 if (setenv("TZ", "GMT0", 1) == -1)
96 err(1, "cannot unsetenv TZ");
98 case 't': /* minutes west of GMT */
99 /* error check; don't allow "PST" */
100 if (isdigit(*optarg
)) {
101 tz
.tz_minuteswest
= atoi(optarg
);
112 * If -d or -t, set the timezone or daylight saving time; this
113 * doesn't belong here, the kernel should not know about either.
115 if ((tz
.tz_minuteswest
|| tz
.tz_dsttime
) &&
116 settimeofday(NULL
, &tz
))
117 err(1, "settimeofday");
119 if (!rflag
&& time(&tval
) == -1)
122 /* allow the operands in any order */
123 if (*argv
&& **argv
== '+') {
136 if (*argv
&& **argv
== '+') {
142 format
= "%a %b %e %H:%M:%S %Z %Y";
143 else if (whatformat
== 1) {
144 format
= "%a, %d %b %Y %H:%M:%S %z";
145 } else if (whatformat
!= 2 && whatformat
!= 4)
146 errx(1, "more than one format specified");
148 strftime(buf
, sizeof (buf
), format
, localtime(&tval
));
153 #define ATOI2(ar) ((ar)[0] - '0') * 10 + ((ar)[1] - '0'); (ar) += 2;
164 for (t
= p
, dot
= NULL
; *t
; ++t
) {
167 if (*t
== '.' && dot
== NULL
) {
174 lt
= localtime(&tval
);
176 lt
->tm_isdst
= -1; /* correct for DST */
178 if (dot
!= NULL
) { /* .SS */
180 if (strlen(dot
) != 2)
182 lt
->tm_sec
= ATOI2(dot
);
191 lt
->tm_year
= bigyear
* 100 - TM_YEAR_BASE
;
196 lt
->tm_year
+= ATOI2(p
);
198 lt
->tm_year
= ATOI2(p
);
199 if (lt
->tm_year
< 69) /* hack for 2000 ;-} */
200 lt
->tm_year
+= (2000 - TM_YEAR_BASE
);
202 lt
->tm_year
+= (1900 - TM_YEAR_BASE
);
206 lt
->tm_mon
= ATOI2(p
);
207 if ((lt
->tm_mon
> 12) || !lt
->tm_mon
)
209 --lt
->tm_mon
; /* time struct is 0 - 11 */
212 lt
->tm_mday
= ATOI2(p
);
213 if ((lt
->tm_mday
> 31) || !lt
->tm_mday
)
217 lt
->tm_hour
= ATOI2(p
);
218 if (lt
->tm_hour
> 23)
222 lt
->tm_min
= ATOI2(p
);
230 /* convert broken-down time to UTC clock time */
231 if ((tval
= mktime(lt
)) < 0)
232 errx(1, "specified date is outside allowed range");
236 struct timeval tv_current
;
238 if (gettimeofday(&tv_current
, NULL
) == -1)
239 err(1, "Could not get local time of day");
241 tv
.tv_sec
= tval
- tv_current
.tv_sec
;
243 if (adjtime(&tv
, NULL
) == -1)
248 if (settimeofday(&tv
, NULL
))
249 err(1, "settimeofday");
252 if ((pc
= getlogin()) == NULL
)
254 syslog(LOG_AUTH
| LOG_NOTICE
, "date set by %s", pc
);
260 warnx("illegal time format");
268 "usage:\t%s [-anRu] [-d dst] [-r seconds] [-t west] [+format]\n",
270 fprintf(stderr
, "\t [[[[[[cc]yy]mm]dd]HH]MM[.SS]]\n");