我正在努力让R遵循Windows计算机上指定的日期格式/区域设置。
我有:
> Sys.getlocale("LC_TIME")
[1] "English_United States.1252"
但是当我检查“控制面板” \“区域和语言设置”时,我有:
Format: English (United States)
Short date: M/d/yyyy
R似乎完全忽略了特定于日期的设置。用R格式化的日期以固定格式“%Y-%m-%d”硬编码(?):
format.Date(Sys.Date())
[1] "2019-01-25"
与外部程序的数据进行交互时出现问题,该程序确实符合本地区域设置。例如,日期由Microsoft Excel格式化。并使代码在不同的区域设置和不同的日期格式下通用。
我发现这在某种程度上可以奏效:
sShortDate <- readRegistry("Control Panel\\International", "HCU")$sShortDate
# convert Windows date format strings into R-date-format-strings
CPformat2Rformat <- function(f) {
f %>%
gsub("yyyy", "%Y", .) %>%
gsub("M", "%m", .) %>%
gsub('d', '%d', .)
}
sShortDate <- CPformat2Rformat(sShortDate)
# now we have the right format
format.Date(Sys.Date(), sShortDate)
# and the other way around;
strptime("01/25/2019", sShortDate)
这是处理此问题的最佳方法吗?还是有更好的功能来更好地处理ShortDate和LongDate格式?
答案 0 :(得分:1)
如果我没看错你的话,你是在问为什么R在每个语言环境中都不显示日期。我同意,如果您可以控制显示的Date
对象的格式,同时将其保存为Date
对象,那就太好了。但是,没有一点工作就没有真正的方法。
这是一个hack:覆盖默认的print.Date
方法,尽管它仅适用于控制台上的直接变量,不适用于data.frame
之类的嵌入式变量:
x <- data.frame(dt = Sys.Date(), dttm = Sys.time())
x$dt
# [1] "2019-01-25"
class(x$dt)
# [1] "Date"
print.Date <- function (x, max = NULL, ...) {
fmt <- getOption("date.format", "%m/%d/%Y")
if (is.null(max))
max <- getOption("max.print", 9999L)
if (max < length(x)) {
print(format(x[seq_len(max)], format=fmt), max = max, ...)
cat(" [ reached getOption(\"max.print\") -- omitted",
length(x) - max, "entries ]\n")
}
else if (length(x))
print(format(x, format=fmt), max = max, ...)
else cat(class(x)[1L], "of length 0\n")
invisible(x)
}
x
# dt dttm
# 1 2019-01-25 2019-01-25 00:22:38
x$dt
# [1] "01/25/2019"
class(x$dt)
# [1] "Date"
options(date.format="%b %d, %Y")
x$dt
# [1] "Jan 25, 2019"
我在此处将默认值定义为"%m/%d/%Y"
,但是这符合您的偏爱。该函数的更通用的应用程序可能默认为"%Y-%m-%d"
的R默认值,并让用户根据需要在某个时候对其进行更改。
(我不知道如何临时使用data.frame
表示形式引用此函数。这很可能是由于范围的缘故,由于名称空间的搜索路径,它正在使用base::print.Date
。如果您问“我能代替那个”吗?,通常会被问到,答案是“这可能有用,但是...” 或“腔体清空器” ,根据我的经验,从来没有真正完美地解决过这个问题,尤其是在尝试覆盖基本函数时。)
答案 1 :(得分:0)
您可以使用as.Date()
函数来适应不同的日期格式,例如:
as.Date("01/25/2019", format='%m/%d/%Y')
as.Date("Jan-30-2019", format='%b-%d-%Y')
as.Date("25012019", format='%d%m%Y')
都将给出相同的通用日期对象。