8

Python スクリプトを使用して電子メールの日時を解析しようとしています。

メールの詳細を開くと、メールの日付の値は次のようになります...

from:    abcd@xyz.com
to:      def@xyz.com
date:    Tue, Aug 28, 2012 at 1:19 PM
subject: Subject of that mail

私は次のようなコードを使用しています

mail = email.message_from_string(str1)
#to = re.sub('</br>','',mail["To"])
to = parseaddr(mail.get('To'))[1]
sender = parseaddr(mail.get('From'))[1]
cc_is = parseaddr(mail.get('Cc'))[1]
date = mail["Date"]
print date

Python解析を使用した同じメールのdatetimeの出力は、時間オフセットを使用して以下のようになります。

Tue, 28 Aug 2012 02:49:13 -0500

私が実際に望んでいるところ

Tue, Aug 28, 2012 at 1:19 PM

この 2 つの値の関係がとても混乱しています。同じ時間をメールの詳細に入れる必要があることを理解するのを手伝ってくれる人はいますか。

4

3 に答える 3

24

GMail でメールを見ると、メールが送信された日付と時刻を表示する際にローカル タイムゾーンが使用されます。「Tue, 28 Aug 2012 02:49:13 -0500」が解析され、ローカル タイムゾーンに更新され、GMail 固有の方法でフォーマットされます。

stdlib の方法での解析とフォーマット

このemail.utilsモジュールには、タイムゾーン オフセットを持つ電子メール ヘッダーを具体的に処理するparsedate_tz()関数が含まれています。

と互換性のあるタプルを返しますtime.struct_timeが、タイムゾーン オフセットが追加されています。追加のmktime_tz()関数は、そのタプルをオフセット値 (UNIX エポックからの秒数) に変換します。datetime.datetime()この値は、型オブジェクトに簡単に変換できます。

同じモジュールには、UNIX エポック タイムスタンプを電子メール互換の日付文字列に変換するformatdate()関数もあります。

>>> from email.utils import parsedate_tz, mktime_tz, formatdate
>>> import time
>>> date = 'Tue, 28 Aug 2012 02:49:13 -0500'
>>> tt = parsedate_tz(date)
>>> timestamp = mktime_tz(tt)
>>> print formatdate(timestamp)
Tue, 28 Aug 2012 07:49:13 -0000

これで、送信メールに適した UTC 形式の日付が作成されました。これをローカルlocaltimeタイムゾーン (コンピューターによって決定される) として出力するには、フラグをTrue次のように設定する必要があります。

>>> print formatdate(timestamp, True)
Tue, 28 Aug 2012 08:49:13 +0100

より優れたツールを使用した解析とフォーマット

タイムゾーンを扱おうとしているうちに、物事が複雑になってきていることに注意してください。このformatdate()関数では、(GMail のように) 少し異なる形式でフォーマットするオプションは提供されず、別のタイムゾーンを選択して作業することもできません。

外部python-dateutilモジュールに入ります。ほぼ何でも処理できる解析機能があり、タイムゾーンを適切にサポートしています

>>> import dateutil.parser
>>> dt = dateutil.parser.parse(date)
>>> dt
datetime.datetime(2012, 8, 28, 2, 49, 13, tzinfo=tzoffset(None, -18000))

この関数はinstanceparse()を返すため、書式設定がはるかに簡単になります。これで、関数を使用して、メール クライアントと同じように出力できます。datetime.datetime().strftime()

>>> print dt.strftime('%a, %b %d, %Y at %I:%M %p')
Tue, Aug 28, 2012 at 02:49 AM

もちろん、これはまだローカル タイムゾーンです。代わりにこれをタイムゾーンにキャストするには、新しいオブジェクトで.astimezone()メソッドを使用します。tzoneこのpython-dateutilパッケージには便利なものがあります。

ローカルタイムゾーンで(マシンに)印刷する方法は次のとおりです。

>>> import dateutil.tz
>>> print dt.astimezone(dateutil.tz.tzlocal()).strftime('%a, %b %d, %Y at %I:%M %p')
Tue, Aug 28, 2012 at 09:49 AM

または、代わりに特定のタイムゾーンを使用します。

>>> print dt.astimezone(dateutil.tz.tzstr('Asia/Kolkata')).strftime('%a, %b %d, %Y at %I:%M %p')
Tue, Aug 28, 2012 at 07:49 AM
于 2012-08-28T13:13:19.830 に答える
8

stdlib のみを使用して実行できます。

>>> from email.utils import parsedate_tz, mktime_tz, formatdate
>>> ts = mktime_tz(parsedate_tz('Tue, 28 Aug 2012 02:49:13 -0500'))
>>> formatdate(ts, localtime=True) # assuming Asia/Kolkata is the local timezone
'Tue, 28 Aug 2012 13:19:13 +0530'

PM時間の形式を使用する場合:

>>> from datetime import datetime
>>> datetime.fromtimestamp(ts).strftime('%a, %b %d, %Y at %I:%M %p')
'Tue, Aug 28, 2012 at 01:19 PM'
于 2014-04-17T00:07:49.900 に答える
2

次のコードを選択できます

start = f.find('date:') + 5  # +5 is to exclude 'date'+':' i.e.(4+1=5)
end = f.find('subject:', start) # parse from date to subject 
date_time = f[start:end]
print date_time #it will print "Tue, Aug 28, 2012 at 1:19 PM"
于 2018-07-31T11:35:51.263 に答える