The recent change to grdc(6), to display additional information if TZ is
set, has a few issues.

1.  Time zone offset incorrectly reported in Newfoundland.

Some time zones have offsets of 30 or 45 minutes.  The displayed time
offset is currently truncated to the closest hour.  (Australia/Eucla
is a fun time zone too.)

2.  The new, additional information disappears if the window is sized too
small (wintoosmall).  There's basically room for it though...  except

3.  The TZ information is a string of unknown length, and so it doesn't
necessarily display correctly.

Yeah, I know with pledge() you can't do testing like
TZ=:/home/pjanzen/dev/usr/share/zoneinfo/testing/2022/America/Kentucky/Monticello
any more, even though that's a perfectly cromulent and functional TZ on my
system otherwise. So for the time being, probably any TZ that exists and
doesn't abort grdc is 38 bytes or shorter.  Which works.

But, if your timezone exists, it already has its name in short form
included in tm->tm_zone.  That's what I think should be
printed, even if "EDT" is way less cool than "America/Pangnirtung".  I
mean, if the point is just to be able to label clocks with nice places,
instead of the time zone it's showing, maybe it could be a different option.

Counterpoint:  some of the timezones have short names that are just the UTC
offset, which is really boring and duplicated given that we print out the
offset already.  Hey, maybe we could just print the offset...

4.  There's no indication if you type an invalid TZ--you get UTC and a
misleading label onscreen.

Timezone handling defaults to UTC if anything breaks along the chain, as
the tzset(3) man page makes clear.  That means if you misspell Antarctica
while setting your TZ=Antartica/McMurdo, you'll end up half a day off from
all your pals at McMurdo as your screen happily tells you that you're
seeing McMurdo +0 time.

There's no simple way to tell if your $TZ is valid or not (if you get back
UTC, maybe that's really what it should be!).  At least if we display
tm->tm_zone rather than $TZ, we're not misleading.



I was going to be upset that the man page for grdc(6) is way pickier on TZ
than tzset(3), but it's quite accurate given the pledge() call.  Speaking
of which, I don't expect any one else plays with timezone files, and surely
one doesn't want one's general utilities to be pwned by possible bugs in
the time-handling code exploited with custom files created outside
/usr/share/zoneinfo.  But it's still a touch irritating-should-be-fixable
that, because the pledge() has to be after initscr(), grdc has the
possibility of leaving the terminal in the wrong state when it aborts on
test TZ files.



Paul Janzen.


Index: grdc.c
===================================================================
RCS file: /cvs/src/games/grdc/grdc.c,v
retrieving revision 1.35
diff -u -p -r1.35 grdc.c
--- grdc.c      17 Sep 2022 10:32:05 -0000      1.35
+++ grdc.c      18 Sep 2022 05:30:04 -0000
@@ -41,6 +41,7 @@ volatile sig_atomic_t sigwinched = 0;
 
 int hascolor = 0;
 
+void print_tz(int, int, int);
 void getwinsize(int *, int *);
 void set(int, int);
 void standt(int);
@@ -184,11 +185,8 @@ main(int argc, char *argv[])
                                move(ybase, xbase + XLENGTH);
                                vline(ACS_VLINE, YDEPTH);
 
-                               if (tz != NULL) {
-                                       move(ybase - 1, xbase);
-                                       printw("[ %s %+d ]", tz,
-                                           tm->tm_gmtoff / 60 / 60 );
-                               }
+                               if (tz)
+                                       print_tz(ybase - 1, xbase, wintoosmall);
 
                                attrset(COLOR_PAIR(2));
                        }
@@ -199,6 +197,8 @@ main(int argc, char *argv[])
                        move(0, 0);
                        printw("%02d:%02d:%02d", tm->tm_hour, tm->tm_min,
                            tm->tm_sec);
+                       if (tz)
+                               print_tz(1, 0, wintoosmall);
                } else for (k = 0; k < 6; k++) {
                        if (scrol) {
                                for(i = 0; i < 5; i++)
@@ -282,6 +282,22 @@ set(int t, int n)
        }
        if (mask & m)
                mask |= m;
+}
+
+void
+print_tz(int y, int x, int sml)
+{
+       int i, j;
+
+       move(y, x);
+       i = tm->tm_gmtoff / 60 / 60;
+       j = tm->tm_gmtoff / 60 - i * 60;
+       if (i < 0)
+               j = -j;
+       if (!sml)
+               printw("[ %s %+dh%02d ]", tm->tm_zone, i, j);
+       else
+               printw("[%+dh%02d]", i, j);
 }
 
 void

Reply via email to