Working with Date and Time

In R, the package lubridate handles date and times.

Basic Functions

Current Date/Time

Current time:

SELECT NOW();
Table 1: 1 records
now
2020-03-23 00:13:29

Current date:

today()
## [1] "2020-03-23"
as_date(now())
## [1] "2020-03-23"
SELECT current_time;
Table 2: 1 records
current_time
00:13:29.623558
SELECT NOW()::DATE;
Table 3: 1 records
now
2020-03-23

Addition and Subtraction

In R, durations are always stored in seconds. This can lead to unexpected results:

ymd(20000101) + dyears(1)
## [1] "2000-12-31"

More often periods are used:

ymd(20000101) + years(1)
## [1] "2001-01-01"
ymd(20000101) + period(year=1, month=1, day=1, hour=1, minute=5, second=15)
## [1] "2001-02-02 01:05:15 UTC"

In SQL, the behaviour is similar to R’s periods:

SELECT DATE '2000-01-01' + INTERVAL '1 YEAR 1 MONTH 1 DAY 1 HOUR 5 MINUTE 15 SECOND' AS new_date;
Table 4: 1 records
new_date
2001-02-02 01:05:15

Note that this is a datetime. To cast it to date:

SELECT (DATE '2000-01-01' + INTERVAL '1 YEAR')::DATE;
Table 5: 1 records
date
2001-01-01

Time difference (Period/Interval)

span <- ymd(20000101) %--% ymd(20010101)
span
## [1] 2000-01-01 UTC--2001-01-01 UTC
as.period(span)
## [1] "1y 0m 0d 0H 0M 0S"
span / ddays(1)
## [1] 366

This is similar to direct subtraction in

SELECT DATE '2001-01-01' - DATE '2000-01-01' AS span
Table 6: 1 records
span
366

The AGE function in PostgreSQL is similar to the %--% operator followed by as.period in lubridate.

SELECT AGE(DATE '2001-01-01', DATE '2000-01-01') AS span
Table 7: 1 records
span
1 year

Extracting Components

In lubridate, you use functions such as year and month on date/datetime to extract components. In PostgreSQL, you use the EXTRACT function with this pattern: EXTRACT(${COMPONENT} FROM date) where ${COMPONENT} can be one of those listed in the following table:

lubridate PostgreSQL Note
year YEAR
month MONTH
day or mday DAY day of month
wday DOW day of week
yday DOY day of year
- CENTURY
hour, minute, second HOUR, MINUTE, SECOND
- MILLISECOND
month(now())
## [1] 3
SELECT EXTRACT(MILLISECOND FROM NOW());
Table 8: 1 records
date_part
30124.907

In PostgreSQL, DOW (day of week) starts from Sunday.