6

我正在使用 Python 处理 PDF,并且正在使用PDFMiner. 我使用以下方法提取信息:

from pdfminer.pdfparser import PDFParser, PDFDocument    
fp = open('diveintopython.pdf', 'rb')
parser = PDFParser(fp)
doc = PDFDocument()
parser.set_document(doc)
doc.set_parser(parser)
doc.initialize()

print doc.info[0]['CreationDate']
# And return this value "D:20130501200439+01'00'"

如何D:20130501200439+01'00'在 Python 中转换为可读格式?

4

4 回答 4

8

我找到了此处记录的格式。我也需要处理时区,因为我要处理来自各地的 16 万份文件。这是我的完整解决方案:

import datetime
import re
from dateutil.tz import tzutc, tzoffset


pdf_date_pattern = re.compile(''.join([
    r"(D:)?",
    r"(?P<year>\d\d\d\d)",
    r"(?P<month>\d\d)",
    r"(?P<day>\d\d)",
    r"(?P<hour>\d\d)",
    r"(?P<minute>\d\d)",
    r"(?P<second>\d\d)",
    r"(?P<tz_offset>[+-zZ])?",
    r"(?P<tz_hour>\d\d)?",
    r"'?(?P<tz_minute>\d\d)?'?"]))


def transform_date(date_str):
    """
    Convert a pdf date such as "D:20120321183444+07'00'" into a usable datetime
    http://www.verypdf.com/pdfinfoeditor/pdf-date-format.htm
    (D:YYYYMMDDHHmmSSOHH'mm')
    :param date_str: pdf date string
    :return: datetime object
    """
    global pdf_date_pattern
    match = re.match(pdf_date_pattern, date_str)
    if match:
        date_info = match.groupdict()

        for k, v in date_info.iteritems():  # transform values
            if v is None:
                pass
            elif k == 'tz_offset':
                date_info[k] = v.lower()  # so we can treat Z as z
            else:
                date_info[k] = int(v)

        if date_info['tz_offset'] in ('z', None):  # UTC
            date_info['tzinfo'] = tzutc()
        else:
            multiplier = 1 if date_info['tz_offset'] == '+' else -1
            date_info['tzinfo'] = tzoffset(None, multiplier*(3600 * date_info['tz_hour'] + 60 * date_info['tz_minute']))

        for k in ('tz_offset', 'tz_hour', 'tz_minute'):  # no longer needed
            del date_info[k]

        return datetime.datetime(**date_info)
于 2014-11-07T07:58:53.810 回答
7

“+01'00'”是时区信息吗?不考虑这一点,您可以按如下方式创建一个日期时间对象...

>>>from time import mktime, strptime
>>>from datetime import datetime
...
>>>datestring = doc.info[0]['CreationDate'][2:-7]
>>>ts = strptime(datestring, "%Y%m%d%H%M%S")
>>>dt = datetime.fromtimestamp(mktime(ts))
datetime(2013, 5, 1, 20, 4, 30)
于 2013-05-12T01:06:33.193 回答
1

我想我没有代表评论 Paul Whipp 的说明性答案,但我已经对其进行了修改以处理我的一些旧文件中存在的 Y2K 错误的一种形式。2000 年写成 19100,所以 pdf_date_pattern 的相关行变成了

r"(?P<year>191\d\d|\d\d\d\d)",

我在转换值循环中添加了一个 elif:

elif k == 'year' and len(v) == 5:
    date_info[k] = int('20' + v[3:])
于 2019-11-30T16:59:10.440 回答
1

使用 Python 3 的datetime.strptime;只需先删除撇号:

from datetime import datetime

creation_date = "D:20130501200439+01'00'"

dt = datetime.strptime(creation_date.replace("'", ""), "D:%Y%m%d%H%M%S%z")

print(repr(dt))
# datetime.datetime(2013, 5, 1, 20, 4, 39, tzinfo=datetime.timezone(datetime.timedelta(seconds=3600)))

print(dt.isoformat())
# 2013-05-01T20:04:39+01:00

一旦你有了一个日期时间对象,你可以格式化回字符串,但是你喜欢“可读”的输出,请参阅strptime/strftime 指令

于 2021-08-16T08:20:05.747 回答