Reputation: 13070
Yet another date/time related question ;-)
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 ;-)
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.
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
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()
.
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"
country.this <- unlist(strsplit(loc$LC_TIME, split="_|\\."))[2]
> country.this
[1] "Germany"
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"
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"
Upvotes: 4
Views: 1847
Reputation: 121057
Some simplifications to your workflow.
You can retrieve just the time part of the locale using
Sys.getlocale("LC_TIME")
which avoids the neeed to split strings.
The lubridate package contains a function to retrieve Olson-style time zone names, so you don't have to worry about reading and parsing zone.tab
.
library(lubridate)
olson_time_zones()
Upvotes: 0
Reputation: 241475
Specifically regarding your 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?
No - there is not. This is because there are several countries that have multiple time zones. One cannot know the time zone from just the country alone.
This is why TZDB identifiers are in the form of Area/Location
, rather than just a list of country codes.
Upvotes: 2