strptime,as.POSIXct和as.Date返回意外的NA

时间:2012-12-05 15:40:17

标签: r macos datetime strptime r-faq

当我尝试按以下格式解析时间戳时:“2012年11月8日星期四15:41:45”,只返回NA

我使用的是Mac OS X,R 2.15.2和Rstudio 0.97.237。我操作系统的语言是荷兰语:我认为这与它有关。

当我尝试strptime时,会返回NA

var <- "Thu Nov 8 15:41:45 2012"
strptime(var, "%a %b %d %H:%M:%S %Y")
# [1] NA

as.POSIXct也不起作用:

as.POSIXct(var, "%a %b %d %H:%M:%S %Y")
# [1] NA

我还在上面的字符串上尝试as.Date,但没有%H:%M:%S个组件:

as.Date("Thu Nov 8 2012", "%a %b %d %Y")
# [1] NA

任何想法我可能做错了什么?

2 个答案:

答案 0 :(得分:23)

我认为这正如您所猜测的那样,strptime因您的语言环境而无法解析您的日期时间字符串。您的字符串包含缩写的工作日(%a)和缩写的月份名称(%b)。这些时间规范在?strptime

中描述
  

<强>详情

     

%a:当前语言环境中缩写的工作日名称   平台

     

%b:此平台上当前区域设置中缩写的月份名称​​

     

“请注意,缩写名称是特定于平台的(尽管如此)   标准规定在C语言环境中它们必须是前三个   大写英文名称的字母:“

     

如果您想使用,“了解缩写是必不可少的   %a%b%h作为输入格式的一部分:请参阅示例   怎么检查。“

     

另见

     

[...] locales来查询或设置区域设置。

locales的问题也适用于as.POSIXctas.POSIXltas.Date

来自?as.POSIXct

  

<强>详情

     

如果指定了format,请记住一些格式   规范是特定于语言环境的,您可能需要设置   通过LC_TIME适当地Sys.setlocale类别。这最常见   会影响%b%B(月份名称)和%p(上午/下午)的使用。

来自?as.Date

  

<强>详情

     

使用与字符串相关的特定于语言环境的转换   在适当和可用的地方。这会影响日期的名称   和几个月。


因此,如果字符串中的工作日和月份名称与当前语言环境中的名称不同,则strptimeas.POSIXctas.Date无法正确解析字符串并NA归还。

但是,您可以通过更改locales

来解决此问题
# First save your current locale
loc <- Sys.getlocale("LC_TIME")

# Set correct locale for the strings to be parsed
# (in this particular case: English)
# so that weekdays (e.g "Thu") and abbreviated month (e.g "Nov") are recognized
Sys.setlocale("LC_TIME", "en_GB.UTF-8")
# or
Sys.setlocale("LC_TIME", "C") 

#Then proceed as you intended
x <- "Thu Nov 8 15:41:45 2012" 
strptime(x, "%a %b %d %H:%M:%S %Y")
# [1] "2012-11-08 15:41:45"

# Then set back to your old locale
Sys.setlocale("LC_TIME", loc) 

使用我的个人区域设置,我可以重现您的错误:

Sys.setlocale("LC_TIME", loc)
# [1] "fr_FR.UTF-8"

strptime(var,"%a %b %d %H:%M:%S %Y")
# [1] NA

答案 1 :(得分:2)

只是搞乱了同样的问题,发现这个解决方案更加清晰,因为不需要手动更改任何系统设置,因为有一个包装函数在lubridate包中执行此工作,你所要做的就是设置参数locale

date <- c("23. juni 2014", "1. november 2014", "8. marts 2014", "16. juni 2014", "12. december 2014", "13. august 2014")
df$date <- dmy(df$Date, locale = "Danish")
[1] "2014-06-23" "2014-11-01" "2014-03-08" "2014-06-16" "2014-12-12" "2014-08-13"