Skip to content

Instantly share code, notes, and snippets.

@micstr
Last active May 25, 2021 11:40
Show Gist options
  • Save micstr/69a64fbd0f5635094a53 to your computer and use it in GitHub Desktop.
Save micstr/69a64fbd0f5635094a53 to your computer and use it in GitHub Desktop.
Testing dates in R - an IsDate() function
# Trying to find a basic test for dates in R. was looking for a is.Date like as.Date vibe
IsDate <- function(mydate, date.format = "%d/%m/%y") {
# Check if field is a date using as.Date that looks for unambiguous dates
# Assumes date format so NA returned not Character error.
# Why? with no date format, R tries two defaults then gives error.
# BUT With a dateformat R returns NA
# Args
# Suspected date and optional date format string
# Returns
# TRUE if thinbks it is a date
tryCatch(!is.na(as.Date(mydate, date.format)),
error = function(err) {FALSE})
}
mydate <- "price"
IsDate(mydate)
# FALSE
mydate <- "1/3/2015"
IsDate(mydate)
# TRUE
@dips99
Copy link

dips99 commented Aug 16, 2018

the code can be improved with various date formats using tryFormats param in as.Date()

library(lubridate)
IsDate <- function(mydate) {
  	tryCatch(!is.na(as.Date(mydate, "",tryFormats = c("%Y-%m-%d", "%Y/%m/%d","%d-%m-%Y","%m-%d-%Y"))),  
        error = function(err) {FALSE})  
}

@AndreAlz
Copy link

Really useful function @micstr, thanks!

@dips99 nice improvements!

@lindeloev
Copy link

@dips99 This function is prone to SQL injection. The following returns TRUE:

    IsDate("2020-08-11; DROP * FROM table")

@lindeloev
Copy link

The base R function seems to work as intended:

is_date = function(x, format) {
  formatted = try(as.Date(x, format), silent = TRUE)
  return(as.character(formatted) == x)
}

@joundso
Copy link

joundso commented May 25, 2021

If I see it right, this cannot handle e.g. NAs. I instead suggest using

is_date_new <- function(date, format) {
  formatted = try(as.Date(date, format), silent = TRUE)
  return(DIZutils::equals2(as.character(formatted), date))
}

which leads to a TRUE/FALSE result:

date <- c("2021-01-01", "2020-12-31", "foo", "2021-31-12")
format <- "%Y-%m-%d"

## The function from above:
is_date(date, format)
#> [1] TRUE TRUE   NA   NA

## This function:
is_date_new(date, format)
#> [1]  TRUE  TRUE FALSE FALSE

Created on 2021-05-25 by the reprex package (v2.0.0)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment