Last active
October 14, 2015 00:18
-
-
Save mattbaggott/4278541 to your computer and use it in GitHub Desktop.
Short demo on successfully working with timezones in R
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
## | |
## Sample code to teach about timezones in R | |
## [email protected] | |
## Dec 13, 2012 | |
## Time zones are important to understand when working with dates | |
## because the most common date class for R, POSIX, is actually a date/time | |
## class. (POSIX = "Portable Operating System Interface, | |
## an IEEE standard) | |
## | |
## Key points: | |
## | |
## POSIX dates without times are considered midnight. | |
## POSIX dates without timezones are considered local timezone. | |
## Some Unix-like systems (especially Linux ones) do not have environment | |
## variable TZ set and you need to set it | |
## Base R contains POSIXct, POSIXlt, and Date classes. | |
## -ct is a numeric vector | |
## -lt is a named list | |
## Date is a numeric vector, intended to be integers - this is not enforced | |
## Time zone names depend on your OS and giving an illegal TZ name will | |
## sometimes fail silently (i.e., it will use "UTC") | |
## While there is no safe universal TZ name list and we should minimize TZ names in | |
## code, "Country/City" list below is widely used (including in R in Windows): | |
## http://en.wikipedia.org/wiki/List_of_tz_database_time_zones | |
######################################### | |
## Getting basic information from system | |
## empty time zone and wrong dates and times can cause huge headaches | |
# get your time zone | |
Sys.timezone() | |
# if you lack one, you can Sys.setenv(TZ="America/Chicago") or whatever | |
# get current date + time | |
Sys.time() | |
# get current day in the current timezone | |
Sys.Date() | |
# get many details about current locale | |
Sys.getlocale() | |
######################################### | |
## Is time zone explicitly stored with time? (Answer: not necessarily) | |
## If not, what happens? Let's find out. (Answer: local one is used) | |
# Let's create a time 10 seconds after 1960-01-01 00:00:00 GMT | |
# (the origin used by SAS; "GMT" is Greenwich Mean Time ) | |
t <- as.POSIXct(10, origin="1960-01-01", tz="GMT") # tzone IS given | |
attributes(t) # Yes explicit tzone | |
t <- as.POSIXct(10, origin="1960-01-01") # note tzone NOT given | |
attributes(t) # No explicit tzone, is assuming Sys.timezone() | |
# and you can see from ?as.POSIXct that the default for tz="" is local time | |
######################################### | |
## POSIXct, stores seconds since origin | |
## vs | |
## POSIXlt, stores list | |
## vs | |
## Date | |
# we have been making objects of class "POSIXct" "POSIXt" | |
class(t) | |
# ct, as before | |
t <- as.POSIXct(10, origin="1960-01-01", tz="GMT") | |
attributes(t) # tzone and class, as before | |
# lt | |
t <- as.POSIXlt(10, origin="1960-01-01", tz="GMT") | |
attributes(t) # list of names and tzone and class | |
# Sys.time() will provide explicit tzone to lt but not ct | |
(now <- as.POSIXlt(Sys.time())) # current datetime, note POSIX- lt not ct | |
attributes(now) # Yes, contains attribute tzone | |
(now <- as.POSIXct(Sys.time())) # current datetime, note POSIX- lt not ct | |
attributes(now) # No attribute tzone | |
# We can include time in origin | |
(t <- as.POSIXct(10, origin="1960-01-01 10:00:00")) | |
# Dates without times are treated as being at midnight | |
(t <- as.POSIXct("1970-01-01", origin="1960-01-01")) | |
(t - 1) # subtract a second, changes date | |
# this means timezone errors can easily change dates! | |
# If you don't need time, may be safer to use Date objects instead of POSIX | |
(t <- as.Date("1970-01-01", origin="1960-01-01")) # save as Date | |
class(t) # now class is Date, no time headaches | |
attributes(t) # only class | |
######################################### | |
## What time zone names should I use? (as few as possible) | |
## | |
## http://en.wikipedia.org/wiki/List_of_tz_database_time_zones | |
# Because TZ is handled by the system, not R, no one can guarantee a given | |
# tz name will work, but Olson's list of Location/Country strings usually | |
# works. http://en.wikipedia.org/wiki/List_of_tz_database_time_zones | |
# A common recommendation is to store as UTC (Universal Time, Coordinated) | |
# which you might call physical time, and convert to | |
# user/local/civil time as needed, but this is not always appropriate | |
# for human generated data. | |
# Differences btwn "Greenwich Mean Time" and "Universal Time, Coordinated" | |
# can usually be ignored | |
######################################### | |
## Conversions | |
## | |
## When it is time t here, what time is it there? | |
# If your input has tz info, use POSIXlt | |
t <- Sys.time() #here | |
as.POSIXlt(t, tz = 'America/Barbados') #there | |
# You must use lt for this as as.POSIXct will use tz info from Sys.time() | |
#or for a succinct ct representation | |
as.POSIXct(as.POSIXlt(t, tz = 'America/Barbados')) | |
# You can also format it as a string with that tz | |
(y <- format(t, tz="America/Barbados", usetz=TRUE)) | |
class(y) | |
######################################### | |
## Additional notes | |
## | |
## my next demo shows how to make circular 24-hour plots | |
## https://gist.github.com/4361381 | |
## for more on timezones see these helpful resources | |
## http://blog.revolutionanalytics.com/2009/06/converting-time-zones.html | |
## http://stackoverflow.com/questions/2532729/daylight-saving-time-and-timezone-best-practices | |
## lubridate package is a user friendly way to work with time/date and | |
## generally fast (because it uses regular expressions) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment