Davide Rivola
Davide Rivola

Reputation: 253

Local time zone to UTC conversion: DST change happens at wrong time

I'm converting a 2013 timeserie in local time (Europe/Paris) with DST to UTC. I'm using the following code

oasi <- read.csv("oasi.csv", sep=";", skip=28, header=FALSE)
oasi$datetime <- as.POSIXct(oasi[,1], tz="Europe/Paris", format="%d.%m.%Y %H:%M:%S")
oasi$utc <- oasi$datetime
attr(oasi$utc, "tzone") <- "UTC"

When I print the DST change at 27/10/2013 at 02:00 I see the following strange behaviour

                 datetime                 utc
43063 2013-10-27 02:05:00 2013-10-27 00:05:00
43064 2013-10-27 02:15:00 2013-10-27 00:15:00
43065 2013-10-27 02:25:00 2013-10-27 00:25:00
43066 2013-10-27 02:35:00 2013-10-27 00:35:00
43067 2013-10-27 02:45:00 2013-10-27 01:45:00
43068 2013-10-27 02:55:00 2013-10-27 01:55:00
43069 2013-10-27 02:05:00 2013-10-27 00:05:00
43070 2013-10-27 02:15:00 2013-10-27 00:15:00
43071 2013-10-27 02:25:00 2013-10-27 00:25:00
43072 2013-10-27 02:35:00 2013-10-27 00:35:00
43073 2013-10-27 02:45:00 2013-10-27 01:45:00
43074 2013-10-27 02:55:00 2013-10-27 01:55:00
43075 2013-10-27 03:05:00 2013-10-27 02:05:00
43076 2013-10-27 03:15:00 2013-10-27 02:15:00
43077 2013-10-27 03:25:00 2013-10-27 02:25:00
43078 2013-10-27 03:35:00 2013-10-27 02:35:00
43079 2013-10-27 03:45:00 2013-10-27 02:45:00
43080 2013-10-27 03:55:00 2013-10-27 02:55:00

It seems the DST is applied between 02:35 and 02:45 and not at 03:00. This is very strange and I don't understand why it is happening.

dput output of local datetime for 02:35 and 02:45:

structure(c(1382834100, 1382838300), class = c("POSIXct", "POSIXt"), tzone = "Europe/Paris")

Could be an OS bug? I'm using Win7 64 Bit.

Upvotes: 1

Views: 290

Answers (2)

Davide Rivola
Davide Rivola

Reputation: 253

As suggested by @roland I tried to finds the DST changes, add the timezone info and eliminates the ambiguity from the initial CET dataset. This code seems to work fine for a one-year dataset.

oasi <- read.csv("oasi.csv", sep=";", skip=28, header=FALSE, stringsAsFactors=FALSE)
dst.index <- which(abs(difftime(as.POSIXct(oasi[,1], tz="UTC", format="%d.%m.%Y %H:%M:%S"),
                      as.POSIXct(c(oasi[1,1], head(oasi[,1],-1)), tz="UTC", format="%d.%m.%Y %H:%M:%S"),
                      units = "mins")) > 10)

oasi[1:dst.index[1],1] <- paste(oasi[1:dst.index[1],1], "+0100")
oasi[dst.index[1]:dst.index[2],1] <- paste(oasi[dst.index[1]:dst.index[2],1], "+0200")
oasi[-1:-dst.index[2],1] <- paste(oasi[-1:-dst.index[2],1], "+0100")

oasi$datetime <- as.POSIXct(oasi[,1], tz="Europe/Paris", usetz=true, format="%d.%m.%Y %H:%M:%S %z")

Upvotes: 0

Roland
Roland

Reputation: 132576

I can reproduce like this:

as.POSIXct(c("27.10.2013 02:35:00", "27.10.2013 02:45:00"), tz="Europe/Paris", format="%d.%m.%Y %H:%M:%S")
#[1] "2013-10-27 02:35:00 CEST" "2013-10-27 02:45:00 CET"

You should be aware that your input is ambiguous. The clock was switched one hour back, so this hour exists twice. I don't know how the time zone is chosen in this case. It seems to be somewhat arbitrary.

You need to add the timezone information to your input:

as.POSIXct(c("27.10.2013 02:35:00 +0100", "27.10.2013 02:45:00 +0100"), tz="Europe/Paris", format="%d.%m.%Y %H:%M:%S %z")
#[1] "2013-10-27 02:35:00 CET" "2013-10-27 02:45:00 CET"
as.POSIXct(c("27.10.2013 02:35:00 +0200", "27.10.2013 02:45:00 +0200"), tz="Europe/Paris", format="%d.%m.%Y %H:%M:%S %z")
#[1] "2013-10-27 02:35:00 CEST" "2013-10-27 02:45:00 CEST" 

Upvotes: 2

Related Questions