在Python中解析法语日期

20

请问如何在Python中解析法式日期?如果这个问题已经有了答案,请原谅我没有找到。

这是我尝试使用dateutil解析器的代码:

import locale
from dateutil.parser import parse as parse_dt
locale.setlocale(locale.LC_TIME, 'fr_FR.UTF-8')   ## first I set locale
## locale.LC_TIME, 'fr_FR.UTF-8')
parse_dt('3 juillet',fuzzy= True)   ## don't work give the default month
## Out[29]: datetime.datetime(2014, 10, 3, 0, 0)
parse_dt(u'4 Août ',fuzzy= True)     ## same thing using another month 

编辑:添加一些上下文:

我正在解析日期,但事先不知道字符串的格式。我的想法是在运行时解析许多日期:

parse_dt(u'Aujourd''hui ',fuzzy= True) 
parse_dt(u'Hier',fuzzy= True) 

使用其他库进行编辑:

通过使用parsedatetime库和一些正则表达式将法语单词翻译成英语,我可以得到以下结果:

import parsedatetime
import re 
cal = parsedatetime.Calendar()
cal.parse(re.sub('juil.*' ,'jul' ,'20 juillet'))
 ((2015, 7, 20, 10, 25, 47, 4, 283, 1), 1)

也许我应该将其推广到所有法国月份吗?

在法语中,我从未读到或听到过将日期和月份按“月日”顺序表达的说法,而是始终按照“日月”的顺序。这是否适用于“3 juillet”或“3 Août”? - Jean Hominal
1
@agstudy:你尝试过使用 datetime.strptime(date_string, '%d %B') 吗? - jfs
1
经过检查 dateutil 源代码,发现 dateutil 似乎不支持基于区域设置的日期解析。 - Jean Hominal
2
我觉得如果不知道数据的格式,你是无法正确解析任何内容的。最多只能得到一些正确和错误的结果,而我想这并不是你想要的。很可能你需要坐下来仔细研究数据,找出最容易解析的格式,然后将其他的格式放在一边不管。 - alvas
显示剩余6条评论
3个回答

26

dateparser模块可以解析问题中的日期:

#!/usr/bin/env python
# -*- coding: utf-8 -*-
import dateparser # $ pip install dateparser

for date_string in [u"Aujourd'hui", "3 juillet", u"4 Août", u"Hier"]:
    print(dateparser.parse(date_string).date())

它使用一个 简单的 YAML 配置文件 将日期翻译成英语,并将日期字符串传递给 dateutil.parser

输出

2015-09-09
2015-07-03
2015-08-04
2015-09-08

这非常有效,比设置区域设置容易得多。 - Romain

6
首先检查您的存储库中是否有正确的区域设置:
$ locale -a
C
C.UTF-8
de_AT.utf8
de_BE.utf8
de_CH.utf8
de_DE.utf8
de_LI.utf8
de_LU.utf8
en_AG
en_AG.utf8
en_AU.utf8
en_BW.utf8
en_CA.utf8
en_DK.utf8
en_GB.utf8
en_HK.utf8
en_IE.utf8
en_IN
en_IN.utf8
en_NG
en_NG.utf8
en_NZ.utf8
en_PH.utf8
en_SG.utf8
en_US.utf8
en_ZA.utf8
en_ZM
en_ZM.utf8
en_ZW.utf8
POSIX

如果不是的话,那就执行以下操作:
$ sudo locale-gen fr_FR.UTF-8
Generating locales...
  fr_FR.UTF-8... done
Generation complete.

然后回到Python:
$ python
>>> import locale
>>> import datetime
>>> locale.setlocale(locale.LC_ALL, 'fr_FR.UTF-8')
'fr_FR.UTF-8'
>>>
>>> date_txt = "Dimanche 3 Juin 2012"
>>> DATE_FORMAT = "%A %d %B %Y"
>>> datetime.datetime.strptime(date_txt, DATE_FORMAT)
datetime.datetime(2012, 6, 3, 0, 0)
>>>

使用自定义日期格式:
>>> date_txt = "3 juillet"
>>> DATE_FORMAT = "%d %B"
>>> datetime.datetime.strptime(date_txt, DATE_FORMAT)
datetime.datetime(1900, 7, 3, 0, 0)

如果年份未明确指定,你会发现它默认设置为1900年。

谢谢。我忘记在解析之前提及确切的格式。我也可能会得到像“今天”或“昨天”这样的东西。看起来我应该做我的个人词典翻译。 - agstudy

4
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import parsedatetime as pdt # $ pip install parsedatetime pyicu

calendar = pdt.Calendar(pdt.Constants(localeID='fr', usePyICU=True))
for date_string in [u"Aujourd'hui", "3 juillet", u"4 Août", u"Hier"]:
    dt, success = calendar.parseDT(date_string)
    if success:
       print(date_string, dt.date())

输出

3 juillet 2015-07-03
4 Août 2015-08-04

今天和昨天无法被parsedatetime 1.4识别。

Github上的当前版本(future 1.5)支持自定义日期偏移量。它可以用于解析今天和昨天:

#!/usr/bin/env python
# -*- coding: utf-8 -*-
import parsedatetime as pdt

class pdtLocale_fr(pdt.pdt_locales.pdtLocale_icu):
    def __init__(self):
        super(pdtLocale_fr, self).__init__(localeID='fr_FR')
        self.dayOffsets.update({u"aujourd'hui": 0, u'demain': 1, u'hier': -1})

pdt.pdtLocales['fr_FR'] = pdtLocale_fr

calendar = pdt.Calendar(pdt.Constants(localeID='fr_FR', usePyICU=False))
for date_string in [u"Aujourd'hui", "3 juillet", u"4 Août", u"Hier",
                    u"au jour de hui", u"aujour-d’hui",
                    u"au-jour-d’hui", "demain", "hier",
                    u"today", "tomorrow", "yesterday"]:
    dt, rc = calendar.parseDT(date_string)
    if rc > 0:
       print(date_string, dt.date())

最新版本

输出

Aujourd'hui 2014-10-11
3 juillet 2015-07-03
4 Août 2015-08-04
Hier 2014-10-10
demain 2014-10-12
hier 2014-10-10
today 2014-10-11
tomorrow 2014-10-12
yesterday 2014-10-10

要安装它,请运行以下命令:
$ pip install git+https://github.com/bear/parsedatetime

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