【问题标题】:`as.POSIXct` get error with `"%Y-%m-%d %H:%M:%S"` format`as.POSIXct` 使用 `"%Y-%m-%d %H:%M:%S"` 格式获取错误
【发布时间】:2021-07-19 06:26:19
【问题描述】:
dates <- seq(1626629937,1626629944)

# CORRECT

## #1
as.POSIXct(dates,                    tz="Asia/Shanghai",origin="1970-01-01")
#> [1] "2021-07-19 01:38:57 CST" "2021-07-19 01:38:58 CST" "2021-07-19 01:38:59 CST" "2021-07-19 01:39:00 CST"
#> [5] "2021-07-19 01:39:01 CST" "2021-07-19 01:39:02 CST" "2021-07-19 01:39:03 CST" "2021-07-19 01:39:04 CST"

## #2
as.POSIXct(dates,                    tz="Asia/Shanghai",origin="1970-01-01",optional = FALSE)
#> [1] "2021-07-19 01:38:57 CST" "2021-07-19 01:38:58 CST" "2021-07-19 01:38:59 CST" "2021-07-19 01:39:00 CST"
#> [5] "2021-07-19 01:39:01 CST" "2021-07-19 01:39:02 CST" "2021-07-19 01:39:03 CST" "2021-07-19 01:39:04 CST"


# DIFFERENT RESULT

## #3
as.POSIXct(dates,"%Y-%m-%d %H:%M:%S"                   ,origin="1970-01-01")
#> [1] "2021-07-18 17:38:57" "2021-07-18 17:38:58" "2021-07-18 17:38:59" "2021-07-18 17:39:00" "2021-07-18 17:39:01"
#> [6] "2021-07-18 17:39:02" "2021-07-18 17:39:03" "2021-07-18 17:39:04"


# NAs

## #4
as.POSIXct(dates,"%Y-%m-%d %H:%M:%S",tz="Asia/Shanghai",origin="1970-01-01")
#> [1] NA NA NA NA NA NA NA NA

## #5
as.POSIXct(dates,"%Y-%m-%d %H:%M:%S",tz="Asia/Shanghai",origin="1970-01-01",optional = FALSE)
#> [1] NA NA NA NA NA NA NA NA


# ERROR

## #6
as.POSIXct(dates,"%Y-%m-%d %H:%M:%S"                                       ,optional = FALSE)
#>  Error in as.POSIXct.numeric(as.integer(.), "%Y-%m-%d %H:%M:%S", optional = FALSE) : 
#>   'origin' must be supplied 

作为上述 R 脚本的输出,使用 tz,origin,optional 参数格式化 "%Y-%m-%d %H:%M:%S" 导致 NA

问题出在哪里?

【问题讨论】:

    标签: r posixct


    【解决方案1】:

    先说简单的:

    • optional = FALSE 是默认值:因此 #1 == #2 和 #4 == #5
    • #6 无需解释:您需要参数 origin = 作为错误状态
    • #3 由于时区(tz= 参数)而返回不同的结果。因此,它显示的是 8 小时前。

    现在,问题是#4 和#5(与我之前所说的相同):

    as.POSIXct(dates,"%Y-%m-%d %H:%M:%S",tz="Asia/Shanghai",origin="1970-01-01")
    #> [1] NA NA NA NA NA NA NA NA
    

    要了解其工作原理,您需要查看函数 as.POSIXct,当使用数字 x(如本例中)调用该函数时,会调用方法:as.POSIXct.numeric

    as.POSIXct.numeric
    
    #> function (x, tz = "", origin, ...) 
    #> {
    #>     if (missing(origin)) {
    #>         if (!length(x)) 
    #>             return(.POSIXct(numeric(), tz))
    #>         if (!any(is.finite(x))) 
    #>             return(.POSIXct(x, tz))
    #>         stop("'origin' must be supplied")
    #>     }
    #>     .POSIXct(as.POSIXct(origin, tz = "GMT", ...) + x, tz)
    #> }
    #> <bytecode: 0x55df7f23b390>
    #> <environment: namespace:base>
    

    关注这一行:

    #> .POSIXct(as.POSIXct(origin, tz = "GMT", ...) + x, tz)
    

    特别是:

    as.POSIXct(origin, tz = "GMT", ...) + x
    

    如您所见,该函数将origin 转换为日期时间,然后对您估算的数字输入求和。您提供的每个附加参数都属于...

    该函数尝试使用您提供的格式将1970-01-01 转换为日期时间:%Y-%m-%d %H:%M:%S。 由于原点1970-01-01 的格式为%Y-%m-%d,因此该函数无法将原点从字符串转换为POSIX,因此返回NA。 (这就是生成NAs 的地方!)

    当您将数字转换为 POSIX 时,作为参数添加的格式不适用于输出(因为它始终是 POSIX)或输入,而是适用于 origin。因此,originformat 需要匹配。

    要解决您的问题,您需要使用origin,格式为%Y-%m-%d %H:%M:%S。 像这样:

    as.POSIXct(dates,"%Y-%m-%d %H:%M:%S",tz="Asia/Shanghai",origin="1970-01-01 00:00:00")
    #> [1] "2021-07-19 01:38:57 CST" "2021-07-19 01:38:58 CST" "2021-07-19 01:38:59 CST" "2021-07-19 01:39:00 CST"
    #> [5] "2021-07-19 01:39:01 CST" "2021-07-19 01:39:02 CST" "2021-07-19 01:39:03 CST" "2021-07-19 01:39:04 CST"
    

    或者你需要使用这种格式:%Y-%m-%d 像这样:

    as.POSIXct(dates,"%Y-%m-%d",tz="Asia/Shanghai",origin="1970-01-01")
    #> [1] "2021-07-19 01:38:57 CST" "2021-07-19 01:38:58 CST" "2021-07-19 01:38:59 CST" "2021-07-19 01:39:00 CST"
    #> [5] "2021-07-19 01:39:01 CST" "2021-07-19 01:39:02 CST" "2021-07-19 01:39:03 CST" "2021-07-19 01:39:04 CST"
    

    结果等于 #1 和 #2。

    【讨论】:

      猜你喜欢
      • 2020-03-18
      • 2017-11-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-10-15
      • 1970-01-01
      相关资源
      最近更新 更多