473,386 Members | 1,873 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,386 software developers and data experts.

datetime strftime methods require year >= 1900

from datetime import date
dt = date(1005,1,1)
print dt.strftime('%Y')

Traceback (most recent call last):
File "<stdin>", line 1, in ?
ValueError: year=1005 is before 1900; the datetime strftime() methods require year >= 1900

Does anyone know of a datetime string formatter that can handles
strftime format strings over the full range that datetime objects
support?

Thanks,
John Hunter
Jul 18 '05 #1
4 9246
John Hunter wrote:
from datetime import date
dt = date(1005,1,1)
print dt.strftime('%Y')
Traceback (most recent call last):
File "<stdin>", line 1, in ?
ValueError: year=1005 is before 1900; the datetime strftime() methods require year >= 1900

Does anyone know of a datetime string formatter that can handles
strftime format strings over the full range that datetime objects
support?

Thanks,
John Hunter


Why would you need to use strftime, if you've already got a year?
print dt.year

1005

HTH
Anna
Jul 18 '05 #2
>>>>> "Anna" == Anna Martelli Ravenscroft <an**@aleax.it> writes:
Anna> Why would you need to use strftime, if you've already got a
Anna> year?
print dt.year

Anna> 1005

That was just a simple-minded example. I need the ability to handle
general format strings over the range of datetime dates.

JDH
Jul 18 '05 #3
John Hunter wrote:
Does anyone know of a datetime string formatter that can handles
strftime format strings over the full range that datetime objects
support?


Here's what the Python source says

/* Give up if the year is before 1900.
* Python strftime() plays games with the year, and different
* games depending on whether envar PYTHON2K is set. This makes
* years before 1900 a nightmare, even if the platform strftime
* supports them (and not all do).
* We could get a lot farther here by avoiding Python's strftime
* wrapper and calling the C strftime() directly, but that isn't
* an option in the Python implementation of this module.
*/

The underlying time.strftime module supports special
behaviour for dates < 1900.
time.accept2dyear 1 time.strftime("%Y", datetime.date(20, 1, 1).timetuple()) '2020' time.accept2dyear = 0
time.strftime("%Y", datetime.date(20, 1, 1).timetuple()) Traceback (most recent call last):
File "<stdin>", line 1, in ?
ValueError: year >= 1900 required
One concern about your request is, what a date mean
when you get before 1900? I assume you want the proleptic
Gregorian calendar, that is, to apply it even when and
where it wasn't in use.

One way to fake it is to move the date to a date in the
supported time range which starts on the same day, then
use strftime on that new date.

It's not enough to find the fake year number in the
resulting string and convert it into the real year
number. After all, the format string might be
"1980 %Y" and if the %Y expands to 1980 in your shifted
time frame then you don't know which to change.

To figure that out, move the date forward by 28 years
(which is the repeat cycle except for the non-leap
centuries) and do it again. The parts of the two
strings that differ indicate where to put the change.

I tried to write this function but I wasn't sure
how to handle the non-leap year centuries. It seems
to be that those are the same as 6 years later, so
that Jan. 1900's calendar looks like 1906's.

Here's what I came up with. Seems to work.
# Format a datetime.date using the proleptic Gregorian calendar

import time, datetime

def _findall(text, substr):
# Also finds overlaps
sites = []
i = 0
while 1:
j = text.find(substr, i)
if j == -1:
break
sites.append(j)
i=j+1
return sites

# I hope I did this math right. Every 28 years the
# calendar repeats, except through century leap years
# excepting the 400 year leap years. But only if
# you're using the Gregorian calendar.

def strftime(dt, fmt):
# WARNING: known bug with "%s", which is the number
# of seconds since the epoch. This is too harsh
# of a check. It should allow "%%s".
fmt = fmt.replace("%s", "s")
if dt.year > 1900:
return time.strftime(fmt, dt.timetuple())

year = dt.year
# For every non-leap year century, advance by
# 6 years to get into the 28-year repeat cycle
delta = 2000 - year
off = 6*(delta // 100 + delta // 400)
year = year + off

# Move to around the year 2000
year = year + ((2000 - year)//28)*28
timetuple = dt.timetuple()
s1 = time.strftime(fmt, (year,) + timetuple[1:])
sites1 = _findall(s1, str(year))

s2 = time.strftime(fmt, (year+28,) + timetuple[1:])
sites2 = _findall(s2, str(year+28))

sites = []
for site in sites1:
if site in sites2:
sites.append(site)

s = s1
syear = "%4d" % (dt.year,)
for site in sites:
s = s[:site] + syear + s[site+4:]
return s

# Make sure that the day names are in order
# from 1/1/1 until August 2000
def test():
s = strftime(datetime.date(1800, 9, 23),
"%Y has the same days as 1980 and 2008")
if s != "1800 has the same days as 1980 and 2008":
raise AssertionError(s)

print "Testing all day names from 0001/01/01 until 2000/08/01"
days = []
for i in range(1, 10):
days.append(datetime.date(2000, 1, i).strftime("%A"))
nextday = {}
for i in range(8):
nextday[days[i]] = days[i+1]

startdate = datetime.date(1, 1, 1)
enddate = datetime.date(2000, 8, 1)
prevday = strftime(startdate, "%A")
one_day = datetime.timedelta(1)

testdate = startdate + one_day
while testdate < enddate:
if (testdate.day == 1 and testdate.month == 1 and
(testdate.year % 100 == 0)):
print testdate.year
day = strftime(testdate, "%A")
if nextday[prevday] != day:
raise AssertionError(str(testdate))
prevday = day
testdate = testdate + one_day

if __name__ == "__main__":
test()

strftime(datetime.date(1850, 8, 2), "%Y/%M/%d was a %A") '1850/00/02 was a Friday'


% cal 8 1850
August 1850
S M Tu W Th F S
1 2 3
4 5 6 7 8 9 10
11 12 13 14 15 16 17
18 19 20 21 22 23 24
25 26 27 28 29 30 31

Andrew
da***@dalkescientific.com
Jul 18 '05 #4
Andrew Dalke wrote:
>>> strftime(datetime.date(1850, 8, 2), "%Y/%M/%d was a %A")
'1850/00/02 was a Friday'


While "%Y/%m/%d was a %A" gives

1850/08/02 was a Friday

% cal 8 1850
August 1850
S M Tu W Th F S
1 2 3
4 5 6 7 8 9 10
11 12 13 14 15 16 17
18 19 20 21 22 23 24
25 26 27 28 29 30 31


I once played around with an alternate time
format string that allowed

%(2000)/%(12)/%(31) to mean %Y, %m, %d.
%(Jan)/%(January)/%(Mon)/%(Monday) to mean %b/%B/%a/%A

because I forget which name is which.

Andrew
da***@dalkescientific.com

Jul 18 '05 #5

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

0
by: fowlertrainer | last post by:
Hi ! I think that I have been found a bug in mx.DateTime... So: I use FireBird, and in this RDBMS the datetime fields are "doubles". So if I set them to 0, the values the fields are '1899-12-30...
3
by: Martin Bless | last post by:
Below is what I'm currently using to construct datatime objects from strings. Date and time objects are made up similar. To and from string conversions are frequently needed in SQL neighborhood. ...
5
by: Sheila King | last post by:
I have a web app that has been running just fine for several months under Python 2.2.2. We are preparing to upgrade the server to run Python 2.4.1. However, part of my web app is throwing an...
0
by: David Pratt | last post by:
Hi. I am creating a couple of small methods to help me manage time from UTC as standard but I am getting strange results. If I start with a datetime of 2005-12-12 14:30:00 in timezone...
5
by: A.M | last post by:
Hi, I have a datetime value and want to format it to "June 1, 2006" shape. How can I do that? Thank you,
0
by: DeePeeJay | last post by:
Hello, Is there a better way to convert separate integer values, representing Day, Month, Year, Hour, Minute and Second to DateTime? I work in the Automation Industry and PLC (Programmable...
7
by: eskgwin | last post by:
I have this piece of code that takes a day of the year and converts it to the month and day of month: char start_mon; char start_day; int s_day = 84; time_t daysecs = (s_day * 86400) - 1;...
0
yasirmturk
by: yasirmturk | last post by:
Standard Date and Time Functions The essential date and time functions that every SQL Server database should have to ensure that you can easily manipulate dates and times without the need for any...
0
by: taylorcarr | last post by:
A Canon printer is a smart device known for being advanced, efficient, and reliable. It is designed for home, office, and hybrid workspace use and can also be used for a variety of purposes. However,...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.