77

I'm working with a csv which unfortunately has logged datetimes using the number format of 42705 although it should be 01/12/2016.

I'd like to convert it to the right format in R using lubridate or some other package. Is there a function that will handle it?

Andrew Brēza
  • 5,779
  • 2
  • 30
  • 39
elksie5000
  • 4,829
  • 8
  • 44
  • 71

3 Answers3

145

You don't need to use lubridate for this, the base function as.Date handles this type of conversion nicely. The trick is that you have to provide the origin, which in Excel is December 30, 1899.

as.Date(42705, origin = "1899-12-30")
# [1] "2016-12-01"

If you want to preserve your column types, you can try using the read_excel function from the readxl package. That lets you load an XLS or XLSX file with the number formatting preserved.

Andrew Brēza
  • 5,779
  • 2
  • 30
  • 39
  • 1
    Thank you for that. I'm still very new to R. It worked a treat. – elksie5000 Apr 05 '17 at 11:58
  • Quite welcome. I'm editing my response now since I realized the origin is slightly off. Give me a minute before you use this code in your project :-) – Andrew Brēza Apr 05 '17 at 11:59
  • Actually I just typed 01/12/2016 into Excel and converted it into a number. The value I got was 42381, not 42705. Using 42381 in the `as.Date` function gets you back to 1/12/2016. Are you sure that you copied the number correctly from Excel? – Andrew Brēza Apr 05 '17 at 12:01
  • Oh, I did exactly the same thing in my copy of Excel, but had a different number. Is because it's European day-month-year format? – elksie5000 Apr 05 '17 at 12:05
  • That's exactly what happened, I should have asked what date format you were using. It's still early here in the states and I'm obviously not thinking clearly yet. – Andrew Brēza Apr 05 '17 at 12:07
  • Hey, I just appreciated your swift response. Thank you. – elksie5000 Apr 05 '17 at 12:08
  • This is my favorite solution, but one caution mentioned in the documentation for the "as.Date" function is the handling of leap years can vary between programs, e.g. Excel intentionally misclassifies 1900 as a leap year. If your dates cover broad range, double check the conversion for the min and max dates in your range. – Robert Alan Greevy Jr PhD Apr 28 '20 at 14:31
  • 2
    In the French version of excel, the best solution is quite fascinating, for a date with hours: `as_datetime(Date,origin = "1969-12-31 24:00:00")` – Clément LVD May 31 '20 at 16:54
25

Here is another way to do it using janitor and tibble packages:

install.packages("janitor")
install.packages("tibble")

library(tibble)
library(janitor)

excel_numeric_to_date(as.numeric(as.character(YourDate)), date_system = "modern")    
Rui Barradas
  • 44,483
  • 8
  • 22
  • 48
Reza Rahimi
  • 381
  • 5
  • 6
11

openxlsx package also allows xls date conversion:

openxlsx::convertToDate(42705)
[1] "2016-12-01"

And as suggested by @Suren, convertToDateTime is useful for datetime conversion:

openxlsx::convertToDateTime(42705.5)
[1] "2016-12-01 12:00:00"
Waldi
  • 21,789
  • 5
  • 13
  • 47