Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Determine and set timezone in POSIXct, POSIXlt, strptime, etc. in R

Tags:

datetime

r

t.ct = as.POSIXct("2009-01-05 14:19 +1200", format="%Y-%m-%d %H:%M %z")
t.lt = as.POSIXlt("2009-01-05 14:19 +1200", format="%Y-%m-%d %H:%M %z")
t.st =   strptime("2009-01-05 14:19 +1200", format="%Y-%m-%d %H:%M %z")

These seem to be the same times:

> t.ct -t.lt
Time difference of 0 secs
> t.ct -t.st
Time difference of 0 secs
> str(t.ct)
 POSIXct[1:1], format: "2009-01-04 21:19:00"
> str(t.lt)
 POSIXlt[1:1], format: "2009-01-04 21:19:00"
> str(t.st)
 POSIXlt[1:1], format: "2009-01-04 21:19:00"
> 

But these appear to have different timezone information in them, and it is not what I'd expect:

>     strftime(t.ct,"%Y-%m-%d %H:%M:%S %z")
[1] "2009-01-04 21:19:00 -0500"
>     strftime(t.lt,"%Y-%m-%d %H:%M:%S %z")
[1] "2009-01-04 21:19:00 +1200"
>     strftime(t.st,"%Y-%m-%d %H:%M:%S %z")
[1] "2009-01-04 21:19:00 +1200"
> 

The timezone on my Mac is:

> Sys.timezone()
[1] "America/New_York"

The questions Difference between as.POSIXct/as.POSIXlt and strptime for converting character vectors to POSIXct/POSIXlt and as.POSIXlt ignores tz argument seemed related, but didn't clarify this for me.

How do I definitively set a time and use it?

Update:

From user3293236's answer below, it seems one should always declare the timezone of the string, and if you are parsing the '-hhmm' offset, then always use tz="UTC":

t.ct = as.POSIXct("2009-01-05 14:19 +1200", format="%Y-%m-%d %H:%M %z", tz="UTC")
t.lt = as.POSIXlt("2009-01-05 14:19 +1200", format="%Y-%m-%d %H:%M %z", tz="UTC")
t.st =   strptime("2009-01-05 14:19 +1200", format="%Y-%m-%d %H:%M %z", tz="UTC")
like image 380
Dave X Avatar asked Jun 07 '16 20:06

Dave X


People also ask

How do you set the time zone in R?

It should be possible to set the time zone via the environment variable TZ: see the section on 'Time zone names' for suitable values. Sys. timezone() will return the value of TZ if set (and on some OSes it is always set), otherwise it will try to retrieve a value which if set for TZ would give the current time zone.

What is the difference between POSIXct and POSIXlt and as date?

There are two POSIX date/time classes, which differ in the way that the values are stored internally. The POSIXct class stores date/time values as the number of seconds since January 1, 1970, while the POSIXlt class stores them as a list with elements for second, minute, hour, day, month, and year, among others.

What is POSIXct format in R?

POSIXct stores date and time in seconds with the number of seconds beginning at 1 January 1970. Negative numbers are used to store dates prior to 1970. Thus, the POSIXct format stores each date and time a single value in units of seconds. Storing the data this way, optimizes use in data.

What is Strptime R?

strptime converts character vectors to class "POSIXlt" : its input x is first converted by as. character . Each input string is processed as far as necessary for the format specified: any trailing characters are ignored. strftime is a wrapper for format.


1 Answers

If you do not use a timezone specifically, POSIXct and POSIXlt will reference to your local timezone. However, this is not entirely reliable. POSIXlt will not display the timezone in the output string.

Note, the tzone argument is not set.

t.ct <- as.POSIXct("2009-01-05 14:19 +1200", format="%Y-%m-%d %H:%M %z")
t.lt <- as.POSIXlt("2009-01-05 14:19 +1200", format="%Y-%m-%d %H:%M %z")
t.ct
t.lt
attr(t.ct,"tzone") #""
attr(t.lt,"tzone") #NULL

If you do want to avoid ambiguous behaviour, you have to specifiy a time zone. The output string will still be different (by default POSIXlt shows no timezone), but the attribute is the same

t.ct <- as.POSIXct("2009-01-05 14:19 +1200", format="%Y-%m-%d %H:%M %z", tz="Europe/Helsinki")
t.lt <- as.POSIXlt("2009-01-05 14:19 +1200", format="%Y-%m-%d %H:%M %z", tz="Europe/Helsinki")
t.ct
t.lt
attr(t.ct,"tzone") #Europe/Helsinki
attr(t.lt,"tzone") #Europe/Helsinki

Now, if you want to change time zones after the original assignment:

attr(t.ct, "tzone") <- "UTC" #this will SHIFT the time zone to UTC
attr(t.lt, "tzone") <- "UTC" #this will REPLACE the time zone to UTC
t.ct
t.lt

As for your problem with strftime and %z, this does not give you the time zone attribute. The difference in your case, probably comes from a combination of string formatting, object conversions and time zone formating, IMO. But maybe somebody more knowledgable, can clarify this.

like image 50
Buggy Avatar answered Sep 20 '22 00:09

Buggy