Plenty of real-world data are associates with instant in time and specific date such as companies reprt each quarter, stock markets report closing prices daily, or network analysts measuring traffic by the hour. Dealing with dates accurately can be complicated as on can encounter time-zone differences, leap years, and regional differences in holidays. Also, people report data differently in different places. For example, what an American would write as “May 12, 2010” or “05-12-10” would be written by someone in the United Kingdom as “12 May 2010” or “12-05-2010”. Similarly, time can be written as 9:25 p.m., 21:25, or 21h25, thus working with a time instant can be difficult (Meys and Vries 2015).
# Write the opening day of the 2016 Rio Olympic Games
xd <- as.Date("2016-08-05")
xd
## [1] "2016-08-05"
# Date structure
str(xd)
## Date[1:1], format: "2016-08-05"
# Find out what day of the week it is
weekdays(xd)
## [1] "Friday"
# Add numbers fro dates
xd + 7
## [1] "2016-08-12"
# Create vector of seven days starting on July 27
xd + 0:6
## [1] "2016-08-05" "2016-08-06" "2016-08-07" "2016-08-08" "2016-08-09"
## [6] "2016-08-10" "2016-08-11"
# Return days of the week for 0:6
weekdays(xd + 0:6)
## [1] "Friday" "Saturday" "Sunday" "Monday" "Tuesday" "Wednesday"
## [7] "Thursday"
# Use seq() to create sequences of dates
startDate <- as.Date("2016-01-01")
xm <- seq(startDate, by = "2 months", length.out = 12)
xm
## [1] "2016-01-01" "2016-03-01" "2016-05-01" "2016-07-01" "2016-09-01"
## [6] "2016-11-01" "2017-01-01" "2017-03-01" "2017-05-01" "2017-07-01"
## [11] "2017-09-01" "2017-11-01"
# Report on months
months(xm)
## [1] "January" "March" "May" "July" "September" "November"
## [7] "January" "March" "May" "July" "September" "November"
# Report on quarters
quarters(xm)
## [1] "Q1" "Q1" "Q2" "Q3" "Q3" "Q4" "Q1" "Q1" "Q2" "Q3" "Q3" "Q4"
# View locale setting of my machine
# Locale setting describes elements of international customization on a specificinstallation of R
Sys.localeconv()
## decimal_point thousands_sep grouping int_curr_symbol
## "." "" "" "USD"
## currency_symbol mon_decimal_point mon_thousands_sep mon_grouping
## "$" "." "," "\003"
## positive_sign negative_sign int_frac_digits frac_digits
## "" "-" "2" "2"
## p_cs_precedes p_sep_by_space n_cs_precedes n_sep_by_space
## "1" "0" "1" "0"
## p_sign_posn n_sign_posn
## "3" "0"
# Convert '5 Aug 2016' into a date
as.Date('5 Aug 2016', format = "%d %b %Y")
## [1] "2016-08-05"
# Convert with '5/08/2016' format
as.Date('5/08/2016', format = "%d/%m/%Y")
## [1] "2016-08-05"
# Table 6.2
library(tibble)
## Warning: package 'tibble' was built under R version 4.5.2
table1 <- tibble(
Format = c("%Y", "%y", "%m", "%B","%b", "%d", "%A", "%a", "%w"),
Description = c("Year with century.", "Year without century (00-99). Values 00 to 68 are prefixed vy 20, and values 69 to 99 are prefixed by 19.", "Months as decimal number (01-12).", "Full month name in the current locale.", "Abbreviated month name in the current locale.", "Day of the month as a decimal number (01-31)",
"Full weekday name in the current locale.", "Abbreviated weekday name in the current locale.", "Weekday as decimal number (0-6, with Sunday being 0)")
)
table1
## # A tibble: 9 × 2
## Format Description
## <chr> <chr>
## 1 %Y Year with century.
## 2 %y Year without century (00-99). Values 00 to 68 are prefixed vy 20, and …
## 3 %m Months as decimal number (01-12).
## 4 %B Full month name in the current locale.
## 5 %b Abbreviated month name in the current locale.
## 6 %d Day of the month as a decimal number (01-31)
## 7 %A Full weekday name in the current locale.
## 8 %a Abbreviated weekday name in the current locale.
## 9 %w Weekday as decimal number (0-6, with Sunday being 0)
# To specify time information, we use as.POSIXct() and as.POSIXlt()
# POSIXct() refers to a time that is internally stored as the number of seconds since the start of 1970
# POSIXlt() refers to a date stored as a named list of vectors for the year, month, day, hours, and minutes
# Example, the time of the Apollo 11 moon landing was July 20 1969 at 20:17:39 UTC or Coordinated Universal
# Time, and that's how the world's clocks are regulated
apollo <- "July 20, 1969, 20:17:39"
apollo.fmt <- "%B %d, %Y, %H:%M:%S"
xct <- as.POSIXct(apollo, format = apollo.fmt, tz = "UTC")
xct
## [1] "1969-07-20 20:17:39 UTC"
# Table 6.3
library(tibble)
table2 <- tibble(
Format = c("%H", "%I", "%M", "%S","%p"),
Description = c("Hours as a decimal number (00-23)", "Hours as a decimal number (01-12.)", "Minutes as a decimal number (00-59).", "Seconds as a decimal number (00-61).", "AM/PM indicator.")
)
table2
## # A tibble: 5 × 2
## Format Description
## <chr> <chr>
## 1 %H Hours as a decimal number (00-23)
## 2 %I Hours as a decimal number (01-12.)
## 3 %M Minutes as a decimal number (00-59).
## 4 %S Seconds as a decimal number (00-61).
## 5 %p AM/PM indicator.
# To format a date for pretty printing, we use format()
format(xct, "%d/%m/%y")
## [1] "20/07/69"
# Format the xct datetime as a sentence
format(xct, "%M minutes past %I %p, on %d %B %Y")
## [1] "17 minutes past 08 PM, on 20 July 1969"
# Add seven days to the Apollo landing scale (each day has 86400 seconds)
xct + 7*86400
## [1] "1969-07-27 20:17:39 UTC"
# Add 3 hours to the time of the Apollo moon landing
xct + 3*60*60
## [1] "1969-07-20 23:17:39 UTC"
There is a difference between Date objects and
POSIXct or POSIXlt objects. When using a
Date object, we add and subtract days; with
POSIXct and POSIXlt, the operations add or
subtract only seconds.
# Example: Convert xct to a Date object and subtract by 7 (will affect days)
as.Date(xct) - 7
## [1] "1969-07-13"
# Get current system time
Sys.time()
## [1] "2026-03-15 20:08:05 EDT"
# Compare current system time with the time of Apollo landing
Sys.time() < xct
## [1] FALSE
The moon landing happened more than 40 years ago, so it’s no surprise this statement is false.
Now, we will compare the start of several decades to the moon landing
date. Then, we will create a POSIXct object containing the
first day of 1950, and use the seq() function to create a sequence with
intervals of ten years.
dec.start <- as.POSIXct("1950-01-01")
dec <- seq(dec.start, by = "10 years", length.out = 4)
dec
## [1] "1950-01-01 EST" "1960-01-01 EST" "1970-01-01 EST" "1980-01-01 EST"
# Compare dec to with moon landing date
dec > xct
## [1] FALSE FALSE TRUE TRUE
N.B. - To achieve this, we use the POSIXlt class, as
this type of data is stored internally as a named list, which enables us
to extract components by name.
# Convert the Date class
xlt <- as.POSIXlt(xct)
xlt
## [1] "1969-07-20 20:17:39 UTC"
# Use $ operator to extract the different components
xlt$year
## [1] 69
# To get month
xlt$mon
## [1] 6
R considers July to be the sixth month of the year. POSIXlt
is based on an old Unix format, and that format starts to count from 0
instead of 1. So, January is 0 and July is 6.
# Internal structure of POSIXlt objects
unclass(xlt)
## $sec
## [1] 39
##
## $min
## [1] 17
##
## $hour
## [1] 20
##
## $mday
## [1] 20
##
## $mon
## [1] 6
##
## $year
## [1] 69
##
## $wday
## [1] 0
##
## $yday
## [1] 200
##
## $isdst
## [1] 0
##
## $zone
## [1] "UTC"
##
## $gmtoff
## [1] 0
##
## attr(,"tzone")
## [1] "UTC"
## attr(,"balanced")
## [1] TRUE