由于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 objectPython's own documentation for the datetime moduledatetime描述为支持的年份,范围从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()的这种限制;当我看时没有发现任何有关它的内容,但我的评论几乎没有穷尽。)

07-28 07:53