[R-SIG-Mac] Formatting of time zone for POSIXct

Don MacQueen macq at llnl.gov
Thu Jan 20 00:17:44 CET 2005


Thank you Simon,

I should have found that myself; apologies for not exhausting all 
resources before sending my query.

I got caught because the default values of usetz in
     print.POSIXct
and
     format.POSIXct
are different.

My general experience has been that calling format() on an object 
gives the same format as calling print() -- at least on the objects I 
work with on a regular basis (and they did for POSIXct on Solaris). 
Obviously, the assumption that they would do so in this case and on a 
different platform was unwarranted.

Thanks again,

-Don

p.s. I'm *not* cc'ing to r-devel because my only real addition to 
this thread in this email is the note about the different defaults, 
and I expect the defaults were thought about and explicitly chosen, 
and don't need to be reconsidered.

At 4:54 PM -0500 1/19/05, Simon Urbanek wrote:
>Don,
>
>thanks for your report.
>
>On Jan 19, 2005, at 12:41 PM, Don MacQueen wrote:
>
>>I'm encountering a problem formatting POSIXct objects in R 2.0.1 on OS X.
>>
>>For reference, on a Solaris system, R 2.0.1 (2004-11-15), 
>>formatting is correct:
>>
>>>  Sys.time()
>>[1] "2005-01-19 09:12:33 PST"
>>>  format(Sys.time(),'%H:%M %Z')
>>[1] "09:12 PST"
>>
>>
>>On Mac OS X, however,
>>
>>R 2.0.1 Patched 2005-01-19
>>
>>>  Sys.time()
>>[1] "2005-01-19 09:18:27 PST"
>>>  format(Sys.time(),'%H:%M %Z')
>>[1] "09:18 P"
>
>The man pages says:
>    usetz: logical.  Should the timezone be appended to the output? This
>           is used in printing time, and as a workaround for problems
>           with using '"%Z"' on most Linux systems.
>
>so after reading that, you get the correct result:
>
>>  format(Sys.time(),'%H:%M',usetz=TRUE)
>[1] "15:57 EST"
>
>Now, the reason why I'm CCing this to R-devel is that in fact the 
>datetime.c is somewhat weird for non-GlibC2 systems as tm.tm_zone is 
>not initialized at all, which I suspect is a bug. Either the docs 
>should state that %Z should not be used at all or I'd propose the 
>following patch to make it work (warning, it's a patch against 
>R-devel):
>
>Index: src/main/datetime.c
>===================================================================
>--- src/main/datetime.c (revision 32715)
>+++ src/main/datetime.c (working copy)
>@@ -581,15 +581,8 @@
>         error("invalid `usetz' argument");
>      tz = getAttrib(x, install("tzone"));
>
>-    /* workaround for glibc bug in strftime */
>-#if defined HAVE_GLIBC2
>-#ifdef __USE_BSD
>-    tm.tm_zone = NULL;
>-#else
>-    tm.__tm_zone = NULL;
>-#endif
>-#endif
>-
>+       memset(&tm, 0, sizeof(tm));
>+
>      /* coerce fields to integer, find length of longest one */
>      for(i = 0; i < 9; i++) {
>         nlen[i] = LENGTH(VECTOR_ELT(x, i));
>
>This just zeroes out tm before use - it should also fix the problems 
>on Linux. Just in case I overlooked something and it's not feasible 
>to zero out the struct tm (e.g. if the size may be unknown), then 
>the following, more paranoid patch could be used:
>
>Index: src/main/datetime.c
>===================================================================
>--- src/main/datetime.c (revision 32715)
>+++ src/main/datetime.c (working copy)
>@@ -588,7 +588,11 @@
>  #else
>      tm.__tm_zone = NULL;
>  #endif
>+#else
>+#ifdef HAVE_STRUCT_TM_TM_ZONE
>+    tm.tm_zone = NULL;
>  #endif
>+#endif
>
>      /* coerce fields to integer, find length of longest one */
>      for(i = 0; i < 9; i++) {
>Index: configure.ac
>===================================================================
>--- configure.ac        (revision 32715)
>+++ configure.ac        (working copy)
>@@ -551,7 +551,7 @@
>    fpu_control.h grp.h ieee754.h ieeefp.h limits.h locale.h \
>    netdb.h netinet/in.h pwd.h strings.h \
>    sys/param.h sys/select.h sys/socket.h sys/stat.h sys/time.h \
>-  sys/times.h sys/utsname.h unistd.h)
>+  sys/times.h sys/utsname.h time.h unistd.h)
>  ## </NOTE>
>  ## <NOTE>
>  ## These are ANSI C headers but some C code (written to work also
>@@ -1333,6 +1333,13 @@
>  ## POSIX times.
>  R_SYS_POSIX_LEAPSECONDS
>
>+dnl some Solaris systems don't have a tm_zone member in struct tm.
>+AC_CHECK_MEMBERS([struct tm.tm_zone],,,[
>+#if defined(HAVE_TIME_H)
>+#include <time.h>
>+#endif
>+])
>+
>  ## R profiling.
>  if test "${want_R_profiling}" = yes; then
>    AC_CHECK_FUNCS(setitimer,
>
>The configure patch makes sure we know that struct tm.tm_zone exists 
>and the other patch makes sure it's reset before calling strftime. 
>Any variation hereof would help, too ;)
>
>>Changing the TZ environment variable, from the default of "" to 
>>"US/Pacific" does not help.
>
>Doing so has no effect for you, because the time zone is correct as 
>you demonstrated yourself in the above output.
>
>Cheers,
>Simon
>
>_______________________________________________
>R-SIG-Mac mailing list
>R-SIG-Mac at stat.math.ethz.ch
>https://stat.ethz.ch/mailman/listinfo/r-sig-mac


-- 
--------------------------------------
Don MacQueen
Environmental Protection Department
Lawrence Livermore National Laboratory
Livermore, CA, USA



More information about the R-SIG-Mac mailing list