Lubridate: BC 日期

创建于 2009-05-27  ·  7评论  ·  资料来源: tidyverse/lubridate

记住自我:考虑公元前的日期和时间(基督之前/普通时代之前)

  • 加勒特

所有7条评论

你好。 我知道这是古老的,但是有人在考虑这个 bce / bc 问题,或者 lubridate 现在是否可以本地处理这个问题?

更具体的问题是什么。 人们心目中的用户模式是什么?

我正在关闭这个。 如果有人坚持应该这样做并且有用,请重新打开。

好吧,并不是说我经常使用它,而是我刚刚处理了一个负年份的数据集,即 BC,包括在内并且处理它有很多困难。 例如以下不起作用:

> lubridate::ymd("-2255-01-01")
[1] "2255-01-01"

> lubridate::parse_date_time(-2255, "Y")
[1] NA
Warning message:
All formats failed to parse. No formats found.

因为返回了具有正年份的 Date 对象。 也就是说,以下工作:

> lubridate::ymd("0000-01-01") - lubridate::years(2255)
[1] "-2255-01-01"

这让我写了一个辅助函数来处理负数。

我可以确认,对于从事古代时期(例如希腊和罗马时期)的任何人来说,此功能将非常有用。 对于在数字人文项目和课程中使用 R 的 Tidyverse 和lubridate爱好者来说,这个问题/选择目前是一个交易破坏者。 我很乐意测试修改后的功能。

你好! 感谢您的包裹和所做的工作。 如果有人考虑实施 BCE 日期,或按原样处理这些日期(1.7.9),这里有一些关于幻影零年引起的问题的想法。

处理(不存在的)“零年”

说明

如果有人正在考虑处理 lubridate 中的“普通时代之前”日期,请注意零年不存在(对于历史学家,我的意思是,有第 -1 年,然后是第 1 年,例如参见维基百科年表——另请注意,这是对于儒略历,这可能与我们现在使用的公历略有冲突;您可以在 Wikipedia 上找到有关此的更多详细信息),这可能会导致一些问题。

不熟悉这些符号的人的快速澄清:

  • CE ”代表“Common Era”,这是长期且仍在使用的“AD”、“Anno Domini”的“去基督教化”(因此日期CE可以被视为“正年”)
  • BCE ”代表“Before Common Era”,相当于“BC”、“Before Christ”(“负年”)。
    例如。 苏格拉底于公元前 399 年去世。

例如,lubridate 遵循 ISO 8601(我认为是8601:2004版本?BCE 日期可以使用ISO 8601:2019处理,但文档的免费访问部分不清楚),起价为0000-01-01 ,即公元前 1 年(第 -1 年)的 1 月 1 日。

这篇文章令人困惑,因为它让人认为“ 0000-01-01 ”是第 0 年,而“ -001-01-01 ”是第 -2 年的第 -1 年,并且可能导致计算持续时间的问题(请参阅下面的代码)。

除此之外,如果遇到,“0 CE/AD”或“0 BCE/BC”可能应该被解析为第 -1 年。

参考资料:维基百科( ISO 8601,0公元前 1 年Common Era ...)

一些代码来说明我的观点

(根据 WTFPL 获得许可:Do What The Fuck You Want to)

pacman::p_load(lubridate)
pacman::p_version(lubridate)
#> [1] '1.7.9'

a <- ymd("0001-01-01")
a
#> [1] "0001-01-01"
# Year 1, no problem

b <- ymd("0000-01-01") - years(1)
b
#> [1] "-001-01-01"
# It is Year -1?
# No, it's -2 even if printed (-001-01-01),
# since ymd("0000-01-01") is already Year -1.

# The problem appears if we compute duration between the two
as.duration(a - b)
#> [1] "63158400s (~2 years)"
# But there is only one year between 1st January -1 and 1st January 1!
# since year zero doesn't exist.

让我们用奥古斯都日期来说明:

  • 出生:公元前63年9月23日
  • 死亡时间:公元 14 年 8 月 19 日
  • 死亡年龄:75
aug_birth <- ymd("0000-09-23") - years(63)
aug_death <- ymd("0014-08-19")
age <- aug_death - aug_birth
as.duration(age)
#> [1] "2426889600s (~76.9 years)"
# That's one year too much!

# The correct writing would be:
aug_birth <- ymd("0000-09-23") - years(63 - 1)

因此,正确的辅助函数是解析 BCE yyyy-mm-dd:

parse_bce_ymd <- function(str) {
  regex <- "(\\d{4})(-\\d{2}-\\d{2})"
  match <- stringr::str_match(str, regex)
  years_n <- readr::parse_number(match[, 2]) - 1 # Beware the -1 here
  right_side <- match[, 3]
  date <- ymd(paste0("0000-",right_side)) - years(years_n)
  return(date)
}
# Test the function.
aug_birth <- parse_bce_ymd("0063-09-23")
aug_death <- ymd("0014-08-19")
age <- aug_death - aug_birth
as.duration(age)
#> [1] "2395353600s (~75.9 years)"
# Yay that's correct!

尽管如此,lubridate 打印的 BCE 日期比“真实的一年”少一年(绝对值少,这里提前一年),好像存在零年,这是误导。

aug_birth
#> [1] "-062-09-23"

鉴于最后的评论(以及 R 和 Tidyverse 包在数字人文项目中的广泛使用),您认为这个问题可以重新打开吗,@vspinu?

此页面是否有帮助?
0 / 5 - 0 等级