R中strftime()函数的行为

4
以下列出了两行代码。除了日期和时间不同之外,两者完全相同,但只有一种起作用。我正在使用R 3.1。
以下代码无效:
DateTime2=strftime("08/13/2010 05:26:24.350", format="%m/%d/%Y %H:%M:%OS", tz="GMT")

返回以下错误:
Error in as.POSIXlt.character(x, tz = tz) : 
  character string is not in a standard unambiguous format

但是以下内容可以正常工作:
DateTime2=strftime("08/02/2010 06:50:29.450", format="%m/%d/%Y %H:%M:%OS", tz="GMT")

第二行按预期存储了 DateTime2
有什么想法吗?

1
第一条命令对我来说没有出现错误。 - user3710546
2
我也一样,没有错误。你在哪个地区/时区? - MrFlick
1
我的问题被Pascal改变了!我没有问那个问题。我的问题涉及strftime而不是strptime。有人按照我之前提出的问题得到了这个错误吗? - R_is_Great
2个回答

7
当你使用strftime时会发生什么?以下是strftime代码:
> strftime
function (x, format = "", tz = "", usetz = FALSE, ...) 
format(as.POSIXlt(x, tz = tz), format = format, usetz = usetz, 
    ...)
<bytecode: 0xb9a548c>
<environment: namespace:base>

它先调用as.POSIXlt,然后使用参数format进行格式化。 如果您直接在示例中调用as.POSIXlt而不提供format参数,则会发生以下情况:
> as.POSIXlt("08/13/2010 05:26:24.350", tz="GMT")
Error in as.POSIXlt.character("08/13/2010 05:26:24.350", tz = "GMT") : 
  character string is not in a standard unambiguous format

原因是 as.POSIXlt 的代码如下:
> as.POSIXlt.character
function (x, tz = "", format, ...) 
{
    x <- unclass(x)
    if (!missing(format)) {
        res <- strptime(x, format, tz = tz)
        if (nzchar(tz)) 
            attr(res, "tzone") <- tz
        return(res)
    }
    xx <- x[!is.na(x)]
    if (!length(xx)) {
        res <- strptime(x, "%Y/%m/%d")
        if (nzchar(tz)) 
            attr(res, "tzone") <- tz
        return(res)
    }
    else if (all(!is.na(strptime(xx, f <- "%Y-%m-%d %H:%M:%OS", 
        tz = tz))) || all(!is.na(strptime(xx, f <- "%Y/%m/%d %H:%M:%OS", 
        tz = tz))) || all(!is.na(strptime(xx, f <- "%Y-%m-%d %H:%M", 
        tz = tz))) || all(!is.na(strptime(xx, f <- "%Y/%m/%d %H:%M", 
        tz = tz))) || all(!is.na(strptime(xx, f <- "%Y-%m-%d", 
        tz = tz))) || all(!is.na(strptime(xx, f <- "%Y/%m/%d", 
        tz = tz)))) {
        res <- strptime(x, f, tz = tz)
        if (nzchar(tz)) 
            attr(res, "tzone") <- tz
        return(res)
    }
    stop("character string is not in a standard unambiguous format")
}
<bytecode: 0xb9a4ff0>
<environment: namespace:base>

如果未指定format,它会尝试一系列常见格式,如果没有一个有效,则会引发您得到的错误。
所有这些的原因是,与strptime相反,strftime不用于将字符转换为POSIXlt对象,而是用于将POSIXlt对象转换为字符。从strftime的帮助页面上可以看到:
格式方法和strftime返回表示时间的字符向量。
要执行所需操作,请直接使用as.POSIXlt,如下所示:
> as.POSIXlt("08/13/2010 05:26:24.350", tz="GMT", format="%m/%d/%Y %H:%M:%OS")
[1] "2010-08-13 05:26:24 GMT"

编辑: 提醒您,您的第二行代码也没有起作用:

strftime("08/02/2010 06:50:29.450", format="%m/%d/%Y %H:%M:%OS", tz="GMT")
[1] "02/20/0008 00:00:00"

1
我认为您误解了strftime的作用。它的目的是将POSIXt对象转换为字符向量。因此,您应该将POSIXt对象作为strftime的参数。如果您提供一个字符向量,则它会尝试在格式化之前转换为POSIXlt。最重要的是,format参数不是输入字符串的格式,而是您想要的输出格式。例如:
strftime(as.POSIXct("2014-10-20 12:14:50"), format = "%Y/%m")
#[1] "2014/10"

在您的情况下会发生什么?由于提供了字符向量,strftime 尝试将其转换为 POSIXlt,假设您以某种标准格式提供了日期。然而,第一个字符串显示了一个 13,而在标准格式中应该提供月份。由于只有 12 个月,因此会出现错误。请注意它如何转换第二个日期(与其预期含义非常不同)。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接