Use `dput` for POSIXct dates in r: why are they in a format like, e.g., 1070236800 instead of 2003-12-01?

I have the following array of POSIXct dates

>x
[1] "2003-12-01 UTC" "2003-12-02 UTC" "2003-12-03 UTC" "2003-12-04 UTC" "2003-12-05 UTC" "2003-12-08 UTC"

[7] "2003-12-09 UTC" "2003-12-10 UTC" "2003-12-11 UTC" "2003-12-12 UTC"

whose structure is:

str(x)
 POSIXct[1:10], format: "2003-12-01" "2003-12-02" "2003-12-03" "2003-12-04" "2003-12-05" "2003-12-08" "2003-12-09 ..."

Anyway, when I use dput, I obtain:

structure(c(1070236800, 1070323200, 1070409600, 1070496000, 1070582400, 
1070841600, 1070928000, 1071014400, 1071100800, 1071187200), class = c("POSIXct", 
"POSIXt"), tzone = "UTC")

>Solution :

POSIXct is stored as a numeric value representing the number of seconds since midnight on 1st January 1970 UTC. Note that if we write the same structure manually with the numeric value set to 0, we get:

structure(0, class = c("POSIXct", "POSIXt"), tzone = "UTC")
#> [1] "1970-01-01 UTC"

We can confirm that POSIXct is stored as a double precision floating point number

x <- Sys.time()

x
#> [1] "2022-11-08 11:33:36 GMT"

class(x)
#> [1] "POSIXct" "POSIXt" 

typeof(x)
#> [1] "double"

The reason why it is stored as a number is because we need to be able to work on date-times arithmetically. If we subtract numbers from a POSIXct object we are subtracting seconds:

x - 3600
#> [1] "2022-11-08 10:33:36 GMT"

If it were stored as a character string, than any time we wanted to perform calculations on date-times or plot them, we would have to parse the character strings into a numerical value, do the calculations, then rewrite the character strings. This is obviously much less efficient than having an underlying numerical representation that uses a special print method to represent the number as a date-time.

Leave a Reply