oracle 有没有办法在 Python 中对 1900 年之前的日期使用类似 strftime 的函数?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1643967/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Is there any way to use a strftime-like function for dates before 1900 in Python?
提问by Jason Baker
I didn't realize this, but apparently Python's strftime
function doesn't support dates before 1900:
我没有意识到这一点,但显然 Python 的strftime
函数不支持 1900 年之前的日期:
>>> from datetime import datetime
>>> d = datetime(1899, 1, 1)
>>> d.strftime('%Y-%m-%d')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ValueError: year=1899 is before 1900; the datetime strftime() methods require year >= 1900
I'm sure I could hack together something myself to do this, but I figure the strftime
function is there for a reason (and there also is a reason why it can't support pre-1900 dates). I need to be able to support dates before 1900. I'd just use str
, but there's too much variation. In other words, it may or may not have microseconds or it may or may not have a timezone. Is there any solution to this?
我确信我可以自己编写一些东西来做到这一点,但我认为这个strftime
函数存在是有原因的(而且它不能支持 1900 年前的日期也是有原因的)。我需要能够支持 1900 年之前的日期。我只是使用str
,但是变化太多了。换句话说,它可能有也可能没有微秒,或者可能有也可能没有时区。有什么解决办法吗?
If it makes a difference, I'm doing this so that I can write the data to a text file and load it into a database using Oracle SQL*Loader.
如果它有所作为,我这样做是为了将数据写入文本文件并使用 Oracle SQL*Loader 将其加载到数据库中。
I essentially ended up doing Alex Martelli's answer. Here's a more complete implementation:
我基本上最终做了亚历克斯·马泰利的回答。这是一个更完整的实现:
>>> from datetime import datetime
>>> d = datetime.now()
>>> d = d.replace(microsecond=0, tzinfo=None)
>>> str(d)
'2009-10-29 11:27:27'
The only difference is that str(d)
is equivalent to d.isoformat(' ')
.
唯一的区别str(d)
是相当于d.isoformat(' ')
.
采纳答案by Alex Martelli
isoformatworks on datetime
instances w/o limitation of range:
isoformat适用于datetime
没有范围限制的实例:
>>> import datetime
>>> x=datetime.datetime(1865, 7, 2, 9, 30, 21)
>>> x.isoformat()
'1865-07-02T09:30:21'
If you need a different-format string it's not too hard to slice, dice and remix pieces of the string you get from isoformat
, which is very consistent (YYYY-MM-DDTHH:MM:SS.mmmmmm
, with the dot and following microseconds omitted if microseconds are zero).
如果您需要不同格式的字符串,那么对您从中获得的字符串的片段进行切片、切块和重新混合并不太难isoformat
,这是非常一致的(YYYY-MM-DDTHH:MM:SS.mmmmmm
如果微秒为零,则省略点和后面的微秒)。
回答by Dave Webb
The documentation seems pretty clear about this:
The exact range of years for which
strftime()
works also varies across platforms. Regardless of platform, years before 1900 cannot be used.
工作的确切年份范围
strftime()
也因平台而异。无论平台如何,1900 年之前的年份都不能使用。
So there isn't going to be a solution that uses strftime()
. Luckily, it's pretty straightforward to do this "by hand":
所以不会有一个使用strftime()
. 幸运的是,“手动”执行此操作非常简单:
>>> "%02d-%02d-%02d %02d:%02d" % (d.year,d.month,d.day,d.hour,d.minute)
'1899-01-01 00:00'
回答by Cat Plus Plus
mxDateTime
can handle arbitrary dates. Python's time
and datetime
modules use UNIX timestamps internally, that's why they have limited range.
mxDateTime
可以处理任意日期。Pythontime
和datetime
模块在内部使用 UNIX 时间戳,这就是它们的范围有限的原因。
In [5]: mx.DateTime.DateTime(1899)
Out[5]: <mx.DateTime.DateTime object for '1899-01-01 00:00:00.00' at 154a960>
In [6]: DateTime.DateTime(1899).Format('%Y-%m-%d')
Out[6]: 1899-01-01
回答by Mark
This is from the matplotlib source. Could provide a good starting point for rolling your own.
这是来自matplotlib 源。可以为您自己的滚动提供一个很好的起点。
def strftime(self, dt, fmt):
fmt = self.illegal_s.sub(r"", fmt)
fmt = fmt.replace("%s", "s")
if dt.year > 1900:
return cbook.unicode_safe(dt.strftime(fmt))
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 = self._findall(s1, str(year))
s2 = time.strftime(fmt, (year+28,) + timetuple[1:])
sites2 = self._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 cbook.unicode_safe(s)
回答by bua
This is the "feature" of the ctime library (UTF). Also You may have problem above 2038.
这是 ctime 库 (UTF) 的“特性”。您也可能在 2038 以上有问题。