使用Python3检测日期格式并将其转换为MM-DD-YYYY

3

我正在尝试使用Python 3.6将日期格式转换并使它们在整个文档中保持一致。
以下是我的文档中日期的示例:(由于文档很大,可能会有其他格式。)

9/21/1989
19640430
6/27/1980
5/11/1987
Mar 12 1951
2 aug 2015

我已经查看了datetime库。但是不知道如何自动检测和更改日期格式。目前为止,我已经查看了以下内容:

>>> from datetime import datetime
>>> oldformat = '20140716'
>>> datetimeobject = datetime.strptime(oldformat,'%Y%m%d')
>>> newformat = datetimeobject.strftime('%m-%d-%Y')
>>> print (newformat)
07-16-2014

但我不知道如何让程序自动检测日期模式并将它们转换为统一的日期格式mm/dd/yyyy。请建议我在Python 3.6中应该怎么做以实现我的目标。

2
你打算如何解释像 2/4/1994 这样的日期?是二月四日还是四月二日? - Kevin
是的,当然可以。我正在尝试将日期格式设置为“MM/DD/yyyy”。是的,您所提到的是正确的。 - Jaffer Wilson
@Kevin:通常如果日期末尾有完整的年份,那么日期格式应该是月/日/年。 - l'L'l
2
在美国可能是这样,但在欧洲他们写的方式正好相反。 - Kevin
@l'L'l 是的,你说得对。 - Jaffer Wilson
显示剩余4条评论
3个回答

9

没有通用的Python方法来完成这个,但我建议使用正则表达式来识别类型,然后正确地转换它:

Python示例

import re
from datetime import datetime

with open("in.txt","r") as fi, open("out.txt","w") as fo:
    for line in fi:
        line = line.strip()
        dateObj = None
        if re.match(r"^\d{8}$", line):
            dateObj = datetime.strptime(line,'%Y%m%d')
        elif re.match(r"^\d{1,2}/", line):
            dateObj = datetime.strptime(line,'%m/%d/%Y')
        elif re.match(r"^[a-z]{3}", line, re.IGNORECASE):
            dateObj = datetime.strptime(line,'%b %d %Y')
        elif re.match(r"^\d{1,2} [a-z]{3}", line, re.IGNORECASE):
            dateObj = datetime.strptime(line,'%d %b %Y')
        fo.write(dateObj.strftime('%m-%d-%Y') + "\n")

输入示例

9/21/1989
19640430
6/27/1980
5/11/1987
Mar 12 1951
2 aug 2015

示例输出

09-21-1989
04-30-1964
06-27-1980
05-11-1987
03-12-1951
08-02-2015

嘿,这也是一个不错的答案。谢谢你的回复。 - Jaffer Wilson

9
我尝试在我的代码中使用dateutil库来检测任何格式的日期字符串,然后使用datetime库将其转换为适当的格式。
以下是代码:
>>> import dateutil.parser
>>> yourdate = dateutil.parser.parse("May 24 2016")
>>>
>>> print(yourdate)
2016-05-24 00:00:00
>>> from datetime import datetime
>>> oldformat = yourdate
>>> datetimeobject = datetime.strptime(str(oldformat),'%Y-%m-%d  %H:%M:%S')
>>> newformat = datetimeobject.strftime('%m-%d-%Y')
>>> print (newformat)
05-24-2016

这个有效。

查看输出图像:
测试图像


在尝试时,我在datetimeobject = datetime.strptime(oldformat,'%Y-%m-%d %H:%M:%S')上遇到了“strptime() argument 1 must be str, not datetime.datetime”错误。 - TanviP
@TanviP 你有试过我的完整代码吗?我猜你遇到的错误不是因为我的代码,而是你自己代码的问题。 - Jaffer Wilson
我不明白你们到底遇到了什么问题?请具体说明。这个对我来说是有效的,现在仍然有效。也许你有一个不同的问题定义,因此,请尝试其他方法。 - Jaffer Wilson
Jaffer,请问您能告诉我们您正在使用的Python版本和dateutil.__version__吗?这段代码对我来说失败了,因为datetime.strptime需要一个str,而接收到的是类型为datetime.datetime的yourdate。这个不会失败:datetimeobject = datetime.strptime(str(oldformat),'%Y-%m-%d %H:%M:%S')然而,由于dateutil.parser.parse返回datetime.datetime,您可以使用更少的代码行通过yourdate.strftime('%m-%d-%Y')获得相同的结果。 - Edvard Rejthar
也许我记错了版本,可能是2.7吧。目前我正在使用Python 3.5.0。我收到了相同的错误,我会编辑答案以便您得到想要的内容。请允许我这样做。 - Jaffer Wilson
仅供记录,我试图在图像的exif数据上使用dateutil.parser.parse,但它完全失败了。 exif日期字符串为“2009:03:29 12:30:23”,解析器返回了datetime.datetime(2022, 5, 5, 12, 30, 23)。 我在项目中发布了一个问题 - https://github.com/dateutil/dateutil/issues/1209 - user1045680

1

(文档很大时可能有其他格式。)

不幸的是,Python没有提供“猜我想要什么”的功能(尽管您可以重新利用GNU date,因为它是非常灵活的)。您必须列出您想要支持的所有格式,然后依次尝试每个格式(使用datetime.strptime(),就像您展示的那样),直到其中一个起作用。

Python不会尝试猜测,因为在国际环境中,通常不可能知道用户想要什么。在美国,2/3/1994表示“1994年2月3日”,但在欧洲,相同的字符串表示“1994年3月2日”。Python故意避免这种混淆。


谢谢Kevin的回答。但我想我已经找到了一个解决方案。让我检查一下,如果有效,我会回答这个问题。 - Jaffer Wilson

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接