0

お気に入りのモジュールを自由に追加してください。ただし、PEP-431 はまだ実装されていないため、タイムゾーンとそれに関連する奇妙さを処理する統一された具体的な方法が得られたため、これまでのところ、、、、、および対処timeする必要があります。夏時間の切り替え中に 2 回発生する、またはまったく発生しないあいまいな日時のように。とにかく、私の質問はかなり平凡ですが、答えが見つからないようです。datetimedateutilpytzlocale

バックストーリー: Sublime Text用の小さなプラグインを開発しています。これにより、最初はユーザーが現在のドキュメントに (指定した形式で、デフォルトにフォールバックして) タイムスタンプを挿入できるようになります。最終的には保存時にタイムスタンプが更新されますが、ここでは関係ありません。これが私の短い自己完結型のコード例です:

import sublime_plugin
from datetime import datetime as dt


class TimeStampCommand(sublime_plugin.TextCommand):

    def run(self, edit):
        stamp = dt.utcnow().strftime("%Y-%m-%d %H:%M:%S UTC")  # 2013-10-10 22:38:40 UTC
        for r in self.view.sel():
            if r.empty():
                self.view.insert(edit, r.a, stamp)
            else:
                self.view.replace(edit, r, stamp)

フォーマット オプションのリストから%Z、ローカル タイムゾーンを追加して取得できるはずです。

stamp = dt.now().strftime("%Y-%m-%d %H:%M:%S %Z")  # should be 2013-10-10 18:38:40 EDT

または、少し変更して、よりユニバーサルな UTC オフセットを取得します。

stamp = dt.now().strftime("%Y-%m-%d %H:%M:%S UTC %z")  # should be 2013-10-10 18:38:40 UTC -0400

残念ながら、これは当てはまりません。なぜなら、 によって返される時刻dt.now()は「ナイーブ」であり、タイムゾーン情報が関連付けられていないためです。を使用することもできますdatetime.tzinfoが、これは抽象的な基本クラスにすぎません。だから、私の質問の根底に:「認識できる」オブジェクトを作成するにはどうすればよいですか // /のtime完全な配列を利用できますdatetimedateutilwhateverstrftime()フォーマットオプション?ユーザーが自分のロケールに従って (何らかの形でこれを検出する必要があります)、または提供されたロケールに従って、好きなようにタイムスタンプをフォーマットできるようにしたいと考えています。できれば、Windows、Mac、および Linux (Sublime Text がサポートするプラットフォーム) で動作することを望みます。最後に、Python 2.6 と 3.3 (それぞれ、ST2 と ST3 の組み込みインタープリターのバージョン) に違いがある場合は、それらについて知りたいです。

私はあなたにすべてのコードを書くように頼んでいるわけではないことに注意してください。私はこれを自分で学びたいのです。私は一日のほとんどを車輪を回転させてきたので、正しい方向に進むためにいくつかの良い指針が必要です. 最低限、生成方法を理解する2013-10-10 18:38:40 UTC -0400ことは素晴らしいスタートになるでしょうが、他のものも本当に素晴らしいでしょう:)

4

1 に答える 1

1

strftime() 書式設定オプションの完全な配列を利用できる「認識」時間/日時/日付ユーティリティ/その他のオブジェクトを作成するにはどうすればよいですか?

タイムゾーンがあれば、pytzモジュールを使えば簡単です:

>>> mytz = pytz.timezone('America/Los_Angeles')
>>> now = datetime.datetime.now(tz=mytz)
>>> now
datetime.datetime(2013, 10, 10, 16, 34, 3, 113620, tzinfo=<DstTzInfo 'America/Los_Angeles' PDT-1 day, 17:00:00 DST>)

それは意識的なタイムゾーンです。そして、それを %Z にフィードすると?

>>> now.strftime('%Y-%m-%d %H:%M:%S %Z')
'2013-10-10 16:34:03 PDT'

もちろん、これは解析して明確な日時オブジェクトに戻すことができるものではありません。これは、太平洋を意味するのかパキスタンを意味するのかを判断する方法がないためです。そのため、エンド ユーザーに表示するのに役立つ場合がありますが、それ以外にはあまり役に立ちません。米国の問題のみを決定したとしても、'MST' は、米国のほとんどの DST 規則で -7 のように Mountain を意味するのでしょうか? または Arizona の DST なし規則で -7 のように -7 のように山を意味するのでしょうか? そして、人気のある 3 文字のコードのほとんどは、これら 2 つよりもさらに悪いものです。


しかし、もっと重要なのは、そもそもどのようにしてそのタイムゾーンを取得するのでしょうか?

できません。

一部の POSIX システムでは、 から読み取ることができますos.environ['TZ']。ただし、通常はそうではありません。または、利用可能な場合でも、ユーザーが明示的に有効なタイムゾーン識別子に設定しない限り、「PST」のようなあいまいな略語になります。

ほとんどの POSIX システムでは、これを行うことができます。

>>> time.tzset()
>>> time.tzname
('PST', 'PDT')

しかし、これはあいまいな省略形であることが保証されています。(そして、Windows ではまだ動作しません。)


最低限、 2013-10-10 18:38:40 UTC -0400 を生成する方法を理解するだけで、素晴らしいスタートになります

これは簡単ではありませんが、サードパーティのコードがなくても、少なくとも簡単です。それはただ面倒です。

まず、信頼できる場合tzset(ほとんどの POSIX プラットフォーム):

>>> time.tzset()
>>> sec = -time.timezone

または、信頼できない場合tzset:

>>> t = time.time()
>>> local = datetime.datetime.fromtimestamp(t)
>>> utc = datetime.datetime.utcfromtimestamp(t)
>>> offset = local - utc
>>> sec = offset.total_seconds()

次に、それを文字列にフォーマットします。

>>> hr, sec = divmod(sec, 3600)
>>> min, sec = divmod(sec, 60)
>>> offstr = '{:+03d}{:02d}'.format(hr, min)

ここで、単純な現地時間をフォーマットする場合は、次のようにします。

>>> datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S") + " " + offstr
'2013-10-10 16:18:36 -0800'

それで、あなたは何をすべきですか?

当然のことながら、すべての内部および永続化の使用については UTC 時間のままです。次に、直接入力と出力のためにローカル時間を処理するだけで済みます。また、Web サービスではなくデスクトップ アプリを作成しているため、「ローカル」が実際にどのタイムゾーンであるかを知らなくても、naive-local を UTC との間で変換するさまざまな関数を使用するだけです。

あなたのユースケースでは、ユーザーのタイムスタンプは、単純な日時に加えて、可能であればtimeモジュールから取得した名前からフォーマットでき、そうでない場合はオフセットにフォールバックできます。tzsetこれは、認識された日時を構築するよりも悪くありません。

于 2013-10-10T23:19:19.930 に答える