Нечетные промежутки времени с использованием POSIXct

Возможно, рано утром 01.10.2017 я обнаружил любопытный пробел в течении времени. У меня есть хорошо зарекомендовавший себя код, который я часто использую для создания 30-минутных интервалов для суммирования и построения графиков наблюдений. Интервалы начинаются на закате и заканчиваются на рассвете, поэтому дата меняется в полночь. Почти для любой пары дат («ночи»), которую я хочу ввести, мой код работает нормально. Но для ночи 2017-09-30 он пропускает два интервала 02:00 и 02:30. Код ниже.

missing.times <- data.frame(isotime2=seq(as.POSIXct("2017-09-30 17:30:00", format="%Y-%m-%d %H:%M:%S"), as.POSIXct("2017-10-01 06:30:00", format="%Y-%m-%d %H:%M:%S"), by="30 min")); missing.times #missing 0200 and 0230

all.okay <- data.frame(isotime2=seq(as.POSIXct("2017-10-01 17:30:00", format="%Y-%m-%d %H:%M:%S"), as.POSIXct("2017-10-02 06:30:00", format="%Y-%m-%d %H:%M:%S"), by="30 min")); all.okay

Я попробовал хитрый обходной путь, но в конечном итоге я все равно создаю пробел.

#create intervals for the next date from midnight to 06:30
workaround <- data.frame(isotime2=seq(as.POSIXct("2017-10-02 00:00:00"), as.POSIXct("2017-10-02 06:30:00"), by="30 min")); workaround; str(workaround)

#substitute the following date for the time-gap date 2017-10-01
workaround$isotime2 <-gsub("2017-10-02", "2017-10-01", workaround$isotime2); workaround; str(workaround)

#change the vector "isotime2" from character to POSIXct magically makes time disappear
workaround$isotime2 <-as.POSIXct(workaround$isotime2, format="%Y-%m-%d %H:%M:%S"); workaround; str(workaround)

Я каким-то образом создал этот временной разрыв, или R что-то знает о складке пространства-времени? Я спал, когда это случилось.


person ptenax    schedule 19.12.2017    source источник
comment
Я предполагаю, что вы находитесь в Австралии. В этот день в Австралии часы перешли на летнее время.   -  person G5W    schedule 19.12.2017
comment
@ G5W спасибо, да, я в Австралии, и меня это интересовало, но я не указал часовой пояс в коде, и у нас есть штаты, которые меняются на летнее время, а другие нет. Возможно, R знает, что я нахожусь в состоянии перехода на летнее время. Мои данные поступают из штата, которого нет. Если я включу tz="Australia/Perth", это не исправит.   -  person ptenax    schedule 19.12.2017
comment
Посмотрите информацию о вашей локали из sessionInfo(). Это может повлиять на интерпретацию часовых поясов. Где именно вы поставили tz= и каков был результат, который вы получили, по сравнению с тем, что вы ожидали?   -  person MrFlick    schedule 19.12.2017
comment
Если вы не укажете часовой пояс, R угадает его за вас. Попробуйте Sys.time() и обратите внимание на tz, который вам назначает R. Это часовой пояс, который применяется к вашим данным о времени, если вы его не используете. tz = Australia/Perth не исправит это, потому что в этом часовом поясе указанное вами время на самом деле не существует (потому что вы теряете час). Если вы хотите, чтобы ваш график отображался без пропусков, вам нужно будет указать часовой пояс, который не меняется для перехода на летнее время.   -  person Nova    schedule 19.12.2017
comment
Спасибо, MrFlick (снова!), @Nova. Вы были правы: Sys.time() дает мне 2017-12-20 01:49:36 ACDT, где ACDT — это центральное летнее время Австралии (с переходом на летнее время). В Перте нет перехода на летнее время, поэтому там должно быть время.   -  person ptenax    schedule 19.12.2017
comment
@MrFlick Я использовал tz вот так: missing.times <- data.frame(isotime2=seq(as.POSIXct("2017-09-30 17:30:00", format="%Y-%m-%d %H:%M:%S"), as.POSIXct("2017-10-01 06:30:00", format="%Y-%m-%d %H:%M:%S", tz="Australia/Perth"), by="30 min")); missing.times #missing 0200 and 0230   -  person ptenax    schedule 19.12.2017
comment
Я не думаю, что вы можете иметь два часовых пояса в одном столбце.   -  person Nova    schedule 19.12.2017
comment
test <- as.POSIXct("2017-10-01 02:30:00", format="%Y-%m-%d %H:%M:%S", tz="Australia/Perth") работает, test <- as.POSIXct("2017-10-01 02:30:00", format="%Y-%m-%d %H:%M:%S", tz="Australia/ACT") не работает (тест будет равен NA во втором случае).   -  person Nova    schedule 19.12.2017
comment
Спасибо @Nova. Возможно, это хорошая демонстрация того, что tz="Australia/Perth" должно работать, если его вставить в исходный код.   -  person ptenax    schedule 19.12.2017


Ответы (1)


Потому что @ptenax так мило попросил...

Используйте часовой пояс, который не меняется при переходе на летнее время (скажем прямо, проклятие для всех при кодировании).

В первом data.frame используется Австралия/ACT tz, который меняется в 2 часа ночи, во втором data.frame используется Австралия/Перт tz, который не изменяется для перехода на летнее время.

missing.times <- data.frame(isotime2=seq(as.POSIXct("2017-09-30 17:30:00", format="%Y-%m-%d %H:%M:%S", tz="Australia/ACT"), as.POSIXct("2017-10-01 06:30:00", format="%Y-%m-%d %H:%M:%S", tz="Australia/ACT"), by="30 min"))
nrow(missing.times)
missing.times
# misses 2:00 and 2:30

missing.times <- data.frame(isotime2=seq(as.POSIXct("2017-09-30 17:30:00", format="%Y-%m-%d %H:%M:%S", tz="Australia/Perth"), as.POSIXct("2017-10-01 06:30:00", format="%Y-%m-%d %H:%M:%S", tz="Australia/Perth"), by="30 min"))
nrow(missing.times)
missing.times
# does not miss 2:00 and 2:30
person Nova    schedule 19.12.2017
comment
Большое спасибо @Nova. Я вставил параметр tz только один раз, а не дважды. Как глупо. Спасибо всем за уделенное время. - person ptenax; 19.12.2017
comment
Я так много боролся с часовыми поясами, что чувствую, что могу сделать все, чтобы другим было менее болезненно... :P - person Nova; 19.12.2017
comment
Спасибо. Я видел, что ранее вы также задавали вопрос о переходе на летнее время. - person ptenax; 19.12.2017