Working With Dates

Using lubridate and date.

Dates are tricky because they can be formatted differently, for example 03/01/1999 or 1-3-99, or March 1, 1999. Months and years also have different numbers of days making them hard to add or subtract. For example what is January 31 st plus 1 month?

To start with this will give todays date and time.

d1 <- date()
d1
## [1] "Tue May 26 18:13:37 2015"

The class of this date is just a character.

class(d1)
## [1] "character"

But things get more complicated

d2 <- Sys.Date()
d2
## [1] "2015-05-26"
class(d2)
## [1] "Date"

A date with a date class allows you to reformat the date into a variety of other formats

For example you can take the existing d2 and reformat it like below:

format(d2, "%a %b %d")
## [1] "Tue May 26"

Below is a table of possible date formats. For example adding %Y will add a year to the date. As you can see from the table, upper and lowercase letters are treated differently.


format(d2, "%a %b %d %Y")
## [1] "Tue May 26 2015"
format(d2, "%A %b %d %y")
## [1] "Tuesday May 26 15"


Table of date formats:
Conversion Spec Description Example
%a Abbreviated weekday Sun, Thu
%A Full weekday Sunday, Thursday
%b or %h Abbreviated month May, Jul
%B Full month May, July
%d Day of the month 01-31 27, 07
%j Day of the year 001-366 148, 188
%m Month 01-12 05, 07
%U Week 01-53 with Sunday as first day of the week 22, 27
%w Weekday 0-6 Sunday is 0 0, 4
%W Week 00-53 with Monday as first day of the week 21, 27
%x Date, locale-specific
%y Year without century 00-99 84, 05
%Y Year with century on input: 00 to 68 prefixed by 20 69 to 99 prefixed by 19 1984, 2005
%C Century 19, 20
%D Date formatted %m/%d/%y 05/27/84, 07/07/05
%u Weekday 1-7 Monday is 1 7, 4
%n Newline on output or Arbitrary whitespace on input
%t Tab on output or Arbitrary whitespace on input


Symbols can also be added between dates.

format(d2, "%A %m/%d/%y")
## [1] "Tuesday 05/26/15"


Creating Dates

You have to tell R that a date is a date and you have to tell it what date elements are in the character vector.

First create a character vector of dates.

x <- c("1jan1960", "2jan1960", "31mar1960", "30jul1960")
class(x)
## [1] "character"
z = as.Date(x, "%d%b%Y")
class(z)
## [1] "Date"
z
## [1] "1960-01-01" "1960-01-02" "1960-03-31" "1960-07-30"


And you can get a time difference from one date to the next.

z[2] - z[1]
## Time difference of 1 days


Julian Conversion

You can get the names of days or months by using the months or weekdays function.

months(d2)
## [1] "May"
weekdays(d2)
## [1] "Tuesday"

And you can get the number of days since the origin, in this case the origin is Jan 1, 1970, which it will tell you.

julian(d2)
## [1] 16581
## attr(,"origin")
## [1] "1970-01-01"


Lubridate

Lubridate makes things quite a bit easier. The function that you use with lubridate tells it what to look for. For example ymd tells it to look for a year then a month and then a day.

library(lubridate)
ymd(20140309)
## [1] "2014-03-09 UTC"
mdy("March 01, 2013")
## [1] "2013-03-01 UTC"


You can also add times.

ymd_hms("09-12-1 3-15-30")
## [1] "2009-12-01 03:15:30 UTC"

lubridate can also weed out unnecessary information and understand rather bizarrely formated dates.

ymd_hms("2009 arbitrary 1 non-decimal 6 chars 12 in between 1 !!! 6")
## [1] "2009-01-06 12:01:06 UTC"
ymd_hms("2009-1, 5 12:1, 5")
## [1] "2009-01-05 12:01:05 UTC"


And you can add timezone information. By default lubridate assumes GMT time.

dmy_hm("03-06-14 4-15", tz="Pacific/Auckland")
## [1] "2014-06-03 04:15:00 NZST"


To get the weekday in lubridate use wday.

wday(d2)
## [1] 3

This gives the day number. To get the day itself add label=TRUE

wday(d2, label=TRUE)
## [1] Tues
## Levels: Sun < Mon < Tues < Wed < Thurs < Fri < Sat



See more here

More about lubridate