2012-07-12 7 views
5

次のように私は文字列のリストを持っている:Python:あいまいな時間を時間オブジェクトに変換する効果的な方法は?

4:00-5:00PM 
11:00-2:00PM 
12:00-1:00PM 
11:00-1:00AM 

を、私は2時間のオブジェクトを作成するための効果的な方法を見つけようとしている(私はこれは、時間の範囲を追跡するための唯一の方法であると仮定し、私は後で日付オブジェクトと組み合わせます)。 00-1:00AM、これだけにこれを変換する効果的な方法は何不思議:私たちは11を言う、我々は意味人間には明らかである

datetime.time(23, 0) 
datetime.time(1, 0) 

私の現在のアプローチは、最初に時間がかかる、とPMを作成することですAMバージョンでは、終了時刻(指定されている)でタイムデータをとり、2つの差のうち短い方を正しい時刻にします。

+0

コードを表示したとき(いくつかの場合)、あなたの手助けがはるかに簡単です。また、左辺の値をAMとPMの両方として解釈し、より小さいデルタを選ぶアプローチは、私がそれをやり遂げる方法です。 –

+0

うわー、それはたくさんのコードなので、あなたは実装を複雑にしています。 –

答えて

3

ここは簡単な実装です。

>>> def timeRange(timestr): 
    ...  t1, t2 = timestr.split("-") 
    ...  timeFormat = "%I:%M%p" 
    ...  t1AM = datetime.datetime.strptime(t1 + "AM", timeFormat) 
    ...  t1PM = datetime.datetime.strptime(t1 + "PM", timeFormat) 
    ...  t2 = datetime.datetime.strptime(t2, timeFormat) 
    ...  
    ...  if (t2 - t1AM).seconds < (t2-t1PM).seconds: 
    ...   return t1AM.time(), t2.time() 
    ...  else: 
    ...   return t1PM.time(), t2.time() 
    >>> timeRange("11:00-2:00PM") 
    (datetime.time(11, 0), datetime.time(14, 0)) 
    >>> timeRange("4:00-5:00PM") 
    (datetime.time(16, 0), datetime.time(17, 0)) 
    >>> timeRange("11:00-1:00AM") 
    (datetime.time(23, 0), datetime.time(1, 0)) 
    >>> timeRange("11:00-2:00PM") 
    (datetime.time(11, 0), datetime.time(14, 0)) 
    >>> timeRange("12:00-1:00PM") 
    (datetime.time(12, 0), datetime.time(13, 0)) 

これはtimeオブジェクトを返しますが、あなたがする必要がある場合は、datetimeオブジェクトにそのロールができます。

+0

2番目の時刻が翌日にあることを示すために、返されたタプルの別のインジケータ。たとえば、最初の時刻がPMで、2番目の時刻がAMの場合。これは、OPで要求された期間の期間を計算する際に役立ちます。それ以外の時間(23、0) - >時間(1、0)は-22時間になります... –

+0

恐ろしい!ありがとう、私は自分自身の実装を試して、それはあなたのものに非常に似ていますが、あなたの最適化されています。 – zhuyxn

2

あなたの質問で暗黙の2つの前提があります。

  • あなたが最初の時間は2の早い
  • これらの時間の間に可能な最短の期間を探していますが。

これらの仮定が真である場合には、迅速な最適化が次のようになります。

  • 初めてたとえば11(秒より大きい場合:00-1:00AMまたは11:00-1: 00PM)である場合、前の時間は秒の「反対の」AM/PMインジケータである。そうでなければ、最初のAM/PMは同じです。

これが最大の期間のためにも働く、例えば6:00-6:00AM

は、第2の観察がある(6時PM-6:00AM 6:00 AM-6:00AMよりも短くなっています)

  • AM-> PM期間は、1日の境界(真夜中)にわたって行われるため、単純な時間オブジェクトは使用できません。これはおそらく、この状態でのあなたのタイムデルタの計算を不正にしているでしょう。

したがって、私はdatetimeを使用するか、またはオブジェクトを前回の時刻として時刻を記述する構造体でこれをすべてラップする必要があると思います。

希望します。

+0

あなたは正しいですが、 '6:00 AM-6:00AM'を長さ0に扱わないように気をつけなければなりません。 – glglgl

+0

6:00 AM-6:00AMは、OPが提供したフォーマットに適合しません。 AM/PMインジケータはありません –

+0

そうです。しかし、「6:00〜6:00 AM」は、「6:00〜6:00AM」の長さが0であり、「6:00〜6:00AM」よりも短い場合、「6:00〜 'は、いずれにしても12時間あります。しかし、「6:00~6:00」が24時間を意味する場合、「6:00~6:00AM」は短く、したがって解決策である。(完全に明白であるように、世界のいくつかの部分は、約90年前にすでに行われた他の部分の切り替えを行い、誰もが何を意味するのかを知るために '18:00-06:00 'と書くことができます) – glglgl

関連する問題