From stephen.berman at gmx.net  Fri Oct 20 18:27:33 2017
From: stephen.berman at gmx.net (Stephen Berman)
Date: Fri, 20 Oct 2017 18:27:33 +0200
Subject: [Rd] Another issue with Sys.timezone
In-Reply-To: <23017.41630.884512.113683@stat.math.ethz.ch> (Martin Maechler's
 message of "Fri, 20 Oct 2017 09:15:42 +0200")
References: <871sm570d3.fsf@gmx.net>
 <23012.59579.35802.920274@stat.math.ethz.ch>
 <23015.31941.397029.272777@stat.math.ethz.ch> <87r2tzmarx.fsf@gmx.net>
 <23017.41630.884512.113683@stat.math.ethz.ch>
Message-ID: <87lgk5ss22.fsf@gmx.net>

On Fri, 20 Oct 2017 09:15:42 +0200 Martin Maechler <maechler at stat.math.ethz.ch> wrote:

>>>>>> Stephen Berman <stephen.berman at gmx.net>
>>>>>>     on Thu, 19 Oct 2017 17:12:50 +0200 writes:
>
>     > On Wed, 18 Oct 2017 18:09:41 +0200 Martin Maechler
>     > <maechler at stat.math.ethz.ch> wrote:
>     >>>>>>> Martin Maechler <maechler at stat.math.ethz.ch>
>     >>>>>>> on Mon, 16 Oct 2017 19:13:31 +0200 writes:
>
[...]
>     >>> whereas on Windows I get Europe/Berlin for the first (why on
>     >>> earth - I'm really in Zurich) and get "CEST" ("Central European Summer
>     >>> Time")
>     >>> for the 2nd one instead of NA ... simply using a smarter version
>     >>> of your proposal.   The windows source is
>     >>> in R's source at  src/library/base/R/windows/system.R :
>     >>> 
>     >>> Sys.timezone <- function(location = TRUE)
>     >>> {
>     >>> tz <- Sys.getenv("TZ", names = FALSE)
>     >>> if(nzchar(tz)) return(tz)
>     >>> if(location) return(.Internal(tzone_name()))
>     >>> z <- as.POSIXlt(Sys.time())
>     >>> zz <- attr(z, "tzone")
>     >>> if(length(zz) == 3L) zz[2L + z$isdst] else zz[1L]
>     >>> }
>     >>> 
>     >>> >From what I read, the last three lines also work in your setup
>     >>> where it seems zz would be of length 1, right ?
>
>     > Those line do indeed work here, but zz has three elements:
>
>     >> attributes(as.POSIXlt(Sys.time()))$tzone
>     > [1] ""     "CET"  "CEST"
>
> { "but" ??   yes, three elements is what I see too, but for that
>   reason there's the  if(length(zz) == 3L) ... }

The "but" was in response to "it seems zz would be of length 1", but
perhaps I misunderstood you.

[...]
>     >> As you say yourself, the above system("... xargs md5sum ...")
>     >> using workaround is really too platform specific  but I'd guess
>     >> there should be a less error prone way to get the long timezone
>     >> name on your system ...
>
>     > If I understand the zic(8) man page, the files in /usr/share/zoneinfo
>     > should contain this information, but I don't know how to extract it,
>     > since these are compiled files.  And since on my system /etc/localtime
>     > is a copy of one of these compiled files, I don't know of any other way
>     > to recover the location name without comparing it to those files.
>
>     >> If that remains "contained" (i.e. small) and works with files
>     >> and R's files tools -- e.g. file.*() ones [but not system()],
>     >> I'd consider a patch to the above source file
>     >> (sent by you to the R-devel mailing list --- or after having
>     >> gotten an account there by asking, via bug report & patch
>     >> attachment at https://bugs.r-project.org/ )
>
>     > If comparing file size sufficed, that would be easy to do in R;
>     > unfortunately, it is not sufficient, since some files designating
>     > different time zones in /usr/share/zoneinfo do have the same size.  So
>     > the only alternative I can think of is to compare bytes, e.g. with
>     > md5sum or with cmp.  Is there some way to do this in R without using
>     > system()?
>
> Can't you use
>       tz1 <- readBin("/etc/localtime", "raw", 200L)
> plus later
>       tz2 <- gsub(.......,  rawToChar(tz1))
>
> on your  /etc/localtime file 
> almost identically as the current code does for "/etc/timezone" ?

Oh, thanks.  I've looked at this code over and over again in the last
few days and somehow still didn't see its usefulness (maybe because I
haven't had occasion to deal with binary data in R till now).  Anyway,
just substituting "/etc/localtime" for "/etc/timezone" doesn't work,
since my /etc/localtime file seems not to hold the timezone location
name in a form recoverable with rawToChar() (all I see are the
abbreviated timezones CEST, CEMT and CET-1CEST); but I can use the raw
bytes to make the comparison with files in /usr/share/zoneinfo.  With
the attached patch, I get both the timezone location name (with
location=TRUE) and the abbreviated timezone (with location=FALSE).  One
thing I wonder about: is looking at just the first 200 bytes guaranteed
to be sufficient, or would it be better to use n=file.size() to examine
the whole file?

Steve Berman

-------------- next part --------------
A non-text attachment was scrubbed...
Name: datetime.R.diff
Type: text/x-patch
Size: 3890 bytes
Desc: not available
URL: <https://stat.ethz.ch/pipermail/r-devel/attachments/20171020/a393193c/attachment.bin>


[Rd] Another issue with Sys.timezone
Stephen Berman