【问题标题】:Convert CreationTime of PDF to a readable format in Python将 PDF 的 CreationTime 转换为 Python 中的可读格式
【发布时间】:2013-05-12 00:39:07
【问题描述】:

我正在使用 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'"

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

【问题讨论】:

  • 看起来已经可读了?当然,前六位数字似乎是yyyymmdd。只需将其切片并转换为整数,例如year = int(doc.info[0]['CreationDate'][2:6])
  • 是的,它是yyyymm,但不是dd。文件的实际日期为Thursday, May 02, 2013, 3:04:39 AM
  • @kimbebot 你确定吗?在哪个时区?
  • 是的@SanjayManohar,时区没有问题。 PDF文件是刚刚从网上下载的,我只是提取每个文件的创建时间。

标签: python date datetime pdf


【解决方案1】:

我找到了here 记录的格式。我也需要处理时区,因为我要处理来自各地的 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)

【讨论】:

    【解决方案2】:

    使用 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 directives

    【讨论】:

      【解决方案3】:

      “+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)
      

      【讨论】:

      • 很好,我用其他 PDF 文件尝试过这个,得到了 yyyymmdd 准确但不是时间,反正不需要时间。
      【解决方案4】:

      我想我没有代表评论 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:])
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-02-26
        • 1970-01-01
        相关资源
        最近更新 更多