I am trying to find out if it is possible to save the date time zone into a file in R. Lets create a date/time variable set to EST time.
x <- as.POSIXct("2015-06-01 12:00:00", tz = "EST")
x
#> [1] "2015-06-01 12:00:00 EST"
lubridate::tz(x)
#> [1] "EST"
tmpfile <- tempfile()
I will save this date information (which is in EST time) using base R,
readr
and data.table
to see how the information is preserved.
Base R version
The date gets converted to UTC and the time is not changed.
write.csv(data.frame(x = x), tmpfile)
df <- read.csv(tmpfile)
df
#> X x
#> 1 1 2015-06-01 12:00:00
lubridate::tz(df$x)
#> [1] "UTC"
tibble/readr version
It gets converted to UTC and the time is formatted as UTC as described in the help. Time is now 17:00:00.
… POSIXct values are formatted as ISO8601 with a UTC timezone Note: POSIXct objects in local or non-UTC timezones will be converted to UTC before writing.
readr::write_csv(tibble::tibble(x = x), tmpfile)
df <- readr::read_csv(tmpfile)
#> Rows: 1 Columns: 1
#> ── Column specification ────────────────────────────────────────────────────────
#> Delimiter: ","
#> dttm (1): x
#>
#> ℹ Use `spec()` to retrieve the full column specification for this data.
#> ℹ Specify the column types or set `show_col_types = FALSE` to quiet this message.
df
#> # A tibble: 1 × 1
#> x
#> <dttm>
#> 1 2015-06-01 17:00:00
lubridate::tz(df$x)
#> [1] "UTC"
data.table version
The date gets converted to UTC and the time is formatted as UTC as described in the help. Time is now also 17:00:00.
data.table::fwrite(data.table::data.table(x = x), tmpfile)
df <- data.table::fread(tmpfile)
df
#> x
#> 1: 2015-06-01 17:00:00
lubridate::tz(df$x)
#> [1] "UTC"
Is it possible to preserve the time zone when saving a file? If the user is not paying attention, this can go silently and create issues.
Created on 2022-03-14 by the reprex package (v2.0.1)
CodePudding user response:
Saving to an .RDS
is often the best choice to preserve an object exactly as it’s represented in R. In this case, it preserves timezone without conversion:
saveRDS(data.frame(x = x), tmpfile)
df <- readRDS(tmpfile)
df
# x
# 1 2015-06-01 12:00:00
lubridate::tz(df$x)
# [1] "EST"
df$x
# [1] "2015-06-01 12:00:00 EST"
CodePudding user response:
You could simply paste the time zone on to the end of the datetime string.
x <- as.POSIXct("2015-06-01 12:00:00", tz = "EST")
df <- data.frame(x = paste(as.character(x), lubridate::tz(x)))
tmpfile <- tempfile()
write.csv(df, tmpfile, row.names = FALSE)
new_df <- read.csv(text = csv)
new_df
#> x
#> 1 2015-06-01 12:00:00 EST
as.POSIXct(new_df$x, strsplit(new_df$x, ' ')[[1]][3])
#> [1] "2015-06-01 12:00:00 EST"