28

我打算用 Python 构建一个需要广泛处理 BC 日期的应用程序(在数据库中存储和检索,进行计算)。大多数日期将具有各种不确定性,例如“大约公元前 2000 年”。

我知道 Python 的日期时间库只处理公元 1 年的日期。

到目前为止,我只找到了 FlexiDate。还有其他选择吗?

编辑:最好的方法可能是将它们存储为字符串(将 String 作为基本数据类型),并且 - 正如建议的那样 - 有一个自定义的 datetime 类,它可以对它产生一些数字意义。对于大多数人来说,日期似乎只包含一年。有一些有趣的问题需要解决,例如“公元前 500 年早期”、“公元前 1600 年和公元前 1500 年之间”、“公元前 1800 年之前”。

4

4 回答 4

10

天文学家和航空航天工程师必须处理 BC 日期和连续的时间线,这就是您搜索的谷歌上下文。

AstropyTime课程将为您工作(甚至比您希望的更精确和完整)。pip install astropy你正在路上。

如果你自己动手,你应该复习瓦拉多关于日期的章节中的一些公式。将日期从儒略历转换为公历等需要很多晦涩的软糖因素。

于 2013-11-08T22:43:07.513 回答
4

这是一个有趣的问题,这样的类还不存在似乎很奇怪(重新@joel Cornett评论)如果你只工作几年,它会简化你的类来处理整数而不是日历日期 - 你可以使用字典文本描述(公元前10年)和整数值(-10)编辑:我用谷歌搜索了这个:

http://code.activestate.com/lists/python-list/623672/

于 2013-04-07T08:33:05.773 回答
3

NASA Spice 函数通过多种格式的转换非常好地处理 BC。在这些示例中begin_dateend_date包含与输入日期相对应的 J2000 纪元之后的 TDB 秒数:

import spiceypy as spice

# load a leap second kernel
spicey.furnsh("path/to/leap/second/kernel/naif0012.tls")

begin_date = spice.str2et('13201 B.C. 05-06 00:00')
end_date = spice.str2et('17191 A.D. 03-15 00:00')  

str2et() 的文档、 输入格式文档以及 Leapsecond 内核文件可通过 NASA Spice 主页获得。

从 datetime 或其他时间方法转换为 spice 很简单:

if indate.year < 0.0:
    spice_indate = str(indate.year) + ' B.C. ' + sindate[-17:]
    spice_indate = str(spice_indate)[1:]
else: 
    spice_indate = str(indate.year) + ' A.D. ' + sindate[-17:]

'2018 B.C. 03-31 19:33:38.44'

其他功能包括:TIMOUT、TPARSE 都在 J2000 纪元秒之间转换。

这些函数在 python 中通过spiceypy可用,例如通过安装pip3 install spiceypy

于 2018-04-01T00:25:54.540 回答
2

这是一个老问题,但我也有同样的问题,发现这篇文章宣布了 datautil,它旨在处理如下日期:

  • 遥远的过去和未来的日期,包括 BC/BCE 日期
  • 各种格式的日期:1890 年 1 月、1890 年 1 月、1890 年 12 月 1 日、1890 年春季等
  • 不同精度的日期:例如 1890、1890-01(即 1890 年 1 月)、1890-01-02
  • 不精确的日期:c1890、1890?、fl 1890 等

安装只是

pip install datautil

到目前为止,我只探索了几分钟,但注意到它不接受 str 作为参数(仅 unicode)并且它实现了自己的日期类(Flexidate,'ISO8601 的略微扩展版本'),这是排序也许有用。

>>> from datautil.date import parse
>>> parse('Jan 1890')

error: 'str' object has no attribute 'read'

>>> fd = parse(u'Jan 1890')
<class 'datautil.date.FlexiDate'> 1890-01

fd.as_datetime()
>>> datetime.datetime(1890, 1, 1, 0, 0)

>>> bc = parse(u'2000BC')
<class 'datautil.date.FlexiDate'> -2000

可惜...

>>> bc.as_datetime()
ValueError: year is out of range

对我来说不幸的是,我正在寻找可以处理带有“ circa ”(c.,ca,ca.,circ。或 cca。)的日期的东西。

>>> ca = parse(u'ca 1900')
<class 'datautil.date.FlexiDate'>  [UNPARSED: ca 1900]

哦,好吧-我想我总是可以发送拉取请求;-)

于 2015-03-25T20:53:20.087 回答