1 # Python's datetime strftime doesn't handle dates before 1900.
2 # These classes override date and datetime to support the formatting of a date
3 # through its full "proleptic Gregorian" date range.
5 # Based on code submitted to comp.lang.python by Andrew Dalke
7 # >>> datetime_safe.date(1850, 8, 2).strftime("%Y/%M/%d was a %A")
8 # '1850/08/02 was a Friday'
10 from datetime
import date
as real_date
, datetime
as real_datetime
14 class date(real_date
):
15 def strftime(self
, fmt
):
16 return strftime(self
, fmt
)
18 class datetime(real_datetime
):
19 def strftime(self
, fmt
):
20 return strftime(self
, fmt
)
22 def combine(self
, date
, time
):
23 return datetime(date
.year
, date
.month
, date
.day
, time
.hour
, time
.minute
, time
.microsecond
, time
.tzinfo
)
26 return date(self
.year
, self
.month
, self
.day
)
29 "Generate a safe date from a datetime.date object."
30 return date(d
.year
, d
.month
, d
.day
)
34 Generate a safe datetime from a datetime.date or datetime.datetime object.
36 kw
= [d
.year
, d
.month
, d
.day
]
37 if isinstance(d
, real_datetime
):
38 kw
.extend([d
.hour
, d
.minute
, d
.second
, d
.microsecond
, d
.tzinfo
])
41 # This library does not support strftime's "%s" or "%y" format strings.
42 # Allowed if there's an even number of "%"s because they are escaped.
43 _illegal_formatting
= re
.compile(r
"((^|[^%])(%%)*%[sy])")
45 def _findall(text
, substr
):
50 j
= text
.find(substr
, i
)
57 def strftime(dt
, fmt
):
59 return super(type(dt
), dt
).strftime(fmt
)
60 illegal_formatting
= _illegal_formatting
.search(fmt
)
61 if illegal_formatting
:
62 raise TypeError("strftime of dates before 1900 does not handle" + illegal_formatting
.group(0))
65 # For every non-leap year century, advance by
66 # 6 years to get into the 28-year repeat cycle
68 off
= 6 * (delta
// 100 + delta
// 400)
71 # Move to around the year 2000
72 year
= year
+ ((2000 - year
) // 28) * 28
73 timetuple
= dt
.timetuple()
74 s1
= time
.strftime(fmt
, (year
,) + timetuple
[1:])
75 sites1
= _findall(s1
, str(year
))
77 s2
= time
.strftime(fmt
, (year
+28,) + timetuple
[1:])
78 sites2
= _findall(s2
, str(year
+28))
86 syear
= "%4d" % (dt
.year
,)
88 s
= s
[:site
] + syear
+ s
[site
+4:]