Как извлечь год, tz-преобразовать и получить миллисекундную часть из временной метки nanotime? - PullRequest
0 голосов
/ 21 мая 2019

Я использую удивительный пакет nanotime для хранения своих драгоценных временных меток. Учтите это:

    library(tibble)
    library(nanotime)

tibble(mytimestamp =  c(nanotime('2011-12-05 08:30:00.000',format ="%Y-%m-%d %H:%M:%E9S",  tz ="GMT"),
                        nanotime('2011-12-05 08:30:00.100',format ="%Y-%m-%d %H:%M:%E9S",  tz ="GMT"),
                        nanotime('2011-12-05 08:30:00.825',format ="%Y-%m-%d %H:%M:%E9S",  tz ="GMT"))) 
# A tibble: 3 x 1
  mytimestamp                        
  <S4: nanotime>                     
1 2011-12-05T08:30:00.000000000+00:00
2 2011-12-05T08:30:00.100000000+00:00
3 2011-12-05T08:30:00.825000000+00:00

Однако я не знаю, каков правильный синтаксис для

  • извлеките миллисекундную часть из моих временных отметок
  • округлить до ближайшей секунды (как lubridate::floor_date(., '1 seconds'))
  • преобразовать в другой часовой пояс (скажем, 'US/Eastern')

Должен ли я использовать другой пакет для этих вещей? Например, использование lubridate приведет к потере точности в миллисекундах (обратите внимание на .0999 вместо .100)

mydf %>% 
  mutate(lubritime = lubridate::as_datetime(mytimestamp))
# A tibble: 3 x 2
  mytimestamp                         lubritime                
  <S4: nanotime>                      <dttm>                   
1 2011-12-05T08:30:00.000000000+00:00 2011-12-05 08:30:00.00000
2 2011-12-05T08:30:00.100000000+00:00 2011-12-05 08:30:00.09999
3 2011-12-05T08:30:00.825000000+00:00 2011-12-05 08:30:00.82500

Аналогично, прямое преобразование в EST не допускается

> mydf %>% 
+   mutate(mytimestamp_EST = lubridate::with_tz(mytimestamp, 'US/Eastern'))
Error in UseMethod("reclass_date", orig) : 
  no applicable method for 'reclass_date' applied to an object of class "c('nanotime', 'integer64', 'oldClass')"

Спасибо!

1 Ответ

1 голос
/ 21 мая 2019

Я делаю все это с data.table, потому что известно, что data.table поддерживает базовый пакет bit64 и integer64 представление , которое необходимо здесь. Других контейнеров нет.

код

library(nanotime)
library(data.table)

DT <- data.table(ts =  c(nanotime('2011-12-05 08:30:00.000',format ="%Y-%m-%d %H:%M:%E9S",  tz ="GMT"),
                         nanotime('2011-12-05 08:30:00.700',format ="%Y-%m-%d %H:%M:%E9S",  tz ="GMT"),
                          nanotime('2011-12-05 08:30:00.825',format ="%Y-%m-%d %H:%M:%E9S",  tz ="GMT")))
DT[, pt := as.POSIXct(ts)]
DT[, millis := as.numeric(pt - trunc(pt)) * 1e3]

Результат

R> DT
                                    ts                      pt millis
1: 2011-12-05T08:30:00.000000000+00:00 2011-12-05 02:30:00.000      0
2: 2011-12-05T08:30:00.700000000+00:00 2011-12-05 02:30:00.700    700
3: 2011-12-05T08:30:00.825000000+00:00 2011-12-05 02:30:00.825    825
R> 

Сдвиги часовых поясов - это другая (и неправильно понятая) тема. Вы можете сделать это для POSIXct.

Обратите внимание, что все, что вы здесь сделали / попросили, это разрешение в миллисекундах. До сих пор нет необходимости в nanotime. Но то, что я показал, вы можете работать на наносекундах - я использую это каждый день с data.table.

...