如何将十进制日期格式(例如 2011.580)转换为普通日期格式?

How to convert decimal date format (e.g. 2011.580) to normal date format?

我正在尝试从十进制日期格式(return 类型的 cpts.ts() 来自 changepoint 包)更改为正常日期格式 %Y-%m-%d。示例:

cpts.ts(myTimeSeries.BinSeg)
[1] 2001.667 2004.083 2008.750 2011.583 2011.917

实际日期大约在 2001 年 8 月、2004 年 1 月、2008 年 9 月、June/July 2011 年和 2011 年 12 月(我不太清楚,我是从图表上读到的)。

我似乎找不到将此格式转换回常用日期格式的标准方法。

有人能帮帮我吗?

谢谢

> foo <- c(2001.667,2004.083,2008.750,2011.583,2011.917)
> as.Date(paste(trunc(foo),round((foo-trunc(foo))*365,0)),"%Y %j")
[1] "2001-08-31" "2004-01-30" "2008-09-30" "2011-08-01" "2011-12-01"

查看 ?as.Date 及其 format 参数,它将引导您到 ?strptime,我从中获取了 %j 格式规范。

您可能需要适应某些特殊情况,例如 1 月 1 日。

lubridate 的结果略有不同:

library(lubridate)
decimals <- c(2001.667, 2004.083, 2008.750, 2011.583, 2011.917)

format(date_decimal(decimals), "%Y-%m-%d")
# [1] "2001-09-01" "2004-01-31" "2008-10-01" "2011-08-01" "2011-12-01"

对于那些考虑使用基本 R 解决方案解决此问题的人来说,lubridate date_decimal 的核心本质上是:

start <- as.POSIXct(paste0(trunc(foo),  "/01/01"), tz="UTC") 
end   <- as.POSIXct(paste0(trunc(foo)+1,"/01/01"), tz="UTC") 
start + (difftime(end, start, units="secs") * (foo - trunc(foo)))

即- 将 start 日期设置为该日期所在年份的年初,将 end 日期设置为下一年的年初,将开始和结束之间的差异乘以该日期的分数年过去了,把这个差异加回到开始。这样做会考虑闰年,并且适用于 1 月 1 日。