web-dev-qa-db-ja.com

特定のタイムスタンプが秒またはミリ秒であるかどうかをテストする方法は?

与えられた変数がUNIXタイムスタンプを含んでいると仮定しますが、秒形式かミリ秒形式か不明なため、秒形式の変数に割り当てます

例えば:

unknown = 1398494489444 # This is millisecond
t = ???

更新:いくつかの制限を与えずに伝えることは不可能であることを理解しているので、ここにあります

  • current_ts-86400 * 365 <不明<current_ts

Assume current_ts = current unix timestamp

27
Ryan

convert ミリ秒でx桁の最大タイムスタンプ値を取得すると、次のようになります。

  • 9999999999999(13桁)は、20月11日土曜日2286 17:46:39 UTCを意味します
  • 999999999999(12桁)は、2001年9月9日(日)01:46:39 UTCを意味します
  • 99999999999(11桁)は、1973年3月3日土曜日09:46:39 UTCを意味する

タイムスタンプは2001よりも古いものですか?そうでない場合は、数字が13桁以上かどうかを確認しても安全だと思います。ある場合はミリ秒、そうでない場合は秒です。もちろん、これは秒単位のタイムスタンプも13桁になるまで機能します。つまり、ミリ秒単位のタイムスタンプは16桁になります。

  • 1000000000000000(16桁)は、金9月27日33658 01:46:40を意味しますが、それまでに私はアルファケンタウリシステムから惑星に住んでおり、時間基準はおそらく少し変更されているでしょう:)

追伸タイムスタンプが1973年より前に戻らない場合は、条件を12桁以上に緩和することができます。

  • 100000000000000(15桁)は、Wed Nov 16 5138 09:46:40を意味します。これは秒単位で12桁となり、条件と重複するためです。
41
Sandman

反対票を集めるリスクを冒して、私は「DO N'T DO IT」と言って記録に残したいと思います。

物理量の単位に関する仮定を立てることはひどい考えです-それは Mars Meteorological Orbiter の破壊につながりました=(計算された推力の単位はポンドであり、エンジンはニュートンを予想しました。十分な推力ではありません-そしてオービターは大気中で燃え尽きました)。

あなたが数の大きさについてかなり良い考えを持っているなら、あなたは単位で「教育された推測」をすることができるはずです。たとえば、私の体重が230だと言ったら、私を見て、「それはキロではなく、ポンドだと思う」と考えるでしょう。同様に、私の誕生日のタイムスタンプを秒単位であると想定して日付に変換すると、200年後の日付であることがわかった場合、「秒」が間違った単位であると合理的に想定できます。

しかし、それは危険なことです。

それでも-あなたがそれをしなければならないなら、一般的に、私は次のアプローチをお勧めします:

  1. 可能なすべての単位を指定して、変換を「適切な」スケールに変換します(たとえば、タイムスタンプを年/月/日に変換します)。
  2. 取得した値を見てください。これらのどれが「最も可能性が高い」か。日付の場合、あなたは良い考えを持っているかもしれません(このコンピューターがサービスを開始した日付:1970年か2012年か?など)
  3. 最も可能性の高い値を選択してください
  4. どこかに記録しますこれはあなたがしたことです-この決定の結果が間違っていることが判明した場合は、エラーを追跡できます

その最後のことは重要です-それはあなたがあなたの過ちから学ぶことを可能にします。たとえば、タイムスタンプで彗星が次に表示される時期がわかる場合は、次のように印刷できます。

次の予想される彗星の出現:2546年12月29日(仮定:Xからのタイムスタンプは秒単位で指定された)

このように、いくつかの「カムバック」があります。一般的に、「仮定を文書化する」は、良いアドバイスではありません-正確な科学では不可欠です。

最後に-タイムスタンプのmsからsへの変換は、数値を1000で除算することによって実現されます。しかし、私はあなたがそれを知っていると確信しています。

21
Floris

制約があれば、ミリ秒のタイムスタンプを検出するのは簡単です。過去1年のタイムスタンプでも、現在のタイムスタンプよりもマグニチュードが大きくなります。

数値が現在のタイムスタンプより大きいかどうかをテストします。もしそうなら、ミリ秒単位のタイムスタンプがあります:

now = time.mktime(time.gmtime())
if t > now:
    # milliseconds, convert to seconds
    t /= 1000.0

1000で除算することにより、タイムスタンプを秒単位のタイムスタンプに変換し直すと、デフォルトのtimeモジュール関数を適用できます。

これは、過去1年を表すミリ秒単位のタイムスタンプでさえ、誤って秒単位のタイムスタンプと解釈され、将来farになるためです。

>>> import time
>>> ts = time.mktime(time.gmtime())
>>> year_ago = ts - (86400 * 365)
>>> time.gmtime(year_ago * 1000) # misinterpret milliseconds as seconds
time.struct_time(tm_year=45395, tm_mon=7, tm_mday=9, tm_hour=14, tm_min=0, tm_sec=0, tm_wday=3, tm_yday=190, tm_isdst=0)

2つの範囲を混同する前に、タイムスタンプ1970年初頭を設定する必要があります。

>>> now = time.mktime(time.gmtime())
>>> time.gmtime(ts / 1000) # misinterpret seconds as milliseconds
time.struct_time(tm_year=1970, tm_mon=1, tm_mday=17, tm_hour=5, tm_min=25, tm_sec=13, tm_wday=5, tm_yday=17, tm_isdst=0)

例えば。 UNIXエポック後の最初の17日間のタイムスタンプは、ミリ秒単位のタイムスタンプと混同される可能性があります。すべてその日付は「現在時刻」のタイムスタンプより大きくなります。

特定の制約があれば、2つのユニットを簡単に分離できることは幸運です。 より良いオプションは、このような状況にならないようにすることですそもそも。このデータはどこかから供給されました。決定できるだけ早く後で推測するのではなく、どのデータ型を使用しているか。タイムスタンプをランダムに秒単位でランダムに与えるシステムや、残りの時間をミリ秒単位でランダムに与えるシステムはありません。確かに、他の情報に基づいて、どのタイプのデータを調達しているかを知ることができ、そのときに変換するか、データに注釈を付けてタイプを含めることができますか?

20
Martijn Pieters

マーティンによって与えられた答えの代替:

この問題は、サードパーティからのドキュメントのタイムスタンプを統一する必要があったときに発生しました。以前の状態は:

if date > time.time():
    use_miliseconds(date)
else:
    use_seconds(date)

、それはうまくいくようです、特にdateがタイムゾーン情報のない文字列表現から派生した場合、または時計が変更されている場合は、Edgeケースがあります。

より安全なバリアントは以下を使用することです:

if date > time.time() + HUNDRED_YEARS:
    use_miliseconds(date)
else:
    use_seconds(date)

、 どこ HUNDRED_YEARS = 365 * 24 * 3600。この状態ははるかにエラーが発生しやすく、実際、1970年1月と2月を除くすべての日付で機能します(どちらの方法でもあいまいです)。

0
vlyubin