5

私は(私のアプリケーションがさまざまなソースやさまざまなタイムゾーン、形式などからの大量のデータを処理しているため)データを保存して操作するのに最適な方法を決定しようとしています。

たとえば、すべてをUTCとして保存する必要がありますか?つまり、データをフェッチするときに、現在のタイムゾーンを特定する必要があります。UTCでない場合は、必要な変換を行ってデータを取得します。(注、私はESTにいます)。

次に、データに対して計算を実行するときに、抽出して(UTCと言う)、MYタイムゾーン(EST)に入る必要があるので、それを見るときに意味がありますか?UTCで保持し、すべての計算を行う必要がありますか?

このデータの多くは時系列であり、グラフ化され、グラフはESTになります。

これはPythonプロジェクトなので、次のようなデータ構造があるとします。

"id1": {
    "interval": 60,                            <-- seconds, subDict['interval']
    "last": "2013-01-29 02:11:11.151996+00:00" <-- UTC, subDict['last']
},

そして、現在の時刻(now())が>最後の+間隔(60秒が経過した)であるかどうかを判断することによって、これを操作する必要がありますか?したがって、コードでは:

lastTime = dateutil.parser.parse(subDict['last'])    
utcNow = datetime.datetime.utcnow().replace(tzinfo=tz.tzutc())

if lastTime + datetime.timedelta(seconds=subDict['interval']) < utcNow:
    print "Time elapsed, do something!"

それは理にかなっていますか?私はどこでもUTCを使用しており、保存と計算の両方で...

また、ソフトウェアでタイムスタンプを操作する方法についての優れた記事へのリンクがあれば、ぜひ読んでみてください。おそらく、アプリケーションでタイムスタンプを使用するためのJoel On Softwareのように?

4

4 に答える 4

3

あなたはすでに「正しい方法」で物事をやっているように私には思えます。ユーザーはおそらくローカルタイムゾーン(入力と出力)で対話することを期待しますが、明確にし、計算を簡素化するために、正規化された日付をUTC形式で保存するのが通常です。したがって、できるだけ早くUTCに正規化し、できるだけ遅くローカライズします。

Pythonとタイムゾーンの処理に関する少量の情報は、次の場所にあります。

私の現在の好みは、日付をUNIXタイムスタンプ値としてバックエンドストレージに保存し、処理中にPythonオブジェクトにtv_sec変換することです。datetime.datetime処理は通常datetime、UTCタイムゾーンのオブジェクトを使用して実行され、出力の直前にローカルユーザーのタイムゾーンに変換されます。datetime.datetimeデバッグに役立つなどの豊富なオブジェクトがあることがわかりました。

タイムゾーンは対処するのが面倒であり、タイムゾーンを正しくサポートするために努力する価値があるかどうかをケースバイケースで判断する必要があります。

たとえば、使用されている帯域幅の1日あたりのカウントを計算しているとします。発生する可能性のあるいくつかの質問は次のとおりです。

  1. 夏時間の境界ではどうなりますか?計算を簡単にするために、1日は常に24時間であると想定する必要がありますか、それとも、夏時間の境界で1日がより少ないまたはより多い時間である可能性があることを、毎日の計算ごとに常にチェックする必要がありますか?
  2. ローカライズされた時間を表示する場合、時間が繰り返されるかどうかは重要ですか?例えば。タイムゾーンが接続されていないローカルタイムで1時間ごとのレポートを表示している場合、ユーザーは1時間のデータが欠落している、または夏時間の変更の前後に1時間のデータが繰り返されていると混乱しますか。
于 2013-01-30T04:31:35.600 に答える
2

ご覧のとおり、実装上の問題はないようですので、コードやタイムスタンプ形式よりも設計面に焦点を当てたいと思います。ローカルネットワークに分散システムとして実装されたナビゲーションシステムのネットワークサポートの設計に参加した経験があります。そのシステムの性質上、さまざまなソースからの大量のデータ(多くの場合競合)が存在するため、発生する可能性のある競合を解決し、データの整合性を維持するのはかなり難しいです。その経験に基づいたいくつかの考え。

多くのコンピューターを含む分散システムであっても、システム時間関数によって提供されるものよりも高い解像度と、OSコンポーネントによって提供されるものよりも高い時間同期精度が必要ない場合は、通常、データのタイムスタンプは問題になりません。

最も単純なケースでは、UTCを使用するのが非常に合理的であり、ほとんどのタスクではそれで十分です。ただし、設計の最初から、システムでタイムスタンプを使用する目的を理解することが重要です。時間の値(Unix時間またはフォーマットされたUTC文字列に関係なく)が等しい場合があります。タイムスタンプに基づいてデータの競合を解決する必要がある場合(つまり、異なるソースから受信した複数の値から常に新しい(または古い)値を選択する)、誤って解決された競合(通常は競合が発生する可能性があることを意味します)を理解する必要がありますタイムスタンプが等しいため、複数の方法で解決することは、システム設計にとって致命的な問題であるかどうかです。考えられるオプションは次のとおりです。

  1. 競合の99.99%がすべてのノードで同じ方法で解決される場合、残りの0.01%は気にせず、データの整合性を損なうことはありません。その場合、UTCのようなものを安全に使い続けることができます。

  2. すべての競合を厳密に解決する必要がある場合は、独自のタイムスタンプシステムを設計する必要があります。タイムスタンプには、時間(システム時間ではないかもしれませんが、より高解像度のタイマー)、シーケンス番号(時間の解像度が十分でない場合でも一意のタイムスタンプを生成できるようにするため)、ノード識別子(システムのさまざまなノードが完全に一意になるようにするため)が含まれる場合がありますタイムスタンプ)。

  3. 最後に、必要なのは時間に基づくタイムスタンプではない場合があります。タイムスタンプのペア間の時間差を本当に計算できる必要がありますか?タイムスタンプをリアルタイムの瞬間に接続するのではなく、タイムスタンプを注文できるようにするだけで十分ではありませんか?時間の計算が必要ない場合は、比較、リアルタイムではなくシーケンシャルカウンターに基づくタイムスタンプが適切な選択です(詳細については、ランポートタイムを参照してください)。

厳密な競合解決が必要な場合、または非常に高い時間解決が必要な場合は、おそらく独自のタイムスタンプサービスを作成する必要があります。

多くのアイデアや手がかりは、A。タネンバウムの著書「分散システム:原理とパラダイム」から借りることができます。このような問題に直面したとき、それは私を大いに助けました、そしてそれにタイムスタンプ生成に捧げられた別の章があります。

于 2013-01-30T06:09:30.990 に答える
1

最善のアプローチは、すべてのタイムスタンプデータをUTCとして保存することだと思います。読み込んだら、すぐにUTCに変換してください。表示の直前に、UTCからローカルタイムゾーンに変換します。

コードですべてのタイムスタンプを2回印刷することもできます。1回は現地時間で、2回目はUTC時間です...これは、一度に画面に収める必要のあるデータの量によって異なります。

私はRFC3339タイムスタンプ形式の大ファンです。それは人間と機械の両方にとって明白です。それについての最もよいことは、ほとんど何もオプションではないということです、それでそれは常に同じに見えます:

2013-01-29T19:46:00.00-08:00

タイムスタンプをストレージと計算のために単精度浮動小数点値に変換してから、表示のために日時形式に変換し直すことを好みます。私はfloatにお金を入れませんが、タイムスタンプ値はfloat値の精度の範囲内です!

時間フロートを操作すると、多くのコードが非常に簡単になります。

if time_now() >= last_time + interval:
    print("interval has elapsed")

すでにこのようにやっているようですので、劇的な改善を提案することはできません。

タイムスタンプをPythonのタイムフロート値に解析し、タイムフロート値をタイムスタンプ文字列に変換するライブラリ関数をいくつか作成しました。たぶん、ここにある何かがあなたに役立つでしょう:

http://home.blarg.net/~steveha/pyfeed.html

をご覧になることをお勧めしますfeed.date.rfc3339。BSDライセンスなので、必要に応じてコードを使用できます。

編集:質問:これはタイムゾーンにどのように役立ちますか?

回答:保存するすべてのタイムスタンプがUTC時間でPythonタイムフロート値(エポックからの秒数、オプションの小数部分を含む)として保存されている場合は、それらを直接比較できます。それらの間の間隔を見つけるために互いに減算します。など。RFC3339タイムスタンプを使用する場合、すべてのタイムスタンプ文字列のタイムゾーンはタイムスタンプ文字列のすぐそこにあり、コードによってUTC時間に正しく変換できます。表示する直前にfloat値からタイムスタンプ文字列値に変換すると、タイムゾーンは現地時間に対して正しくなります。

また、私が言ったように、彼はすでにこれをかなりやっているように見えるので、私は素晴らしいアドバイスをすることはできないと思います。

于 2013-01-30T03:54:07.027 に答える
1

個人的にはUnix時間標準を使用していますが、単純な表現形式であるため、ストレージに非常に便利です。これは単なる数字のシーケンスです。内部的にはUTC時刻を表すため、保存して必要なタイムゾーンに合わせてフォーマットする前に、適切に生成(他のタイムスタンプから変換)する必要があります。

バックエンドデータ(tz対応)に共通のタイムスタンプ形式を設定すると、宛先TZを設定するだけで、データのプロットが非常に簡単になります。

例として:

import time
import datetime
import pytz
# print pre encoded date in your local time from unix epoch
example = {"id1": {
                   "interval": 60,
                   "last": 1359521160.62
                   }
           }
#this will use your system timezone formatted
print time.strftime("%Y-%m-%d %H:%M:%S",time.localtime(example['id1']['last']))
#this will use ISO country code to localize the timestamp
countrytz = pytz.country_timezones['BR'][0]
it = pytz.timezone(countrytz)
print  it.localize(datetime.datetime.utcfromtimestamp(example['id1']['last']))
于 2013-01-30T05:19:24.643 に答える