Subject: date(1) patch to alow timezone to be specified
To: None <current-users@netbsd.org>
From: Scott Aaron Bamford <sab@ansic.net>
List: current-users
Date: 04/29/2000 17:20:39
I'm soon to change timezone and wanted an easy way to know the time in
differnt timezones, so as not to wake up someone and have them pissed at me
forever (:

The attached patch adds this function to date(1) with little change in size:
% ls -l date*
-rwxr-xr-x  1 root  bin  79296 Apr 29 17:09 date
-rwxr-xr-x  1 root  bin  78719 Apr 29 17:09 date.old

% date            
Sat Apr 29 17:17:38 BST 2000
% date -z GMT
Sat Apr 29 16:17:41 GMT 2000
% date -z Pacific/Auckland
Sun Apr 30 04:17:53 NZST 2000

 - Scott

                              ("`-''-/").___..--''"`-._
 ------------------------------ `6_6  )   `-.  (     ).`-.__.`)
         sab@ansic.net |        (_Y_.)'  ._   )  `._ `. ``-..-'
  sab@zeekuschrist.com |      _..`--'_..-_/  /--'_.' ,'
 --------------------------- (il),-''  (li),'  ((!.-' ----


--- /usr/src/bin/date/date.c	Sat Apr 29 17:05:02 2000
+++ date.c	Sat Apr 29 16:58:37 2000
@@ -66,6 +66,8 @@
 
 #include "extern.h"
 
+#define ZONEDIR		"/usr/share/zoneinfo/"
+
 time_t tval;
 int retval, nflag;
 
@@ -73,6 +75,7 @@
 static void setthetime __P((const char *));
 static void badformat __P((void));
 static void badtime __P((void));
+static void badzone __P((void));
 static void usage __P((void));
 
 int
@@ -80,13 +83,14 @@
 	int argc;
 	char *argv[];
 {
-	int ch, rflag;
+	int ch, rflag, tzfd;
 	char *format, buf[1024];
+	char *tzone;
 
 	(void)setlocale(LC_ALL, "");
 
 	rflag = 0;
-	while ((ch = getopt(argc, argv, "nr:u")) != -1)
+	while ((ch = getopt(argc, argv, "nr:uz:")) != -1)
 		switch((char)ch) {
 		case 'n':		/* don't set network */
 			nflag = 1;
@@ -98,6 +102,19 @@
 		case 'u':		/* do everything in UTC */
 			(void)putenv("TZ=UTC0");
 			break;
+		case 'z':		/* use specified time zone */
+			(void)asprintf(&tzone, "%s%s", ZONEDIR, optarg);
+			if((tzfd = open(tzone, O_RDONLY)) < 0) {
+				close(tzfd);
+				free(tzone);
+				badzone();
+			}
+			close(tzfd);
+			free(tzone);
+			(void)asprintf(&tzone, "TZ=%s", optarg); 
+			(void)putenv(tzone);
+			free(tzone);
+			break;
 		default:
 			usage();
 		}
@@ -232,10 +249,17 @@
 }
 
 static void
+badzone()
+{
+	warnx("illegal time zone");
+	usage();
+}
+
+static void
 usage()
 {
 	(void)fprintf(stderr,
-	    "usage: date [-nu] [-r seconds] [+format]\n");
+	    "usage: date [-nu] [-r seconds] [-z timezone] [+format]\n");
 	(void)fprintf(stderr, "       date [[[[[cc]yy]mm]dd]hh]mm[.ss]\n");
 	exit(1);
 	/* NOTREACHED */
--- /usr/src/bin/date/date.1	Sat Apr 29 17:05:02 2000
+++ date.1	Sat Apr 29 16:58:07 2000
@@ -46,6 +46,7 @@
 .Nm
 .Op Fl nu
 .Op Fl r Ar seconds
+.Op Fl z Ar timezone
 .Op Cm + Ns Ar format
 .Nm ""
 .Ar [[[[[cc]yy]mm]dd]hh]mm[\&.ss]
@@ -80,6 +81,10 @@
 Display or set the date in
 .Tn UTC
 (universal) time.
+.It Fl z
+Display or set the date in
+.Ar timezone
+time.
 .El
 .Pp
 An operand with a leading plus (``+'') sign signals a user-defined format
@@ -174,6 +179,8 @@
 A record of date resets and time changes.
 .It Pa /var/log/messages
 A record of the user setting the time.
+.It Pa /usr/share/zoneinfo
+time zone information directory.
 .El
 .Sh SEE ALSO
 .Xr gettimeofday 2 ,