Защита от случайного преобразования часового пояса - PullRequest
7 голосов
/ 05 октября 2011

В R у меня есть куча значений даты и времени, которые я измеряю в GMT.Я продолжаю сталкиваться с авариями, когда та или иная функция теряет часовой пояс моих значений или даже теряет имя класса.Даже на такие базовые функции, как c() и unlist():

> dput(x)
structure(1317830532, class = c("POSIXct", "POSIXt"), tzone = "GMT")
> dput(c(x))
structure(1317830532, class = c("POSIXct", "POSIXt"))
> dput(list(x))
list(structure(1317830532, class = c("POSIXct", "POSIXt"), tzone = "GMT"))
> dput(unlist(list(x)))
1317830532

Я чувствую, что у меня на волосок от настоящего Mars Climate Orbiter момента, если это произойдеткогда я меньше всего этого ожидаю.У кого-нибудь есть какие-либо стратегии для того, чтобы их даты оставались на месте?

Ответы [ 3 ]

6 голосов
/ 05 октября 2011

Это поведение задокументировано в ?c, ?DateTimeClasses и ?unlist:

С ?DateTimeClasses:

Использование c на объектах "POSIXlt" преобразует их в текущий часовой пояс, а на объектах "POSIXct" удаляются любые атрибуты "tzone" (даже если они все отмечены одним и тем же часовым поясом). ). *

С ?c:

c иногда используется для побочного эффекта удаления атрибутов, кроме имен. *


Тем не менее, мое тестирование показывает, что целостность ваших данных остается неизменной, несмотря на использование c или unlist. Например:

x <- structure(1317830532, class = c("POSIXct", "POSIXt"), 
                 tzone = "GMT")
y <- structure(1317830532+3600, class = c("POSIXct", "POSIXt"), 
                 tzone = "PST8PDT")
x
[1] "2011-10-05 16:02:12 GMT"

y
[1] "2011-10-05 10:02:12 PDT"

strftime(c(x, y), format="%Y/%m/%d %H:%M:%S", tz="GMT")
[1] "2011/10/05 16:02:12" "2011/10/05 17:02:12"

strftime(c(x, y), format="%Y/%m/%d %H:%M:%S", tz="PST8PDT")
[1] "2011/10/05 09:02:12" "2011/10/05 10:02:12"

strftime(unlist(y), format="%Y/%m/%d %H:%M:%S", tz="PST8PDT")
[1] "2011/10/05 10:02:12"

Ваш марсоход должен быть в порядке, если вы используете R для отслеживания дат.

4 голосов
/ 05 октября 2011

Почему бы тогда не установить часовой пояс GMT для сеансов R?Если что-то конвертируется в «текущий» часовой пояс, это все равно правильно.

2 голосов
/ 06 октября 2011

Учитывая, что это документированное поведение, и нужно либо избегать таких функций, либо защищаться от такого поведения, тогда вам нужны механизмы для поддержки любого из этих подходов.Для таких вещей я бы порекомендовал написать «пух бедного человека»;с таким детектором пуха вы можете восстановить здравый смысл. Кроме обнаружения пуха, существует несколько подходов к предотвращению сбоев Mars Polar Orbiter, некоторые из которых не зависят друг от друга, другие зависят:

  1. Установите политику и создайте альтернативы Во-первых, для всех функций, которые, как вы знаете, вызывают проблемы, либо решите, что вы их не используете, либо напишите новую функцию-оболочку, которая будет работать так, как задумано, и чтоустановит желаемый параметр часового пояса.Затем убедитесь, что вы используете эту специальную оболочку, а не базовую функцию.
  2. Статический анализ Напишите функцию поиска, используя ваш любимый редактор (например, как макрос), используя сценарий оболочки иФункции GNU find и grep или каким-либо другим способом (например, grep в R), чтобы найти те конкретные функции, которые вызывают у вас проблемы.Если найдено, удалите или используйте метод защитного кодирования (например, обертку в # 1).
  3. Тестирование Используя модульные тесты, например Runit или testthat, разработайте тесты, которые гарантируютчто свойства часового пояса поддерживаются при использовании ваших функций или пакета.Каждый раз, когда появляется новая ошибка, создайте новый тест, чтобы гарантировать, что ошибка не появится снова в выпущенных версиях.
  4. Слабая проверка типов Вы также можете включить в свой код тесты, которые проверяют,часовой пояс указан.Для этого теста лучше иметь собственную функцию, а не писать блок кода, который воспроизводится повсюду.Таким образом, вы можете в конечном итоге расширить проверку, включив в нее другие типы проверок, такие как сохранение часового пояса и тесты на предмет того, учитывают ли операции над двумя или более объектами различия в часовых поясах (возможно, они это разрешают, а могут и нет).).
  5. Отобразить все на один TZ Также известный как Индиана-будь проклятым .Сохранение различных политик в отношении часовых поясов - это тяжелая работа, и, по существу, это очень сложно при работе с временными данными.Просто сопоставьте с одним TZ (UTC), а затем пусть что-нибудь локальное сработает.Если у вас есть локальная закономерность, инвариантная к летнему времени, то обратитесь к ней после обратного преобразования из UTC.

Я делаю все # 1-4 для других проблем, но так же, как ониИх легко адаптировать к проверке часовых поясов, и они достаточно многократно используются для многих целей, избегающих полета на орбите.Я делаю такие вещи именно для того, чтобы избежать кодирования следующего такого орбитального аппарата Марса.(Это был дорогой урок для всех нас, кто работает с числовыми данными. :))

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...