I am reading a file that contains timestamps and a timezone specification. I would like to be able to detect if a given timezone on this file is recognized by R or not, and supply my own default in case it isn't.
However, it seems like as.POSIXct silently falls back to UTC if given an invalid timezone, with no error or warning I could catch and handle:
> as.POSIXct("1970-01-01", tz="blah")
[1] "1970-01-01 UTC"
What would be a 'proper' way in R to check if a given timezone is recognized or not?
help("time zones")
explains a lot of the issues with time zones in detail and is well worth the read.
Results will vary based on your OS, but example("time zones")
shows how you can read a zone.tab file if your OS has one.
tzfile <- "/usr/share/zoneinfo/zone.tab"
tzones <- read.delim(tzfile, row.names = NULL, header = FALSE,
col.names = c("country", "coords", "name", "comments"),
as.is = TRUE, fill = TRUE, comment.char = "#")
str(tzones$name)
#chr [1:415] "Europe/Andorra" "Asia/Dubai" "Asia/Kabul" "America/Antigua" "America/Anguilla" ...
NROW(tzones)
#[1] 415
head(tzones)
# country coords name comments
#1 AD +4230+00131 Europe/Andorra
#2 AE +2518+05518 Asia/Dubai
#3 AF +3431+06912 Asia/Kabul
#4 AG +1703-06148 America/Antigua
#5 AI +1812-06304 America/Anguilla
#6 AL +4120+01950 Europe/Tirane
You could use a timezone library which has knowledge of time zones. This is from the SVN version of RcppBDT:
R> tz <- new(bdtTz, "America/Chicago")
R> cat("tz object initialized as: ", format(tz), "\n")
tz object initialized as: America/Chicago
R> tzBAD <- new(bdtTz, "blah")
Error in new_CppObject_xp(fields$.module, fields$.pointer, ...) :
Unknown region supplied, no tz object created
R>
In general, time zone support is dependent on the operating system. So for a portable solution you need to supply a list of valid time zones from somewhere...
And for what it is worth, I am using the csv file from the Boost sources. A copy of that time zones file is eg here at github.
Just stumbled on this question since I was looking to figure out the same thing. Turned out using the following. Leaving this for anyone who might stumble on this question...
is.valid.timezone <- function(timezone) {
return(timezone %in% (OlsonNames()))
}
You can also use the Rmetrics
package timeDate
package to check for timezone.
require(timeDate)
timeDate("1970-01-01", zone = "Africa/Dakar")
## [1] [1970-01-01]
timeDate("1970-01-01", zone = "blah")
## Error in .formatFinCenterNum(unclass(ct), zone, type = "any2gmt") :
## 'blah' is not a valid FinCenter.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With