Преобразование даты и времени в отформатированную строку времени

Я не знаю, почему это не работает. Вот мой код:

> t <- hms("14:11:49")
> t
[1] "14H 11M 49S"
t <- t + minutes(3)
> format(t, format="%H:%M:%S")
[1] "14H 14M 49S"
# Expected output: "14:14:49"

Обновление:

В настоящее время я нашел это решение, но я надеюсь, что есть более элегантное:

t <- hms("14:11:49") # example period object
sprintf("%s:%s:%s", hour(t), minute(t), second(t))
#"14:11:49"

person biocyberman    schedule 04.09.2014    source источник


Ответы (3)


Не уверен, почему вам нужно преобразовать в hms и обратно в исходный формат строки. Возможно, вам нужна функция parse_date_time:

library(lubridate)
myTime <- "14:11:49"
hms(myTime)
#"14H 11M 49S"

POSIXct_myTime <- parse_date_time(myTime,"hms")
format(POSIXct_myTime, format="%H:%M:%S")
#"14:11:49"

EDIT: мы можем использовать paste:

t <- hms("14:11:49")
t
#[1] "14H 11M 49S"
t <- t + minutes(3)
t
#[1] "14H 14M 49S"

paste(hour(t),minute(t),second(t),sep=":")
#[1] "14:14:49"

Вывод эталона:

op <- microbenchmark(
  Use_paste=paste(hour(t),minute(t),second(t),sep=":"),
  Use_sprintf=sprintf("%s:%s:%s", hour(t), minute(t), second(t)),
  times=1000000L)
op

# Unit: microseconds
# expr    min     lq median     uq      max neval
# Use_paste 28.072 31.695 32.601 33.506 44253.42 1e+06
# Use_sprintf 29.582 33.807 34.412 35.619 44367.52 1e+0
person zx8754    schedule 04.09.2014
comment
Это кажется лучшей идеей. - person MrFlick; 04.09.2014
comment
Я считаю (параноидально), что строковый формат экономит несколько байтов для каждой записи при записи в текстовый файл. Однако ваше решение не делает того, чего я пытаюсь достичь. Эта строка chicken-egg проблема: POSIXct_myTime <- parse_date_time(myTime,"hms"). У меня нет myTime в строковом формате. Я читаю миллионы записей в формате %H:%M:%S, фильтрую их и хочу записать в точности тот же формат, что и при вводе. - person biocyberman; 05.09.2014
comment
... строковый формат сохраняет несколько байтов для каждой записи при записи в текстовый файл... - не уверен, что это правда... Кроме того, ... у меня нет myTime в строковом формате... - в вашем post вы передаете строку в hms - hms("14:11:49") - person zx8754; 05.09.2014
comment
Извините за путаницу. Я поставил строку hms("14:11:49") только для того, чтобы создать объект из временной строки. Мой рабочий процесс таков: чтение миллионов записей временной строки; используйте смазку, чтобы сделать некоторые вычисления; записать обратно в текстовый файл результат. Пожалуйста, проверьте начало моего обновленного вопроса - person biocyberman; 05.09.2014
comment
@biocyberman смотрите обновление с решением для вставки и результатами теста. - person zx8754; 05.09.2014
comment
Я забыл о функции paste в этом случае. Но я надеялся, что есть способ избежать вызова hour, minute и second. Моя мысль: пакет lubridate, очевидно, очень хорошо читает во многих входных форматах даты и времени, но не очень хорошо возвращает эти выходные данные. - person biocyberman; 05.09.2014
comment
К сожалению, решение paste печатает 04 как 4. Я добавил простой обходной путь, используя функцию format. - person shosaco; 27.02.2019

Проблема в том, что class(t) — это «Период», а функция format.Period() не имеет параметра для format=. Объект t не является стандартным объектом стиля POSIXt, который вы, возможно, привыкли использовать с format(). Так будут вести себя только функции format.POSIXct() и format.POSIXlt().

Так что, возможно, проще всего было бы определить вспомогательную функцию для превращения класса Period в POSIXct. Мы можем сделать это с помощью:

as.POSIXct.Period <- function(x, start=today()) {
    X<-as.interval(x, start); 
    [email protected]+X@start
}

Важно отметить, что POSIXct — это значение даты/времени, а не просто значение времени. Поэтому по умолчанию мы просто предполагаем, что оно началось сегодня в полночь. Но тогда мы можем использовать формат так, как вы хотели

format(as.POSIXct(t), format="%H:%M:%S")
# [1] "14:11:49"

Должен признать, что я не являюсь опытным пользователем lubridate, поэтому, возможно, я упустил из виду очевидную функцию, но кажется, что возможности форматирования lubridate классов в "красивые" форматы очень ограничены.

person MrFlick    schedule 04.09.2014
comment
Это решение работает, но требует дополнительного шага для преобразования времени в объект date_time. В любом случае, спасибо за упоминание функций format.POSIXct() и format.POSIXlt(). - person biocyberman; 05.09.2014
comment
Ну, ваш первоначальный вопрос был просто о том, что вы не знали, почему это не работает, он не просил решения чего-либо. Если бы это был не ваш настоящий вопрос, я бы постарался лучше сформулировать ваши вопросы в будущем. Я сделал преобразование только потому, что вы, кажется, действительно хотите использовать функцию format с синтаксисом "%H:%M:%S". - person MrFlick; 05.09.2014

Предлагаемое решение не печатает ведущие нули. Следующее решение кажется более элегантным:

> t <- hms("14:01:49") + minutes(3)
> sprintf("%s:%s:%s", hour(t), minute(t), second(t))
[1] "14:4:49" # looking weird
> format(Sys.Date() + t, "%H:%M:%S")
[1] "14:04:49" # looking better
person shosaco    schedule 27.02.2019