Часовой пояс теряется с lubridate при создании нового компонента datetime из него - PullRequest
0 голосов
/ 18 февраля 2019

Следующий кадр данных взят из dput.Я использовал forced_tz в datatime без аргументов.Я живу в UTC + 1 часовой пояс.

library(lubridate)
library(dplyr)

df <- structure(list(value = structure(c(1514967058, 1515148132, 1517472989, 1543844646, 1525085884, 1520584330, 1522838681, 1540379051, 1516707360, 1516705706), 
                                 class = c("POSIXct", "POSIXt"))), 
          .Names = "value", 
          row.names = c(NA, -10L), 
          class = c("tbl_df", "tbl", "data.frame"))


    tz(df$value)
[1] ""

df2 <- df %>% 
  mutate(year=year(value))


    > tz(df2$year)
[1] "UTC"

Я также использовал tz= "Europe/Paris", но когда я извлекаю что-то из даты (day, month и т. Д.), Они теряют свой часовой пояс и снова получают UTC.Можно ли один раз установить часовой пояс, а затем перенести его на все новые компоненты datetime, которые я создаю?

1 Ответ

0 голосов
/ 18 февраля 2019

Проблема в том, что year(), кажется, возвращает numeric, поэтому он больше не является date объектом.

Это метод по умолчанию для year():

year.default <- function(x)
    as.POSIXlt(x, tz = tz(x))$year + 1900

Так, например:

y <- as.POSIXlt("2018-01-03 09:10:58 CET", tz = Sys.timezone())$year + 1900
#y
#[1] 2018

Обратите внимание, что я форсировал ток tz с помощью Sys.timezone().

Но:

class(y)
#[1] "numeric"

Таким образом, когда вы звоните tz(y), поскольку он числовой, он не имеет атрибута tz, и по умолчанию ему присваивается "UTC".

# example:
# tz(123)
# [1] "UTC"

Простое решениеэто установить себе часовой пояс:

attr(y, "tzone") <- Sys.timezone()
y
#[1] 2018
#attr(,"tzone")
#[1] "Europe/Berlin"

Так что теперь tz работает:

tz(y)
[1] "Europe/Berlin"

Я бы посоветовал против этого, но вы также можете изменить метод по умолчанию: tz () :

my_tz <- function(x) {
  tzone <- attr(x, "tzone")[[1]]
  if (is.null(tzone) && !is.POSIXt(x))
    return(Sys.timezone()) # original was "UTC"
  if (is.character(tzone) && nzchar(tzone))
    return(tzone)
  tzone <- attr(as.POSIXlt(x[1]), "tzone")[[1]]
  if (is.null(tzone))
    return(Sys.timezone()) # original was "UTC"
  tzone
}

my_tz(y)
#[1] "Europe/Berlin"

Итак, теперь у вас есть «пользовательская» версия tz(), которая возвращает текущий часовой пояс всякий раз, когда введенные данные имеют неправильный формат даты.

...