由于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)]
键入“版权”,“信用”或“ license()”以获取更多信息。
>>>导入ephem
>>> ephem.localtime(ephem.Date('1970'))
datetime.datetime(1970,1,1,1,0,0,3)
>>> ephem.localtime(ephem.Date('1969'))
追溯(最近一次通话):
文件“”,第1行,在
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()。我对它的使用是错误的还是代码中有错误?
最佳答案
我并不直接熟悉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(tuple)
一个不相关但方便的函数,它采用一个时间元组,例如由time模块中的gmtime()函数返回,并返回相应的Unix时间戳值(假定为1970年)和POSIX编码。实际上,time.gmtime()和timegm()彼此相反。
因此存在问题:Ephem
localtime()
试图通过Unix时间戳格式传递其参数,该格式不起作用,因为早于Unix纪元的日期必须由负的时间戳值表示,并且Unix时间戳是无符号的整数。现在,关于如何解决此问题,恐怕我可能没有太多帮助,因为我从未使用过Ephem或Python。通常,我建议修改Ephem
localtime()
,以免它试图将其参数表示为Unix时间戳。也许可以使用一些更广泛的时间表示形式,或者您可以根据datetime模块提供的时间转换功能对localtime()
进行重做。在我看来,您可能希望将此错误报告给Ephem开发人员。如果他们的软件包打算使用可追溯到1899年甚至更早的日期,那么大概他们会想知道他们软件包中的至少一个功能不能处理1970年以前的任何事情。(当然,他们的文档可能描述
localtime()
的这种限制;当我看时没有发现任何有关它的内容,但我的评论几乎没有穷尽。)