R Lesson 19: Fun With Dates & Times

Hello everybody,

It’s Michael, and today I thought I’d do an R lesson (which I haven’t done in almost 9 months). Today’s R lesson will be a little different, as it’s not an analysis. Rather, it’s a demo that shows what R can do beyond performing analyses-in today’s post, I’ll show you how to work with dates and times in R, as well as manipulate them with a handy little package called lubridate.

After installing the lubridate package, let’s start to play around with it. First, let’s create a date in three different formats:

Screen Shot 2020-04-26 at 11.48.34 AM

In this example, I displayed a date in three different formats (year-month-day, month-day-year, day-month-year). Notice how the different date formats use different separators. For instance, the year-month-day format doesn’t use separators while the month-day-year format uses dashes and the day-month-year format uses backslashes.

  • Keep in mind these separators aren’t necessary, and if you use other separators for certain formats (or no separators at all), that would be perfectly acceptable. Just don’t incorrectly place certain elements of the date (in other words, don’t place the year first if you’re using month-day-year formatting).

 

Ok, so creating dates is only the basics of what the lubridate package can do-and we haven’t even gotten to the fun parts yet. For instance, did you know you could include a time with your date?:

Screen Shot 2020-04-26 at 12.11.22 PM

In this example, I created the variable dateandtime, which contains today’s date (April 26, 2020) along with the time (12:10) using the mdy_hm function, which allows me to include the date (in month-day-year format) along with the time (only the hour and minute though).

  • You can also add an s to the mdy_hm function if you want to include seconds in the date-time object.
  • The time only works with 24-hour notation (more commonly known as “military time”), so trying to write something like “01:15 PM” wouldn’t work-unless you could figure out how to concatenate the “AM” or “PM” onto the end of the date-time object.
  • You could also change the formatting of the date in the date-time object, but remember to write the function according to the formatting you chose. For instance, if you chose to use year-month-day formatting, remember to write the function as ymd_hm (or ymd_hms if you choose to include  the seconds)

 

But wait, there more you can include in a date-time object! Yes, you can also include the time-zone in your date-time object. See, the date-time object defaults to UTC, or Coordinated Universal Time. For those that don’t know what Coordinated Universal Time is, it’s not a time zone, but rather a 24-hour time standard used to synchronize world clocks. In other words, it’s the base point for all other time zones in the world, as they are determined by their distance from the UTC. Also, keep in mind that while the UTC doesn’t adjust to daylight savings time clock changes, the difference between the UTC and the local time does change. For instance, the difference between the UTC and US Central Time Zone is 6 hours when daylight savings time isn’t in place (from the first Sunday in November to the second Sunday in March), but only 5 hours when daylight savings time is in place.

So, let’s see what happens when we add the time-zone to our date-time object:

Screen Shot 2020-04-26 at 1.07.10 PM

In this example, I added the US Central Time Zone to the date-time object (I chose Central Time since I am currently in Nashville, TN, which is in the Central Time Zone). The way to add the time-zone to a date-time object is to use the variable tz and set tz to US/(choose time zone). You can’t write the name of a city and expect R to recognize it (I know, since I tried to write US/Nashville and got an error from R).

  • I’m impressed that R knew the US is in Daylight Savings Time since the date-time object did have CDT (Central Daylight Time, as opposed to Central Standard Time) besides it. Then again, R probably looked at the date and time-zone and correctly assumed that the US is in Daylight Savings Time.

The next thing I want to show you is how to extract certain information in a date-time object. Here’s an example of that (using out dateandtime2 object):

Screen Shot 2020-04-27 at 9.49.17 PM

All in all, there are 10 functions to extract information from a date-time object. Here’s an explanation of each of them:

  • second-extracts the second from the date-time object. In this example, second is zero since I didn’t include any seconds in this date-time object.
  • minute-extracts the minute from the date-time object. In this example, minute is 5 since the time in dateandtime2 is 13:05
  • hour-extracts the hour from the date-time object. In this example, hour is 13.
  • day-extracts the day from the date-time object. Since the date I used is April 26, 2020, 26 is given as the day
  • wday-extracts the number of the weekday from the date-time object. Since lubridate assumes the week starts on Sunday (some calendars start the week on Monday), Sunday is wday 1, Monday is wday 2, and so on until you get to Saturday (wday 7).
  • yday-extracts what day of the year the date is. In simpler terms, April 26, 2020 is the 117th day of 2020, so 117 is displayed.
  • week-extracts what week of the year the date falls on. Since April 26, 2020 is the 17th week of 2020, 17 is be displayed.
  • month-extracts the numerical value of the month, which can range from 1 (January) to 12 (December). Since April is the 4th month of the year, 4 is displayed
  • year-extracts the year from the date, which is 2020 in this case
  • tz-extracts the timezone from the date-time object (provided you set a timezone). In this case, the tz is US/Central, which is the US’s Central Time Zone.

Next, Iet’s demonstrate how to convert a date-time object into a different time zone:

Screen Shot 2020-05-02 at 3.54.23 PM

This date-time object contains the date 05-02-2020 and the time 15:50 (which means 3:50PM). The tz is set to US/Central, which represents the US’s Central Time Zone (and my current city of Nashville, TN is in the Central Time Zone).

But what if I wanted to call some relatives in Bogota, Colombia?  What time would it be there? Well, the with_tz function can help with figuring out this question. Simply use you date-time object and the timezone you wish to convert to as the parameters for this function. When I tried to find out the time in Bogota, Colombia, it turns out that when it’s 3:50PM in Nashville, TN, it’s also 3:50PM in Bogota, Colombia. The -05 means it’s five hours behind UTC (likewise, a +05 would mean that it’s five hours ahead of UTC).

Now, if it’s 3:50PM in Nashville, TN, what time would it be in Paris, France? Using the with_tz function, we can see that it’s 10:50PM in Paris, France, meaning that Paris is 7 hours ahead of Nashville. The CEST stands for Central European Summer Time.

But how would you know which timezone to use? Here’s a nice little hack-type in OlsonNames() into the compiler and you will see the list of all possible time-zones that lubridate will accept:

[1] “Africa/Abidjan” “Africa/Accra” “Africa/Addis_Ababa” “Africa/Algiers”
[5] “Africa/Asmara” “Africa/Asmera” “Africa/Bamako” “Africa/Bangui”
[9] “Africa/Banjul” “Africa/Bissau” “Africa/Blantyre” “Africa/Brazzaville”
[13] “Africa/Bujumbura” “Africa/Cairo” “Africa/Casablanca” “Africa/Ceuta”
[17] “Africa/Conakry” “Africa/Dakar” “Africa/Dar_es_Salaam” “Africa/Djibouti”
[21] “Africa/Douala” “Africa/El_Aaiun” “Africa/Freetown” “Africa/Gaborone”
[25] “Africa/Harare” “Africa/Johannesburg” “Africa/Juba” “Africa/Kampala”
[29] “Africa/Khartoum” “Africa/Kigali” “Africa/Kinshasa” “Africa/Lagos”
[33] “Africa/Libreville” “Africa/Lome” “Africa/Luanda” “Africa/Lubumbashi”
[37] “Africa/Lusaka” “Africa/Malabo” “Africa/Maputo” “Africa/Maseru”
[41] “Africa/Mbabane” “Africa/Mogadishu” “Africa/Monrovia” “Africa/Nairobi”
[45] “Africa/Ndjamena” “Africa/Niamey” “Africa/Nouakchott” “Africa/Ouagadougou”
[49] “Africa/Porto-Novo” “Africa/Sao_Tome” “Africa/Timbuktu” “Africa/Tripoli”
[53] “Africa/Tunis” “Africa/Windhoek” “America/Adak” “America/Anchorage”
[57] “America/Anguilla” “America/Antigua” “America/Araguaina” “America/Argentina/Buenos_Aires”
[61] “America/Argentina/Catamarca” “America/Argentina/ComodRivadavia” “America/Argentina/Cordoba” “America/Argentina/Jujuy”
[65] “America/Argentina/La_Rioja” “America/Argentina/Mendoza” “America/Argentina/Rio_Gallegos” “America/Argentina/Salta”
[69] “America/Argentina/San_Juan” “America/Argentina/San_Luis” “America/Argentina/Tucuman” “America/Argentina/Ushuaia”
[73] “America/Aruba” “America/Asuncion” “America/Atikokan” “America/Atka”
[77] “America/Bahia” “America/Bahia_Banderas” “America/Barbados” “America/Belem”
[81] “America/Belize” “America/Blanc-Sablon” “America/Boa_Vista” “America/Bogota”
[85] “America/Boise” “America/Buenos_Aires” “America/Cambridge_Bay” “America/Campo_Grande”
[89] “America/Cancun” “America/Caracas” “America/Catamarca” “America/Cayenne”
[93] “America/Cayman” “America/Chicago” “America/Chihuahua” “America/Coral_Harbour”
[97] “America/Cordoba” “America/Costa_Rica” “America/Creston” “America/Cuiaba”
[101] “America/Curacao” “America/Danmarkshavn” “America/Dawson” “America/Dawson_Creek”
[105] “America/Denver” “America/Detroit” “America/Dominica” “America/Edmonton”
[109] “America/Eirunepe” “America/El_Salvador” “America/Ensenada” “America/Fort_Nelson”
[113] “America/Fort_Wayne” “America/Fortaleza” “America/Glace_Bay” “America/Godthab”
[117] “America/Goose_Bay” “America/Grand_Turk” “America/Grenada” “America/Guadeloupe”
[121] “America/Guatemala” “America/Guayaquil” “America/Guyana” “America/Halifax”
[125] “America/Havana” “America/Hermosillo” “America/Indiana/Indianapolis” “America/Indiana/Knox”
[129] “America/Indiana/Marengo” “America/Indiana/Petersburg” “America/Indiana/Tell_City” “America/Indiana/Vevay”
[133] “America/Indiana/Vincennes” “America/Indiana/Winamac” “America/Indianapolis” “America/Inuvik”
[137] “America/Iqaluit” “America/Jamaica” “America/Jujuy” “America/Juneau”
[141] “America/Kentucky/Louisville” “America/Kentucky/Monticello” “America/Knox_IN” “America/Kralendijk”
[145] “America/La_Paz” “America/Lima” “America/Los_Angeles” “America/Louisville”
[149] “America/Lower_Princes” “America/Maceio” “America/Managua” “America/Manaus”
[153] “America/Marigot” “America/Martinique” “America/Matamoros” “America/Mazatlan”
[157] “America/Mendoza” “America/Menominee” “America/Merida” “America/Metlakatla”
[161] “America/Mexico_City” “America/Miquelon” “America/Moncton” “America/Monterrey”
[165] “America/Montevideo” “America/Montreal” “America/Montserrat” “America/Nassau”
[169] “America/New_York” “America/Nipigon” “America/Nome” “America/Noronha”
[173] “America/North_Dakota/Beulah” “America/North_Dakota/Center” “America/North_Dakota/New_Salem” “America/Ojinaga”
[177] “America/Panama” “America/Pangnirtung” “America/Paramaribo” “America/Phoenix”
[181] “America/Port_of_Spain” “America/Port-au-Prince” “America/Porto_Acre” “America/Porto_Velho”
[185] “America/Puerto_Rico” “America/Punta_Arenas” “America/Rainy_River” “America/Rankin_Inlet”
[189] “America/Recife” “America/Regina” “America/Resolute” “America/Rio_Branco”
[193] “America/Rosario” “America/Santa_Isabel” “America/Santarem” “America/Santiago”
[197] “America/Santo_Domingo” “America/Sao_Paulo” “America/Scoresbysund” “America/Shiprock”
[201] “America/Sitka” “America/St_Barthelemy” “America/St_Johns” “America/St_Kitts”
[205] “America/St_Lucia” “America/St_Thomas” “America/St_Vincent” “America/Swift_Current”
[209] “America/Tegucigalpa” “America/Thule” “America/Thunder_Bay” “America/Tijuana”
[213] “America/Toronto” “America/Tortola” “America/Vancouver” “America/Virgin”
[217] “America/Whitehorse” “America/Winnipeg” “America/Yakutat” “America/Yellowknife”
[221] “Antarctica/Casey” “Antarctica/Davis” “Antarctica/DumontDUrville” “Antarctica/Macquarie”
[225] “Antarctica/Mawson” “Antarctica/McMurdo” “Antarctica/Palmer” “Antarctica/Rothera”
[229] “Antarctica/South_Pole” “Antarctica/Syowa” “Antarctica/Troll” “Antarctica/Vostok”
[233] “Arctic/Longyearbyen” “Asia/Aden” “Asia/Almaty” “Asia/Amman”
[237] “Asia/Anadyr” “Asia/Aqtau” “Asia/Aqtobe” “Asia/Ashgabat”
[241] “Asia/Ashkhabad” “Asia/Atyrau” “Asia/Baghdad” “Asia/Bahrain”
[245] “Asia/Baku” “Asia/Bangkok” “Asia/Barnaul” “Asia/Beirut”
[249] “Asia/Bishkek” “Asia/Brunei” “Asia/Calcutta” “Asia/Chita”
[253] “Asia/Choibalsan” “Asia/Chongqing” “Asia/Chungking” “Asia/Colombo”
[257] “Asia/Dacca” “Asia/Damascus” “Asia/Dhaka” “Asia/Dili”
[261] “Asia/Dubai” “Asia/Dushanbe” “Asia/Famagusta” “Asia/Gaza”
[265] “Asia/Harbin” “Asia/Hebron” “Asia/Ho_Chi_Minh” “Asia/Hong_Kong”
[269] “Asia/Hovd” “Asia/Irkutsk” “Asia/Istanbul” “Asia/Jakarta”
[273] “Asia/Jayapura” “Asia/Jerusalem” “Asia/Kabul” “Asia/Kamchatka”
[277] “Asia/Karachi” “Asia/Kashgar” “Asia/Kathmandu” “Asia/Katmandu”
[281] “Asia/Khandyga” “Asia/Kolkata” “Asia/Krasnoyarsk” “Asia/Kuala_Lumpur”
[285] “Asia/Kuching” “Asia/Kuwait” “Asia/Macao” “Asia/Macau”
[289] “Asia/Magadan” “Asia/Makassar” “Asia/Manila” “Asia/Muscat”
[293] “Asia/Nicosia” “Asia/Novokuznetsk” “Asia/Novosibirsk” “Asia/Omsk”
[297] “Asia/Oral” “Asia/Phnom_Penh” “Asia/Pontianak” “Asia/Pyongyang”
[301] “Asia/Qatar” “Asia/Qyzylorda” “Asia/Rangoon” “Asia/Riyadh”
[305] “Asia/Saigon” “Asia/Sakhalin” “Asia/Samarkand” “Asia/Seoul”
[309] “Asia/Shanghai” “Asia/Singapore” “Asia/Srednekolymsk” “Asia/Taipei”
[313] “Asia/Tashkent” “Asia/Tbilisi” “Asia/Tehran” “Asia/Tel_Aviv”
[317] “Asia/Thimbu” “Asia/Thimphu” “Asia/Tokyo” “Asia/Tomsk”
[321] “Asia/Ujung_Pandang” “Asia/Ulaanbaatar” “Asia/Ulan_Bator” “Asia/Urumqi”
[325] “Asia/Ust-Nera” “Asia/Vientiane” “Asia/Vladivostok” “Asia/Yakutsk”
[329] “Asia/Yangon” “Asia/Yekaterinburg” “Asia/Yerevan” “Atlantic/Azores”
[333] “Atlantic/Bermuda” “Atlantic/Canary” “Atlantic/Cape_Verde” “Atlantic/Faeroe”
[337] “Atlantic/Faroe” “Atlantic/Jan_Mayen” “Atlantic/Madeira” “Atlantic/Reykjavik”
[341] “Atlantic/South_Georgia” “Atlantic/St_Helena” “Atlantic/Stanley” “Australia/ACT”
[345] “Australia/Adelaide” “Australia/Brisbane” “Australia/Broken_Hill” “Australia/Canberra”
[349] “Australia/Currie” “Australia/Darwin” “Australia/Eucla” “Australia/Hobart”
[353] “Australia/LHI” “Australia/Lindeman” “Australia/Lord_Howe” “Australia/Melbourne”
[357] “Australia/North” “Australia/NSW” “Australia/Perth” “Australia/Queensland”
[361] “Australia/South” “Australia/Sydney” “Australia/Tasmania” “Australia/Victoria”
[365] “Australia/West” “Australia/Yancowinna” “Brazil/Acre” “Brazil/DeNoronha”
[369] “Brazil/East” “Brazil/West” “Canada/Atlantic” “Canada/Central”
[373] “Canada/Eastern” “Canada/Mountain” “Canada/Newfoundland” “Canada/Pacific”
[377] “Canada/Saskatchewan” “Canada/Yukon” “CET” “Chile/Continental”
[381] “Chile/EasterIsland” “CST6CDT” “Cuba” “EET”
[385] “Egypt” “Eire” “EST” “EST5EDT”
[389] “Etc/GMT” “Etc/GMT-0” “Etc/GMT-1” “Etc/GMT-10”
[393] “Etc/GMT-11” “Etc/GMT-12” “Etc/GMT-13” “Etc/GMT-14”
[397] “Etc/GMT-2” “Etc/GMT-3” “Etc/GMT-4” “Etc/GMT-5”
[401] “Etc/GMT-6” “Etc/GMT-7” “Etc/GMT-8” “Etc/GMT-9”
[405] “Etc/GMT+0” “Etc/GMT+1” “Etc/GMT+10” “Etc/GMT+11”
[409] “Etc/GMT+12” “Etc/GMT+2” “Etc/GMT+3” “Etc/GMT+4”
[413] “Etc/GMT+5” “Etc/GMT+6” “Etc/GMT+7” “Etc/GMT+8”
[417] “Etc/GMT+9” “Etc/GMT0” “Etc/Greenwich” “Etc/UCT”
[421] “Etc/Universal” “Etc/UTC” “Etc/Zulu” “Europe/Amsterdam”
[425] “Europe/Andorra” “Europe/Astrakhan” “Europe/Athens” “Europe/Belfast”
[429] “Europe/Belgrade” “Europe/Berlin” “Europe/Bratislava” “Europe/Brussels”
[433] “Europe/Bucharest” “Europe/Budapest” “Europe/Busingen” “Europe/Chisinau”
[437] “Europe/Copenhagen” “Europe/Dublin” “Europe/Gibraltar” “Europe/Guernsey”
[441] “Europe/Helsinki” “Europe/Isle_of_Man” “Europe/Istanbul” “Europe/Jersey”
[445] “Europe/Kaliningrad” “Europe/Kiev” “Europe/Kirov” “Europe/Lisbon”
[449] “Europe/Ljubljana” “Europe/London” “Europe/Luxembourg” “Europe/Madrid”
[453] “Europe/Malta” “Europe/Mariehamn” “Europe/Minsk” “Europe/Monaco”
[457] “Europe/Moscow” “Europe/Nicosia” “Europe/Oslo” “Europe/Paris”
[461] “Europe/Podgorica” “Europe/Prague” “Europe/Riga” “Europe/Rome”
[465] “Europe/Samara” “Europe/San_Marino” “Europe/Sarajevo” “Europe/Saratov”
[469] “Europe/Simferopol” “Europe/Skopje” “Europe/Sofia” “Europe/Stockholm”
[473] “Europe/Tallinn” “Europe/Tirane” “Europe/Tiraspol” “Europe/Ulyanovsk”
[477] “Europe/Uzhgorod” “Europe/Vaduz” “Europe/Vatican” “Europe/Vienna”
[481] “Europe/Vilnius” “Europe/Volgograd” “Europe/Warsaw” “Europe/Zagreb”
[485] “Europe/Zaporozhye” “Europe/Zurich” “GB” “GB-Eire”
[489] “GMT” “GMT-0” “GMT+0” “GMT0”
[493] “Greenwich” “Hongkong” “HST” “Iceland”
[497] “Indian/Antananarivo” “Indian/Chagos” “Indian/Christmas” “Indian/Cocos”
[501] “Indian/Comoro” “Indian/Kerguelen” “Indian/Mahe” “Indian/Maldives”
[505] “Indian/Mauritius” “Indian/Mayotte” “Indian/Reunion” “Iran”
[509] “Israel” “Jamaica” “Japan” “Kwajalein”
[513] “Libya” “MET” “Mexico/BajaNorte” “Mexico/BajaSur”
[517] “Mexico/General” “MST” “MST7MDT” “Navajo”
[521] “NZ” “NZ-CHAT” “Pacific/Apia” “Pacific/Auckland”
[525] “Pacific/Bougainville” “Pacific/Chatham” “Pacific/Chuuk” “Pacific/Easter”
[529] “Pacific/Efate” “Pacific/Enderbury” “Pacific/Fakaofo” “Pacific/Fiji”
[533] “Pacific/Funafuti” “Pacific/Galapagos” “Pacific/Gambier” “Pacific/Guadalcanal”
[537] “Pacific/Guam” “Pacific/Honolulu” “Pacific/Johnston” “Pacific/Kiritimati”
[541] “Pacific/Kosrae” “Pacific/Kwajalein” “Pacific/Majuro” “Pacific/Marquesas”
[545] “Pacific/Midway” “Pacific/Nauru” “Pacific/Niue” “Pacific/Norfolk”
[549] “Pacific/Noumea” “Pacific/Pago_Pago” “Pacific/Palau” “Pacific/Pitcairn”
[553] “Pacific/Pohnpei” “Pacific/Ponape” “Pacific/Port_Moresby” “Pacific/Rarotonga”
[557] “Pacific/Saipan” “Pacific/Samoa” “Pacific/Tahiti” “Pacific/Tarawa”
[561] “Pacific/Tongatapu” “Pacific/Truk” “Pacific/Wake” “Pacific/Wallis”
[565] “Pacific/Yap” “Poland” “Portugal” “PRC”
[569] “PST8PDT” “ROC” “ROK” “Singapore”
[573] “Turkey” “UCT” “Universal” “US/Alaska”
[577] “US/Aleutian” “US/Arizona” “US/Central” “US/East-Indiana”
[581] “US/Eastern” “US/Hawaii” “US/Indiana-Starke” “US/Michigan”
[585] “US/Mountain” “US/Pacific” “US/Pacific-New” “US/Samoa”
[589] “UTC” “W-SU” “WET” “Zulu”

Last but not least, let’s learn how to do arithmetic with dates and times (and quite personally, I think this is tons of fun):

Screen Shot 2020-05-02 at 4.21.06 PM

The lubridate packages contains two general time span classes-durations and periods. To create a function for periods, simply use the plural form for the unit of time you wish to make a period from. To create a function for durations, use the formatting for periods functions, but add a d in front of the unit of time.

In the hours() function, the amount of hours, minutes and seconds are displayed; since I used 15 for hours, the period is shown as 15H 0M 0S. In the dhours() function, the amount of hours are converted into seconds; since I also used 15 for hours, the duration shown is 54000s.

What if we used decimals for our period and duration functions? Let’s see what would happen:

Screen Shot 2020-05-03 at 11.56.27 AM

In this example, I used 15.5 hours for both my period and duration functions. While 15.5 worked fine with my duration function, it gave me an error when I tried to use it with my period function because the parameter for a period function must be an integer.

The period function will give you the entire time period down to the second, while the duration function will always give you the length of the time period in seconds.

  • I’m not sure how far the duration function would go, but I did try using dmonth and got an error.

Why are there two classes of time in lubridate? This is because the calendar timeline isn’t as reliable as the number line. See, durations always supply mathematically precise results-a duration year is ALWAYS 365 days (even for a leap year like 2020). However, periods fluctuate the way the calendar timeline does, so in periods, 2019 has 365 days while 2020 has 366 days.

But, before I get into any further time-date arithmetic, let’s see how R can detect a leap year:

Screen Shot 2020-05-02 at 4.43.19 PM

To find out whether a year is a leap year, simply use the leap_year() function along with the year you want to inquire about as the parameter. If the result is FALSE, the year isn’t a leap year, but if it’s TRUE, then the year is a leap year. As you can see, 2018 and 2019 aren’t leap years, but 2020 is a leap year.

Now, let’s perform some basic addition with period years and duration years:

Screen Shot 2020-05-03 at 12.18.50 PM

When I add 1 period year and 1 duration year to the date January 1 2019, I get January 1 2020 both times. This is because 2019 has 365 days, so 1 period year and 1 duration year from January 1 2019 would add up to January 1 2020.

However, with a leap year like 2020, the results from period years and duration years would be different. Similar to the last example, I am adding 1 period year and 1 duration year to January 1 2020. Since period years fluctuate with the calendar timeline, 1 period year from January 1 2020 is January 1 2021. However, 1 duration year from January 1 2020 is December 1 2020, since duration years always contain 365 days (and 2020 has 366 days).

Aside from adding period years and duration years, you can also perform other arithmetic with other units of time (such as days and months);

Screen Shot 2020-05-03 at 12.48.12 PM

In the first expression shown, I added 1 month to the date May 3 2020 and got June 3 2020. In the second expression, I subtracted 18 days from May 3 2020 and got April 15 2020.

Now, here’s where things get interesting. Notice how the third and fourth expressions shown generated error messages. This is because, unlike with regular numbers and decimals, you can’t multiply or divide units of time.

  • If you can’t multiply or divide units of time, then you certainly can’t do more advanced things like raising a date to a certain power or find the base-10 logarithm of a certain date (just saying in case anyone was wondering).

Now, there’s something interesting I wanted to point out when it comes to adding months to dates. In the example, when I added 1 month to May 3 2020, I got June 3 2020. Seems clear enough, right? Well, not always. See, there are two possible answers to adding a month to May 3 2020. They are:

  • June 3 2020, which is 31 days after May 3 2020
  • May 31 2020, which is 4 weeks after May 3 2020 (four weeks is considered a month)

I’ll explain the whole month addition thing later, but now, let’s discuss how to calculate the duration between two dates. To do this, we must first create a date interval:

Screen Shot 2020-05-03 at 1.21.37 PM

To create an interval, use the interval function that lubridate provides. For the parameters, use two dates-and keep the second date greater than the first date.

  • You can also include date-time objects as parameters in interval, complete with time-zones. I just chose not to include them for simplicity’s sake.

I’m going to use my most recent holiday vacation for this example, which lasted from December 24 2019 to January 5 2020. I stored my interval in the variable vacation.

Now, how long was my holiday vacation in days?:

Screen Shot 2020-05-03 at 1.30.38 PM

Dividing the vacation variable by ddays(1) gives us the length of my vacation in days-12. To be sure we get the exact duration in days, I had to use 1 as the parameter for ddays, because if I had used another number, I wouldn’t have gotten the exact duration. For instance, I tried vacation/ddays(2), and got 6, which is half the duration of my vacation (in days).

  • I could’ve used days(1) instead of ddays(1) and I would’ve gotten the same answer-12.

Now here’s another example of an interval:

Screen Shot 2020-05-03 at 1.39.13 PM

This interval represents how long I’ve been living in Nashville as of May 3 2020. 09052019 is the first parameter, since I moved to Nashville on September 5 2019.

Now how long is that in days and months?:

Screen Shot 2020-05-03 at 1.41.35 PM

So, according to these calculations, I’ve been living in Nashville for 241 days, or 7.93 months as of May 3 2020. What I find interesting is that the days and ddays functions both returned 241, despite having a February 29 factored in.

Now let’s try an even larger time interval:

Screen Shot 2020-05-03 at 2.01.06 PM

This interval represents how long this blog has been active for as of May 3 2020 (I launched this blog on June 13 2018). So how long would this be in years, months, and days?:

Screen Shot 2020-05-03 at 1.53.37 PM

All in all, this blog has been active for:

  • 1.888 period years and 1.89 duration years.
  • 22.67 months
  • 690 days (both period days and duration days)

Personally, I think it’s interesting that dyears and ddays can be used, but not dmonths. But I guess it’s just one of those R quirks.

Last but not least, let’s discuss the whole adding months thing. Earlier in this post, I did mention there were several possible answers to adding a month (or months) to a certain time using the example of May 3 2020. In that example, I said that there were two possible answers to the question of adding a month-June 3 (31 days from May 3) or May 31 (four weeks from May 3). See, since the 12 months of the year aren’t equal length, trying to do arithmetic with them won’t work.

So, how would we approach this problem? Let’s take a look:

Screen Shot 2020-05-03 at 9.47.03 PM

In this example, the months function keeps adding a month to 04302020 (April 30 2020) 11 times. You can see the results of the months function in the output below; the first result is 2020-04-30 and the last result is 2021-03-30, which is 11 months from the start date.

But wait, what’s the NA doing there? See, since there’s no such date as February 30 2021, an NA is displayed in its place.

  • The syntax for the months functions is as follows-months(X months from date:Y months from X). This means that the value to the left of the colon should be how many months from the start date you want to begin the calculation at and the value to the right of the colon should be how many months from the first value you want the calculations to end at.
  • It’s not necessary to use 0 as the first value for the months function, but if you want to include the given date in your calculation, then use 0.

OK, so what if we didn’t want to see any NA values. Here’s how we’d approach that:

Screen Shot 2020-05-03 at 9.58.35 PM

The floor_date function automatically starts the calculations on the first of the month following the date given (since I gave 05032020 as the date, the calculations automatically start with June 1 2020). The months function will add 1 month to June 1 2020 11 times and display all 12 of these results (the 12 results include June 1 2020). The days function tells R to run under the assumption that each month has 31 days (though using 28 for days would’ve worked just fine too).

OK, so there’s another approach to the whole adding-a-month-to-a-date-several-times question. Here it is:

Screen Shot 2020-05-03 at 10.07.32 PM

Using the %m+% and %m-% operators, you can get a list of months up to X months out from a certain date. The amazing thing about these operators is that they will automatically roll back to the last day of the month if necessary.

One thing to keep in mind is that the %m+% operator will move forward 1 month for X amount of months but the %m-% operator will move backwards 1 month for X amount of months. At least both are very precise when calculating months.

 

 

 

 

 

 

 

 

 

 

Leave a Reply