Use datetime.strftime() on years before 1900? ("require year >= 1900")

Question:

I used :
utctime = datetime.datetime(1601,1,1) + datetime.timedelta(microseconds = tup[5])
last_visit_time = "Last visit time:"+ utctime.strftime('%Y-%m-%d %H:%M:%S')

But I have the time of 1601, so the error show:
ValueError: year=1601 is before 1900; the datetime strftime() methods require year >= 1900

I used python2.7, how can I make it? Thanks a lot!

Asked By: Alex

||

Answers:

You can do the following:

>>> utctime.isoformat()
'1601-01-01T00:00:00.000050'

Now if you want to have exactly the same format as above:

iso = utctime.isoformat()
tokens = iso.strip().split("T")
last_visit_time = "Last visit time: %s %s" % (tokens[0], tokens[1].strip().split(".")[0])

Not that there seems to be a patch for strftime to fix this behavior here (not tested)

Answered By: Charles Menguy

the isoformat method accepts a parameter specifing the character(s) dividing the date part from the time part of a datetime obj in its representation. Therefore:

>>> utctime.isoformat(" ")
'1601-01-01 00:00:00.000050'

should do it.
Furthermore, if you want to remove the microseconds you can operate a split.

>>> utctime.isoformat(" ").split(".")[0]
'1601-01-01 00:00:00'
Answered By: Michele Soltanto

There are various ways to alter strftime so that it handles pre-1900 dates:

  • There’s a recipe at ASPN that gives you a separate strftime method that you can call with a date object: aspn_recipe.strftime(dt, fmt) if you set it up in a module yourself
  • As @stephen-rumbalski said, the external mxDateTime package supports this; but that’s using a totally different date object system
  • As of version 1.5, the virtualtime package will patch both time.strftime and datetime.datetime.strftime to behave as in Python 3.3+. You can take advantage of this without enabling the other virtual time functions. (Disclaimer: I work on this package)

Note that Python 2.7, 3.0 and 3.1 have errors before the year 1900, Python 3.2 has errors before the year 1000. Additionally, pre-3.2 versions interpret years between 0 and 99 as between 1969 and 2068. Python versions from 3.3 onward support all positive years in datetime (and negative years in time.strftime), and time.strftime doesn’t do any mapping of years between 0 and 99.

The original Python bug explains that they decided that this was a feature in Python 2.7 (presumably since it avoided lack of system strftime support for these dates), and then gradually worked on it in the Python 3 series, by reimplementing functionality.

Answered By: David Fraser

I recommend using arrow (which is an abstraction package on datetime and dateutil), it’s really easy to handle every kind of datetime objects, even in Python 2.6/7.x and with dates prior to 1900.

For example:

>>> import arrow

>>> in_date_str = "1853-10-30T13:36:41.942623+00:00"
>>> in_date_obj = arrow.get(crea)
>>> print(in_date_obj)
arrow[1853-10-30T13:36:41.942623+00:00]>

# basic formatting
>>> in_date_obj.format()
u'1853-10-30 13:36:41-00:00'

# advanced formatting
>>> in_date_obj.format("dddd D MMMM YYYY", "fr_FR")
u'Dimanche 30 Octobre 1853'

# humanized delta
>>> in_date_obj.humanize()
u'162 years ago'
# easy localization handling
>>> in_date_obj.humanize(locale="fr_FR")
u'il y a 162 ans'
Answered By: Guts
Categories: questions Tags: , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.