Yet another date/time related question ;-)
Before you aim and shoot
Things are kind of messed up with a Germany + MS Windows + R combination as the following yields an invalid time zone:
> Sys.timezone()
[1] "MST"
Warning message:
In as.POSIXlt.POSIXct(Sys.time()) : unknown timezone 'MET-1MST'
That's definitely not R's fault, it's Windows. Hence the question in the first place ;-)
Question
Is there an easy/alternative and OS-independent way to query your current country via locale info and then look up the corresponding time zone (format "<country>/<city>"
, e.g. "Europe/Berlin"
for Germany)?
I should also add that I'd like the solution to be independent from internet resources such as stated in this post/answer.
The problem context
Suppose you don't know how to specify your time zone yet. You might have heard something about CET/CEST etc, but AFAIK that doesn't really get you anywhere when using base R functionality (at least being located in Germany ;-)).
You can get a list of available "<country>/<city>"
pairs from the /share/zoneinfo/zone.tab
file in your RHOME directory. Yet, in order to find the time zone corresponding to the current country you're in you need to know the ISO country code.
Of course we usually do for our native country, but let's suppose we don't (I'd like to end up with a generic approach). What do you do next?
Below is my "four-step" solution, but I'm not really happy with it because
- it relies on yet another contrib package (ISOcodes)
- I can't test if it works for other locales as I don't know what the info actually would look like if you're in India, Russia, Australia etc.
Anyone got a better idea? Also, It'd be great if some of you in countries other than Germany could run this through and post their locale info Sys.getlocale()
.
Step 1: get locale info
loc <- strsplit(unlist(strsplit(Sys.getlocale(), split=";")), split="=")
foo <- function(x) {
out <- list(x[2])
names(out) <- x[1]
out
}
loc <- sapply(loc, foo)
> loc
$LC_COLLATE
[1] "German_Germany.1252"
$LC_CTYPE
[1] "German_Germany.1252"
$LC_MONETARY
[1] "German_Germany.1252"
$LC_NUMERIC
[1] "C"
$LC_TIME
[1] "German_Germany.1252"
Step 2: get country name from locale info
country.this <- unlist(strsplit(loc$LC_TIME, split="_|\\."))[2]
> country.this
[1] "Germany"
Step 3: get ISO country code
Use country.this
to look up the associated country code in data set ISO_3166_1
of package ISOcodes
require("ISOcodes")
data("ISO_3166_1")
iso <- ISO_3166_1
idx <- which(iso$Name %in% country.this)
code <- iso[idx, "Alpha_2"]
> code
[1] "DE"
Step 4: get time zone
Use code
to look up the time zone in the data frame that can be derived from file RHOME/share/zoneinfo/zone.tab
path <- file.path(Sys.getenv("R_HOME"), "share/zoneinfo/zone.tab")
tzones <- read.delim(
path,
row.names=NULL,
header=FALSE,
col.names=c("country", "coords", "name", "comments"),
as.is=TRUE,
fill=TRUE,
comment.char = "#"
)
> tzones[which(tzones$country == code), "name"]
[4] "Europe/Berlin"