Convert string to datatime object in r

Viewed 133

I have a list of strings times. I want to convert those strings to datetime object. I tried as.POSIXct and did not get expected outcomes. I want datetimes like this 00:30, 01:30 ect...

Is there any easy code for doing this?

> times
 [1] "00:30" "01:30" "02:30" "03:30" "04:30" "05:30" "06:30" "07:30" "08:30" "09:30" "10:30" "11:30" "12:30" "13:30" "14:30"
[16] "15:30" "16:30" "17:30" "18:30" "19:30" "20:30" "21:30" "22:30" "23:30"
> times <- as.POSIXct(times, format = '%H:%M')
 [1] "2020-03-11 00:30:00 CDT" "2020-03-11 01:30:00 CDT" "2020-03-11 02:30:00 CDT" "2020-03-11 03:30:00 CDT"
 [5] "2020-03-11 04:30:00 CDT" "2020-03-11 05:30:00 CDT" "2020-03-11 06:30:00 CDT" "2020-03-11 07:30:00 CDT"
 [9] "2020-03-11 08:30:00 CDT" "2020-03-11 09:30:00 CDT" "2020-03-11 10:30:00 CDT" "2020-03-11 11:30:00 CDT"
[13] "2020-03-11 12:30:00 CDT" "2020-03-11 13:30:00 CDT" "2020-03-11 14:30:00 CDT" "2020-03-11 15:30:00 CDT"
[17] "2020-03-11 16:30:00 CDT" "2020-03-11 17:30:00 CDT" "2020-03-11 18:30:00 CDT" "2020-03-11 19:30:00 CDT"
[21] "2020-03-11 20:30:00 CDT" "2020-03-11 21:30:00 CDT" "2020-03-11 22:30:00 CDT" "2020-03-11 23:30:00 CDT"



2 Answers

As previous comments and answers suggested, the POSIXct (i.e., datetime) class in R always stores dates along with times. If you convert from a character object with just times to that class, today's date is added by default (if you want another date, you could do, for example, this: as.POSIXct(paste("2020-01-01", times), format = "%Y-%m-%d %H:%M")).

However, this should almost never be a problem since you can use format(times, format = "%H:%M") or for ggplot2 scale_x_datetime to get just the times back. For plotting, this would look something like this:

times <- c("00:30", "01:30", "02:30", "03:30", "04:30", "05:30", "06:30", "07:30", "08:30", "09:30", "10:30", "11:30", "12:30", "13:30", "14:30",
           "15:30", "16:30", "17:30", "18:30", "19:30", "20:30", "21:30", "22:30", "23:30")

library(tidyverse)
df <- tibble(
  time_chr = times,
  time = as.POSIXct(times, format = "%H:%M"),
  value = rnorm(length(times))
)
df
#> # A tibble: 24 x 3
#>    time_chr time                 value
#>    <chr>    <dttm>               <dbl>
#>  1 00:30    2020-03-12 00:30:00  0.352
#>  2 01:30    2020-03-12 01:30:00 -0.547
#>  3 02:30    2020-03-12 02:30:00 -0.574
#>  4 03:30    2020-03-12 03:30:00  0.843
#>  5 04:30    2020-03-12 04:30:00  0.798
#>  6 05:30    2020-03-12 05:30:00 -0.620
#>  7 06:30    2020-03-12 06:30:00  0.213
#>  8 07:30    2020-03-12 07:30:00  1.21 
#>  9 08:30    2020-03-12 08:30:00  0.370
#> 10 09:30    2020-03-12 09:30:00  0.497
#> # … with 14 more rows

ggplot(df, aes(x = time, y = value)) +
  geom_line() +
  scale_x_datetime(date_labels = "%H:%M")

Created on 2020-03-12 by the reprex package (v0.3.0)

In base you can use as.difftime to convert a string to time object:

as.difftime(times, "%H:%M")
#Time differences in mins
# [1]   30   90  150  210  270  330  390  450  510  570  630  690  750  810  870
#[16]  930  990 1050 1110 1170 1230 1290 1350 1410

You can also use the hms package:

library(hms)
head(as_hms(paste0(times, ":00")))
#00:30:00
#01:30:00
#02:30:00
#03:30:00
#04:30:00
#05:30:00

or the lubridate package as already suggested by @jpmam1

library(lubridate)
hm(times)
# [1] "30M 0S"     "1H 30M 0S"  "2H 30M 0S"  "3H 30M 0S"  "4H 30M 0S" 
# [6] "5H 30M 0S"  "6H 30M 0S"  "7H 30M 0S"  "8H 30M 0S"  "9H 30M 0S" 
#[11] "10H 30M 0S" "11H 30M 0S" "12H 30M 0S" "13H 30M 0S" "14H 30M 0S"
#[16] "15H 30M 0S" "16H 30M 0S" "17H 30M 0S" "18H 30M 0S" "19H 30M 0S"
#[21] "20H 30M 0S" "21H 30M 0S" "22H 30M 0S" "23H 30M 0S"

as.POSIXct stores dates with your times. If you need it only for plotting that will cause no problem and use the answer from @JBGruber. Storing dates where there are no dates should be avoided or the dates should be set to values where it is clear that they are wrong.

head(as.POSIXct(paste("9999-1-1", times)))
#[1] "9999-01-01 00:30:00 CET" "9999-01-01 01:30:00 CET"
#[3] "9999-01-01 02:30:00 CET" "9999-01-01 03:30:00 CET"
#[5] "9999-01-01 04:30:00 CET" "9999-01-01 05:30:00 CET"
Related