Dates are represented by the Date class and can be
coerced from a character string using the as.Date()
function. This is a common way to end up with a Date object
in R.
## Coerce a 'Date' object from character
x <- as.Date("1970-01-01")
x
## [1] "1970-01-01"
You can see the internal representation of a Date object
by using the unclass() function.
unclass(x)
## [1] 0
unclass(as.Date("1970-01-02"))
## [1] 1
unclass(as.Date("1969-12-31"))
## [1] -1
unclass(as.Date("1945-10-10"))
## [1] -8849
Sys.Date()
## [1] "2022-11-12"
unclass(Sys.Date())
## [1] 19308
as.Date("2004-12-31") - as.Date("2003-12-31")
## Time difference of 366 days
as.Date("1900-12-31") - as.Date("1899-12-31")
## Time difference of 365 days
as.Date("2100-12-31") - as.Date("2099-12-31")
## Time difference of 365 days
Times are represented by the POSIXct or the
POSIXlt class.
POSIXct is just a very large integer under the hood.
POSIXlt is a list underneath and it stores a bunch of
other useful information like the day of the week, day of the year,
month, day of the month.
There are a number of generic functions that work on dates and times to help you extract pieces of dates and/or times.
weekdays: give the day of the weekmonths: give the month namequarters: give the quarter number (“Q1”, “Q2”, “Q3”, or
“Q4”)Times can be coerced from a character string using the
as.POSIXlt or as.POSIXct function.
x <- Sys.time()
x
## [1] "2022-11-12 11:07:43 +08"
Website:
knitr::kable(OlsonNames())
x <- Sys.time()
x
## [1] "2022-11-12 11:07:43 +08"
class(x)
## [1] "POSIXct" "POSIXt"
The POSIXlt object contains some useful metadata.
p <- as.POSIXlt(x)
names(unclass(p))
## [1] "sec" "min" "hour" "mday" "mon" "year" "wday" "yday"
## [9] "isdst" "zone" "gmtoff"
## day of the week
p$wday
## [1] 6
## day of the year
p$yday
## [1] 315
You can also use the POSIXct format.
# 1 minute past midnight in GMT of January 1, 1970
x1 <- as.POSIXct("1970-01-01 00:01:00", tz = "GMT")
x1
## [1] "1970-01-01 00:01:00 GMT"
unclass(x1)
## [1] 60
## attr(,"tzone")
## [1] "GMT"
# Philippine time zone is 8 hours ahead of GMT (Greenwich Mean Time) or UTC
x2 <- as.POSIXct("1970-01-01 08:00:00", tz = "Asia/Manila")
x2
## [1] "1970-01-01 08:00:00 PST"
unclass(x2)
## [1] 0
## attr(,"tzone")
## [1] "Asia/Manila"
p2 <- as.POSIXlt(x2)
p2$hour
## [1] 8
Finally, there is the strptime() function in case your
dates are written in a different format. strptime() takes a
character vector that has dates and times and converts them into to a
POSIXlt object.
datestring <- c("January 10, 2012 10:40",
"December 9, 2011 9:10",
"October 10, 2022 9:30")
datestring
## [1] "January 10, 2012 10:40" "December 9, 2011 9:10" "October 10, 2022 9:30"
z <- strptime(datestring, "%B %d, %Y %H:%M", tz = "Asia/Manila")
z
## [1] "2012-01-10 10:40:00 PST" "2011-12-09 09:10:00 PST"
## [3] "2022-10-10 09:30:00 PST"
The weird-looking symbols that start with the %
symbol are the formatting strings for dates and times.
Check ?strptime for details. It’s probably not worth
memorizing this stuff.
You can use mathematical operations on dates and times. Well, really
just + and -.
You can do comparisons too (i.e. ==,
<=)
x <- as.POSIXlt("2022-01-01")
y <- strptime("10 Oct 2022 09:30:00", "%d %b %Y %H:%M:%S")
y - x
## Time difference of 282.3958 days
9/24 + 30/(24*60)
## [1] 0.3958333
he nice thing about the date/time classes is that they keep track of all the annoying things about dates and times, like leap years, leap seconds, daylight savings, and time zones.
Here’s an example where a leap year gets involved.
x <- as.Date("2012-03-01")
y <- as.Date("2012-02-28")
x-y
## Time difference of 2 days
## 2022 is not a leap year
as.Date("2022-12-31") - as.Date("2022-01-01")
## Time difference of 364 days
## 2020 is a leap year
as.Date("2020-12-31") - as.Date("2020-01-01")
## Time difference of 365 days
## 2100 is not a leap year
as.Date("2100-12-31") - as.Date("2100-01-01")
## Time difference of 364 days
## 1900 is not a leap year
as.Date("1900-12-31") - as.Date("1900-01-01")
## Time difference of 364 days
Here’s an example where two different time zones are in play (unless you live in GMT timezone, in which case they will be the same!).
## My local time zone
x <- as.POSIXct("2022-10-10 12:30:00")
y <- as.POSIXct("2022-10-10 12:30:00", tz = "GMT") #knowing the time difference, different time zones
y-x
## Time difference of 8 hours