从 R 到 Excel 的日期转换(有时会有一天的偏移)

Date Conversion from R to Excel (sometimes there is a shift by one day)

我正在从事一个 R 项目,其中一个目标是创建 Excel Sheets。 问题是某些日期值(旧值)有一天的变化,但其他值运行良好!

显示的代码创建了一个 data.frame,其中包含一个名为 Dates 的列。在此列中存储值 01.01.1900、01.01.1950 和 01.01.2000。创建 Excel Sheet 后,01.01.1900 更改为 02.01.1900,其他保持不变。

dates = as.Date(c("01.01.1900","01.01.1950","01.01.2000"), "%d.%m.%Y")
df = data.frame(Dates=dates)

wb <- createWorkbook()
addWorksheet(wb, sheetName = "Dates")
writeData(wb, 1, df)
saveWorkbook(wb, "dates.xlsx", overwrite = TRUE)

如果有人能向我解释为什么会这样,最好能提供解决方案。

一切顺利, 安迪

被称为Excel的leap-year bug。它错误地假定 29/02/1900 是实际的一天。但是,它是故意这样实现的,以确保与 Lotus 1-2-3 电子表格的兼容性。

因此,您会发现 01/01/1900 和 28/02/1900 之间的任何日期都会出现此问题。当用 R 写入电子表格时,它会将日期向前移动 1 天,而当从电子表格中读取时,它应该将日期向后移动 1 天。

在 openxlsx 的 github 上有一个未解决的问题 - 因此将来可能会修复此问题。参见:openxlsx github issue

一般来说,我觉得应该很少需要在这个日期范围内写日期。除了作为缺失日期的占位符之外。

不过,如果您需要解决方法,您始终可以编写一个小函数,在写入 excel 之前手动将受影响的日期增加 1 天。例如:


library(tidyverse)
library(lubridate)
library(openxlsx)

# Helper Function

fix_dates_for_excel_write <- function(df) {

  df %>% 
    as_tibble() %>% 
    mutate_if(is.Date, ~ if_else(. <= ymd(19000228), . - days(1), .))

}
# Affected dates to test

dates = as.Date(c("01.01.1900", "02.01.1900", 
                  "27.02.1900", "28.02.1900", 
                  "01.03.1900", "01.01.1950"), "%d.%m.%Y")

df = data.frame(Dates=dates)

# Apply helper function

df <- fix_dates_for_excel_write(df)

# Write to Excel
writeData(wb, 1, df)