8.1 Date

as.POSIXct(zoo::as.yearmon(seq(1960,2014)) + 11/12, frac = 1) generate yearly date (the end of year) sequence.

Sys.getlocale("LC_TIME") Check your locale. The locale describes aspects of the internationalization of a program. Initially most aspects of the locale of R are set to "C" (which is the default for the C language and reflects North-American usage – also known as "POSIX").

  • R uses the current “LC_TIME” locale when parsing or writing dates (see format.Date), to determine the appropriate words for the days of the weeks and the months.
  • Locale affects how R processes date time representations, e.g., languages.

Sys.setlocale(category = "LC_TIME", locale = "C") this set the time language to English. Same as Sys.setlocale(category = "LC_TIME", locale = "en_US.UTF-8").

  • locale = "" means set to the default locale for your system.

    • locale also accepts locales such as “en_US” (for the English-language locale in the Unites States) or “fr_FR” (for the French-language locale in France).
    • First two-letter lowercase stands for the language code (using the ISO-639 standard); followed by a two-letter uppercase country code (using the ISO-3166 standard).
    # examples
    Sys.setlocale("LC_TIME", "de")     # Solaris: details are OS-dependent
    Sys.setlocale("LC_TIME", "de_DE")  # Many Unix-alikes
    Sys.setlocale("LC_TIME", "de_DE.UTF-8")  # Linux, macOS, other Unix-alikes
    Sys.setlocale("LC_TIME", "de_DE.utf8")   # some Linux versions
    Sys.setlocale("LC_TIME", "German") # Windows

Every time you start a new R session, you get back to native setting. Should you want a permanent change, put

.First <- function() {
   Sys.setlocale("LC_TIME", "C")
   }

in the $(R RHOME)/etc/Rprofile.site file. Read ?Startup for how to customize R startup and the use of .First.

From string/numeric to date

lubridate::ymd(...), mdy(...), dmy(...): They automatically work out the format once you specify the order of the component. To use them, identify the order in which year, month, and day appear in your dates, then arrange “y”, “m”, and “d” in the same order.

  • ... a character or numeric vector of suspected dates
  • E.x.
ymd(20101215)
#> [1] "2010-12-15"
mdy("4/1/17")
#> [1] "2017-04-01"
dmy("31-Jan-2017")
#> [1] "2017-01-31"

# create year-month-01 date series from individual components columns in df
df$date <- with(df, ymd(sprintf('%04d%02d%02d', YR, MON, 1)))

Get year and month from date

lubridate::year(date)
lubridate::month(date)

From date to string

Convert date x to a string of your choosing format using base R:

  • format(x, format="%Y-%m-%d")
  • strftime(x, format="%Y-%m-%d")
  • From string to date, one can use strptime, but lubridate is more flexible.
  • Use ?strptime to check how to represent date components using strings, usually start with % and followed by a letter.

Format code list

This code list corresponds to user’s locale setting and platform. For instance, %b will return English if your language setting is English, return German is your language setting is German.

Specification Description
%d Day of the month: 01-31
%m 2 digits month: 01-12
%b Abbreviated month name in the current locale on this platform: Jan, Feb, …
%B Month’s name in full: January, February etc.
%y 2 digits year without century: 00-99
%Y 4 digits year. Year with century on input:
00 to 68 prefixed by 20; e.g., 2005
69 to 99 prefixed by 19; e.g., 1968

zoo.as.yearmon(x) to convert date to yearmon. This is useful when you want to join tables by year-month combination.

as.yearmon("mar07", "%b%y")
as.yearmon("2007-03-01")
as.yearmon("2007-12")

# year-quarter
> as.yearqtr("2019-01")
[1] "2019 Q1"

# returned Date is the fraction of the way through
# the period given by frac (= 0 by default)
as.Date(x)
as.Date(x, frac = 1)
as.POSIXct(x)

as.Date(x, frac=0)

  • frac specifies the fractional amount through the month to use so that
    • 0 is beginning of the month. The default value of frac is 0.
    • 1 is the end of the month.

Add one month to date

%m+% and %m-% add and subtract months to a date without exceeding the last day of the new month.

d <- ymd("2012-01-31")
[1] "2012-01-31 UTC"
d %m+% months(1) # `%m+%` avoid rollover
[1] "2012-02-29 UTC"
> d + months(1) # this is invalid as Feb doesn't have 31th day
[1] NA
> d %m+% months(-1)
[1] "2011-12-31"
> d %m-% months(1) # same as last code
[1] "2011-12-31"
> d %m+% years(1)
[1] "2013-01-31"
> d %m+% years(1:3)  # add a sequence
[1] "2013-01-31" "2014-01-31" "2015-01-31"
> d %m+% days(1:3)
[1] "2012-02-01" "2012-02-02" "2012-02-03"

A vector of dates

d <- ymd("2014-03-31")
d %m+% months(seq(3,30,3))
 [1] "2014-06-30" "2014-09-30" "2014-12-31" "2015-03-31" "2015-06-30"
 [6] "2015-09-30" "2015-12-31" "2016-03-31" "2016-06-30" "2016-09-30"

Initialize an empty vector of dates

# if you use d<-c(), this will create a numeric vector
# cannot concatenate afterwards
d <- lubridate::ymd()
c(d, ymd("2014-03-31"))