如何在R中验证日期

时间:2012-11-19 08:53:38

标签: r

我的日期格式为dd-mm-yyyy HH:mm:ss 验证此日期的最佳和最简单的方法是什么?

我试过

d <- format.Date(date, format="%d-%m-%Y %H:%M:%S")

但是,如果通过非法日期,我怎样才能发现错误?

5 个答案:

答案 0 :(得分:11)

简单方法:

d <- try( as.Date( date, format= "%d-%m-%Y %H:%M:%S" ) )
if( class( d ) == "try-error" || is.na( d ) ) print( "That wasn't correct!" )

说明: format.Date在内部使用as.Datedate转换为Date类的对象。但是,它不使用格式选项,因此as.Date使用默认格式,即%Y-%m-%d,然后是%Y/%m/%d

来自format的{​​{1}}选项仅用于输出,而不用于解析。引自format.Date手册页:

  

'as.Date'方法接受字符串,因子,逻辑        'NA'和类''POSIXlt''和'“POSIXct”'的对象。 (该        通过忽略午夜后的时间将最后一天转换为天数        默认情况下,在指定时区中表示时间        UTC。)也是类'“date”'的对象(来自包'date')和        ''dates''(来自'chron'包装)。处理字符串        只要指定的格式是必要的:任何尾随        字符被忽略。

但是,当您使用格式规范直接调用as.Date时,除了适合您的格式之外,不允许任何其他内容。

另见as.Date

答案 1 :(得分:1)

您可能需要查看gsubfn包。这个函数(具体为gsubfn)与其他正则表达式函数一样,可以将片段与字符串匹配,但随后它会调用用户提供的函数并将匹配的片段传递给此函数。因此,您可以编写自己的函数来查看年份,蛾子和日期,并确保它们处于正确的范围内(并且日期的范围可以取决于所传递的月份和年份。

答案 2 :(得分:0)

我相信您正在寻找的是 tryCatch 功能。 以下是我编写的脚本的摘录,该脚本接受任何带有两个具有公共x轴的系列的.csv文件。数据&#39;中的第一列是常见的x轴变量,第2列和第2列是3是y轴变量。我需要tryCatch语句来确保脚本无论x轴数据是时间序列还是其他类型的变量都会创建绘图。

### READ DATA FROM A CSV FILE
data = read.csv("STLDvsNEM2.csv", header = TRUE)

#CONVERT FIRST ROW OF DATA (IN MY CASE, THE COLUMN INTENDED TO BE THE X AXIS)
#TO AN ACCEPTABLE DATE FORMAT
#IF FIRST ROW OF DATA IS NOT IN AN ACCEPTABLE DATE FORMAT
#USE THE VALUE WITHOUT ANY TRANSFORMATION
x <- tryCatch({
  as.Date(data[,1])},
  warning = function(w) {},
  error = function(e) {
    x <- data[,1]
  })
y1 <- data[,2]
y2 <- data[,3]

答案 3 :(得分:0)

如果在日期时间输入中需要灵活性,这可能会有所帮助。

我有一个要允许仅日期输入或日期时间输入的功能,然后设置一个标志-仅在该函数内部使用。我称这个标记为data_type。稍后将在较大的功能中使用该标志来选择单位,以使两个日期与difftime有所不同。 (在大多数情况下,该功能仅适用于日期功能,但在某些情况下,用户可能需要较短的时间范围。如果用户不需要,我不想在较短的时间范围内带来不便。)

我发布此消息的原因有两个:1)帮助任何试图允许日期参数灵活的人,以及2)在方法存在问题的情况下欢迎进行完整性检查,因为这是R包中的函数

dat_time_check_fn <- function(dat_time) {
  if (!anyNA(as.Date(dat_time, format= "%Y-%m-%d %H:%M:%S"))) date_type <- 1
else if (!anyNA(as.Date(dat_time, format= "%Y-%m-%d"))) date_type <- 2
else stop("Error: dates must either be in format '1999-12-31' or '1999-12-31 23:59:59' ")
date_type
}

日期时间情况

date5 <- "1999-12-31 23:59:59"

date_type <- dat_time_check_fn(date5)
date_type
[1] 1

仅日期情况:

date6 <- "1999-12-31"

date_type <- dat_time_check_fn(date6)
date_type
[1] 2

请注意,如果函数中的上述顺序颠倒,则较长的日期时间可能会无意间被强制转换为较短的版本,并且这两种类型都会导致date_type = 1。

我较大的函数有多个日期,但是我需要它们兼容。在下面,我正在检查上面选中的两个日期,其中一个是类型1,一个是类型2。将类型组合起来只能得到带有日期的结果(类型2):

date_type <- dat_time_check_fn(c(date5, date6))
date_type
[1] 2

这是不兼容的版本:

date7 <- "1/31/2011"

date_type <- dat_time_check_fn(date7)

Error in dat_time_check_fn(date7) : 
  Error: dates must either be in format '1999-12-31' or '1999-12-31 23:59:59'

答案 4 :(得分:0)

这里的许多解决方案都易于进行SQL注入。他们为TRUE返回date = "2020-08-11; DROP * FROM my_table"。这是可与NA一起使用的矢量化基本R函数:

is_date = function(x, format = NULL) {
  formatted = try(as.Date(x, format), silent = TRUE)
  is_date = as.character(formatted) == x & !is.na(formatted)  # valid and identical to input
  is_date[is.na(x)] = NA  # Insert NA for NA in x
  return(is_date)
}

让我们尝试一下:

> is_date(c("2020-08-11", "2020-13-32", "2020-08-11; DROP * FROM table", NA), format = "%Y-%m-%d")
## TRUE FALSE FALSE    NA