Lubridate: Даты до нашей эры

Созданный на 27 мая 2009  ·  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"

что заставило меня написать вспомогательную функцию, которая работает с отрицательными годами.

Я могу подтвердить, что для всех, кто работает с древними периодами (например, с греческим и римским периодами), эта функция будет очень полезна. Эта проблема / выбор в настоящее время является преградой для энтузиастов Tidyverse и lubridate использующих R в проектах и ​​курсах Digital Humanities. Буду рад протестировать измененные функции.

Привет! Спасибо за посылку и проделанную работу. Если кто-то думает о внедрении дат BCE или о работе с ними в пакете как есть (1.7.9), вот несколько мыслей о проблемах, вызванных фантомным нулевым годом.

Работа с (несуществующим) "нулевым годом"

Пояснения

Если кто-то рассматривает возможность работы с датами «до нашей эры» в lubridate, имейте в виду, что нулевого года не существует (для историков я имею в виду год -1, а затем год 1, см., Например, хронологию Википедии - также обратите внимание, что для юлианского календаря, который может иметь незначительные противоречия с григорианским календарем, который мы используем в настоящее время; вы можете найти более подробную информацию об этом в Википедии), и это может вызвать несколько проблем.

Краткое пояснение для людей, незнакомых с этими обозначениями:

  • « CE » означает «Common Era», что является «дехристианизацией» давних и все еще используемых «AD», «Anno Domini» (поэтому даты CE можно рассматривать как «положительные годы»).
  • « До нашей эры » означает «
    например. Сократ умер в 399 г. до н. Э.

Например, lubridate следует стандарту ISO 8601 (я полагаю, версия 8601: 2004 ? Даты BCE могут обрабатываться с помощью ISO 8601: 2019, но часть документа о свободном доступе не совсем ясна), который начинается с 0000-01-01 , то есть 1 января 1 года до н. э. (-1 год).

Такое написание сбивает с толку, поскольку заставляет думать, что « 0000-01-01 » - это год 0, а « -001-01-01 » - это год -1, когда это год -2, и может вызвать проблемы при вычислении продолжительности ( см. код ниже ).

Кроме того, если они встречаются, «0 CE / AD» или «0 BCE / BC», вероятно, следует проанализировать в Year -1.

Ссылки: Википедия ( ISO 8601 , нулевой год , 1 год до нашей эры , наша эра ...)

Какой-то код, чтобы выразить мою точку зрения

(Лицензия WTFPL: делай, что хочешь, черт возьми)

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.

Проиллюстрируем датами Августа :

  • рождение: 23 сентября 63 г. до н. э.
  • смерть: 19 августа 14 г. н.э.
  • возраст на момент смерти: 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 рейтинги