tags:

views:

128

answers:

4

I want to subtract 1 day from a POSIX date and end up at the same time around DST.

For example, when I add a day:

> as.POSIXct('2009-03-08 23:00:00.000') + 86400
[1] "2009-03-09 23:00:00 EDT"

But when I go past, it offsets:

> as.POSIXct('2009-03-08 23:00:00.000') - 86400
[1] "2009-03-07 22:00:00 EST"

What's the best way to deal with absolute time differences around DST? Usually I deal with this by converting the times into strings and dealing with them separately so that DST isn't applied.

+1  A: 

Store datetimes as UTC - or in this case convert to UTC subtract a day and convert back to local time. (This ignores leap seconds)

Mark
If I convert to UTC, subtract a day, and then convert back, I will end up with the same offset because DST is still applied in the conversion. Right?
Shane
Well depends on the acual dates if on the first day of DST then no otherwise yes.But think of all date times as UTC and only format into local time at the last moment
Mark
A: 

If you just want to count the days, you can use trunc to just move the day:

> trunc(Sys.time(), "day") + 86400
[1] "2009-09-13 PDT"
> trunc(Sys.time(), "day") - 86400
[1] "2009-09-11 PDT"
ayman
+1  A: 

Your code is doing exactly what you asked it to do, because you didn't ask it to add or subtract one day, you asked it to add or subtract 24 hours. 24 hours (86400 seconds) before 2009-03-08 23:00:00 EDT is 2009-03-07 22:00:00 EST. I'm not familiar with the R libraries, but I am familiar with the POSIX functions that they wrap. If you take a POSIXct, decrease its day property by 1, and then "re-cast" it to POSIXct via POSIXlt ( to ensure that e.g. February -1st becomes January 31st) then you should be able to subtract one day reliably.

hobbs
+1  A: 

Thanks hobbs! I need to do a little more work with it, but subtracting from the day slot works in POSIXlt:

> a <- as.POSIXct('2009-03-08 23:00:00.000')
> as.POSIXlt(a)
[1] "2009-03-08 23:00:00 EDT"
> a <- as.POSIXlt(a)
> a$mday <- a$mday -1
> a
[1] "2009-03-07 23:00:00 EDT"
Shane