4

I have to get a datetime from a float using Python. I am tryint to use the following code:

import time
print (time.strftime("%Y-%m-%d %H:%M:%S", time.gmtime(float(63650571169.50261))))

But when executing this code, I get an error:

OSError: [Errno 22] Invalid argument

The sys.float_info.max displays 1.7976931348623157e+308.

How do I convert this float number into a datetime?

Stephen Rauch
  • 47,830
  • 31
  • 106
  • 135
Zoya
  • 1,195
  • 2
  • 12
  • 14
  • 5
    The code works for me on Python 3.6.1 on OS X, producing `3987-01-03 10:12:49` – Martijn Pieters Mar 29 '17 at 16:51
  • What OS do you use? Works for me on 3.4.5 on Linux, same answer as above. – DYZ Mar 29 '17 at 16:52
  • If we can't reproduce this but you *can*, you probably will have to do a strace to find out what system call failed. See [IOError: \[Errno 22\] Invalid Argument with clock() being passed in](//stackoverflow.com/q/3239883) – Martijn Pieters Mar 29 '17 at 16:54
  • @MartijnPieters initial test, I can _partially_ replicate in Python 2.7 on Windows, with `ValueError: (22, 'Invalid argument')` – roganjosh Mar 29 '17 at 16:55
  • @roganjosh: for the `time.gmtime()` part or the `time.strftime()` part? – Martijn Pieters Mar 29 '17 at 16:56
  • @MartijnPieters `a = time.gmtime(float(63650571169.50261))` throws the same error. – roganjosh Mar 29 '17 at 16:57
  • @roganjosh: So it seems that the OP is on an OS where the system call to produce the time struct doesn't support values this far into the future then. – Martijn Pieters Mar 29 '17 at 16:58
  • Thank you for your reply, i'm using windows 7 64 bits and python version 3.5 – Zoya Mar 29 '17 at 16:59
  • @MartijnPieters To be specific, I'm also on Windows 7 64 bit and Python 2.7.9. The reporting of the error has presumably changed between Python versions then, with Windows 7 being the culprit. – roganjosh Mar 29 '17 at 17:01
  • I am on Windows 7 64 bit and Python 3.5.1, and I get the same error that OP does. Playing around with it, it looks like the highest value `gmtime` can accept is `32535291599`. I wonder if that number is significant somehow? It's not particularly round in hex or anything... – Kevin Mar 29 '17 at 17:10
  • Note: only the integer portion of your floating point value is used (it can be rounded up or down, but the decimal portion is discarded). Since you are getting a 22 error, I can only assume that Windows 7 uses *32 bits* for the `time_t` type, meaning you can't use dates beyond 2038.. – Martijn Pieters Mar 29 '17 at 17:12
  • @Kevin: hrm, that's a value greater than what a 32-bit signed integer could store. Does Windows 7 have a Year 3K issue? – Martijn Pieters Mar 29 '17 at 17:13
  • @roganjosh: are you using a 32-bit Python binary perhaps? What does `import sys; print(sys.maxint)` produce? – Martijn Pieters Mar 29 '17 at 17:20
  • Oops, I misremembered. I'm actually on Window 10. But that just means if there's an OS limitation at play here, it has lingered for a couple versions. – Kevin Mar 29 '17 at 17:22
  • @MartijnPieters `2147483647` so actually it probably is. This is what came with Enthought Canopy though, and will do 64-bit calculations just fine. Then again, Windows converts int to 32-bit signed integer when using `numpy` e.g. my confusion here http://stackoverflow.com/questions/41705764/numpy-sum-giving-strange-results-on-large-arrays – roganjosh Mar 29 '17 at 17:22
  • According to [What are valid arguments for localtime function?](http://stackoverflow.com/q/35048512/953482), the Windows function `localtime` has an upper limit of 23:59:59, December 31, 3000, UTC. If `gmtime` calls `localtime` (or some other time function with the same limitation), then that would explain why it doesn't work on very-far-future dates. – Kevin Mar 29 '17 at 17:30
  • @Kevin deleted last comment as noticed UTC and I'm currently in UK daylight saving time so I thought I made a mistake, but actually yes, it wouldn't explain, I don't think, why your max int input (which is also the same as mine) gives me `3001-01-01 20:59:59`. – roganjosh Mar 29 '17 at 17:35

2 Answers2

1

It looks like your OS is using the ISO 8601:2004 (clause 4.3.2.1 The Gregorian calendar) with the epoch at Year 0. This can be converted by applying the correct zero offset as:

Code:

import datetime as dt

# define some constants
epoch = dt.datetime(1970, 1, 1)
gregorian_8601_to_unix_epoch = 62167305600

def gregorian_8601_to_datetime(gregorian_8601_seconds):

    # get number of seconds from epoch
    from_epoch = gregorian_8601_seconds - gregorian_8601_to_unix_epoch

    # convert to python datetime
    return epoch + dt.timedelta(seconds=from_epoch)

Test Code:

print(gregorian_8601_to_datetime(63650571169.50261))

Results:

2017-01-01 10:12:49.502609
Stephen Rauch
  • 47,830
  • 31
  • 106
  • 135
  • Thank you for your reply, In fact, the datenum is number of milliseconds and the datetime must be from 2010-11-04 to 2011-06-11. An example of datetime:2010-11-04 00:03:50.209589. – Zoya Apr 03 '17 at 11:06
  • So, you think that `63650571169.50261` is a number of milliseconds from a base time, and it represents a date between 2010-11-04 to 2011-06-11? This is highly unlikely since it would mean the epoch date was sometime between `2008-10-28` and `2009-06-04`. – Stephen Rauch Apr 03 '17 at 14:41
  • Thank you for your answer @Stephan, for simple examples its worked but then I wanted to use it as a function for bigger computations and I had the error bellow : OverflowError: Python int too large to convert to C long – Amy21 Sep 05 '17 at 12:07
  • @Amy21, thanks for the feedback. The best thing for you to do is ask a new question. Be sure to include an [MCVE](http://stackoverflow.com/help/mcve), and if desired, provide a link to this answer. You can put another comment here with a link to the new question if you want me to be sure and see it. – Stephen Rauch Sep 05 '17 at 14:09
0

Try this :

import datetime
print datetime.datetime.fromtimestamp(63650571169.50261)
#3987-01-03 05:12:49.502609
mongotop
  • 7,114
  • 14
  • 51
  • 76
  • 1
    It doesn't work, the same error persist. i'm using windows 7 64 bits and python version 3.5 – Zoya Mar 29 '17 at 17:00