由于http://www.lfd.uci.edu/%7Egohlke/pythonlibs/分发的预编译版本,我终于可以在我的Windows7 64位计算机和Python 3.3.1中安装天文计算 Ephem 程序包。
在学习使用它时,我偶然发现了以下奇怪的事情,为此我找不到任何解释:
在win32上的Python 3.3.1(v3.3.1:d9893d13c628,2013年4月6日,20:30:21)[MSC v.1600 64位(AMD64)] 输入“copyright”,“credits”或“license()”以获取更多信息。>>> 导入ephem
>>> ephem.localtime(ephem.Date('1970'))
datetime.datetime(1970,1,1,1,0,0,3)
>>> ephem.localtime(ephem.Date('1969'))
追踪(最近一次呼叫最后一次):
文件“”,第1行,in ephem.localtime(ephem.Date('1969'))
文件“C:\ Python33 \ lib \ site-packages \ ephem__init __。py”,第479行,在本地时间 timetuple = time.localtime(calendar.timegm(date.tuple()))
OSError:[Errno 22]参数无效
>>>
小于 1970 的所有参数都会触发同样的错误。由于 ephem.Date()似乎不是罪魁祸首,
>>> ephem.Date('1969')
25202.5
>>>
我只能得出结论,奇怪的行为属于 ephem.localtime()。我使用它是错误的还是代码有一些错误?
答案 0 :(得分:2)
我并不直接熟悉Ephem套餐,但你所看到的行为强烈暗示你所看到的是一个时代问题; Unix纪元是1970-01-01 00:00:00 UTC,尝试将之前的日期转换为Unix时间值(无符号的32位或64位int)将产生未定义的结果。
以the documentation for Ephem's date
method来判断,这不应该发生;似乎使用了一个不同的内部时间表示,其时间段是1899-12-31 12:00:00,虽然我不太确定在什么时区。然而,Ephem localtime
方法returns a Python datetime
object; Python's own documentation for the datetime module将datetime
描述为支持年份介于1到9999之间,因此您所看到的行为似乎表明,在Ephem的内部日期表示与Python的datetime
之间,有一种尝试转换为Unix时间戳。看一下你问题中的追溯,我们有以下极具启发性的一句话:
File "C:\Python33\lib\site-packages\ephem__init__.py", line 479, in localtime \
timetuple = time.localtime(calendar.timegm(date.tuple()))
在检查the Python documentation for the calendar module时,我们发现:
calendar.timegm(元组)
一个不相关但很方便的函数,它接受一个时间元组,例如时间模块中的gmtime()函数返回的,并返回相应的Unix时间戳值,假定一个1970年的纪元,并且POSIX编码。事实上,time.gmtime()和timegm()彼此是反向的。
所以有问题:Ephem localtime()
试图通过Unix时间戳格式传递它的参数,这种格式不起作用,因为早于Unix纪元的日期必须用负时间戳值表示,并且Unix时间戳是无符号整数。
现在,关于如何解决这个问题,恐怕我可能没那么多帮助,因为我从未使用过Ephem或Python。一般来说,我建议修改Ephem localtime()
,以便它不会试图将其参数表示为Unix时间戳;也许你可以使用更广泛的时间表示,或者你可以返工localtime()
来操作日期时间模块提供的时间转换功能。
我也想到你可能希望向Ephem开发者报告这个错误;如果他们的软件包打算使用的日期可以追溯到1899年之前,可能之前,那么他们可能会有兴趣知道他们的软件包中至少有一个函数不能在1970年之前处理任何事情。(当然,他们的文档可能会描述localtime()
的这种限制;我看的时候没有找到任何关于它的内容,但我的评论并不详尽。)
答案 1 :(得分:1)
它适用于我的机器(Ubuntu,Python 3.3.0,ephem 3.7.5.1):
>>> import ephem
>>> ephem.Date('1969')
25202.5
>>> d = ephem.Date('1969')
>>> d.datetime() # utc
datetime.datetime(1969, 1, 1, 0, 0)
>>> ephem.localtime(d) # local timezone
datetime.datetime(1969, 1, 1, 6, 0, 0, 2)