Comportamiento extraño de la función *localtime()* del paquete Python de Ephem

I could finally install the astronomical calculations Efem package in my Windows7 64 bit machine and Python 3.3.1 thanks to the precompiled version distributed by

In learning to use it I have stumbled on the following oddity, for which I can find no explanation:

Python 3.3.1 (v3.3.1:d9893d13c628, Apr 6 2013, 20:30:21) [MSC v.1600 64 bit (AMD64)] on win32 Type "copyright", "credits" or "license()" for more information.

>>> import ephem

>>> ephem.localtime( ephem.Date( '1970' ) )

datetime.datetime(1970, 1, 1, 1, 0, 0, 3)

>>> ephem.localtime( ephem.Date( '1969' ) )

Rastreo (llamadas recientes más última):

File "", line 1, in ephem.localtime( ephem.Date( '1969' ) )

File "C:\Python33\lib\site-packages\", line 479, in localtime timetuple = time.localtime(calendar.timegm(date.tuple()))

OSError: [Errno 22] Invalid argument


All arguments smaller than 1970 trigger this same error. As ephem.Date() does not seem to be the culprit,

>>> ephem.Date('1969')



I can only conclude that the odd behaviour belongs to ephem.localtime(). Is my use of it mistaken or does the code have some bug?

preguntado el 05 de mayo de 13 a las 17:05

tratar: import time; time.localtime(-31536000.0) (it works fine on Ubuntu). -

2 Respuestas

I'm not directly familiar with the Ephem package, but the behavior you're seeing strongly suggests that what you're seeing is an epoch problem; the Unix epoch being 1970-01-01 00:00:00 UTC, attempts to convert dates prior to that into a Unix time value (an unsigned 32- or 64-bit int) will have undefined results.

A juzgar por the documentation for Ephem's date Método, this shouldn't be happening; that appears to use a different internal time representation whose epoch is 1899-12-31 12:00:00, though I'm not quite sure in what time zone. The Ephem localtime método, sin embargo, returns a Python datetime objeto; Python's own documentation for the datetime module describe datetime as supporting years ranging from 1 to 9999, so the behavior you're seeing would seem to suggest that, somewhere between Ephem's internal date representation and Python's datetime, there's an attempt to convert to a Unix timestamp. Looking at the traceback in your question, we have the following highly suggestive line:

File "C:\Python33\lib\site-packages\", line 479, in localtime \
timetuple = time.localtime(calendar.timegm(date.tuple()))

And in checking the Python documentation for the calendar module, encontramos:


An unrelated but handy function that takes a time tuple such as returned by the gmtime() function in the time module, and returns the corresponding Unix timestamp value, assuming an epoch of 1970, and the POSIX encoding. In fact, time.gmtime() and timegm() are each others’ inverse.

So there's the problem: Ephem localtime() is trying to pass its argument through the Unix timestamp format, which isn't working because dates earlier than the Unix epoch would have to be represented by negative timestamp values, and the Unix timestamp is an unsigned integer.

Now, as for how to go about fixing this, there I'm afraid I may not be of as much help, because I've never used either Ephem or Python. In general, I'd advise modifying Ephem localtime() so that it doesn't try to represent its argument as a Unix timestamp; perhaps there's some more widely ranging time representation you could use, or perhaps you could rework localtime() to operate in terms of the time conversion functions provided by the datetime module.

It also occurs to me that you may wish to report this to the Ephem developers as a bug; if their package is intended to work with dates ranging back to 1899 and possibly before, then presumably they would be interested to know at least one of the functions in their package can't handle anything earlier than 1970. (Of course, their documentation may describe this limitation of localtime(); I didn't find anything about it when I looked, but my review was hardly exhaustive.)

contestado el 05 de mayo de 13 a las 19:05

Thank you very much, Aaron, for your exhaustive explanation. I will continue trying to understand and solve the problem, whose cause you have surely pinpointed. Francisco. - user2284034

Unix timestamp is no an unsigned integer. Corresponding Python methods are documented to accept/return a float number (though precision might be no better than one second depending on the OS) and at least on Ubuntu they accept negative values. - jfs

...why, so it's not. Boy, is my face red. - aarón molinero

It works on my machine (Ubuntu, Python 3.3.0, ephem

>>> import ephem
>>> ephem.Date('1969')
>>> 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)

contestado el 05 de mayo de 13 a las 22:05

This makes it even more odd! Francisco. - user2284034

Apparently time.localtime() can't accept negative arguments en las ventanas : time.localtime(-1) -> ValueError: (22, 'Invalid argument') on 2.7.13 windows 7. Got bitten by it recently and looking for a workaround. I guess this is the reason the OP has problems on windows (probably calling time.localtime internally) - Sr_y_Sra_D

@Mr_and_Mrs_D yes. Functions in the time module are documented as thin wrappers around corresponding platform functions and localtime() on Windows doesn't accept negative values - jfs

Thanks! That should be OP's issue. Any easy workaround in my case? Or is it worth a question ? - Sr_y_Sra_D

@Mr_and_Mrs_D it depends on what your case is, the context. - jfs

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.