2


0

一連の時間を意味のあるデータにシリアル化する最良の方法

私のWebアプリの一部には、毎日のドラッグアンドドロップセレクターを使用した「予定」(シフト)の作成が含まれます。 現在、このデータは次のようにシリアル化されています。

9,10,11,12,13,14,15,16,76,77,78,298,299,300,301,302,303,304,

各数値は、週のn番目の30分を表します(したがって、「304」は週の300番目の30分、つまり土曜日の午前8時です)。

次に、Pythonを使用してサーバー上でこれをもう少し賢明なものに解析します。

[[9,16],[76,78],[298,304]]

しかし、その後、主にどのように…​ そもそもデータがサーバーに送信されるのは粘着性があります。

私の質問は次のとおりです

私が思いついた見苦しいHTML / Javascriptのhttp://files.massiveatom.com/stracker/templates/stracker/setshift.html [ライブバージョン]があります。 クライアント側でJavascript / jQueryを使用し、サーバーでPython / Djangoを使用しています。

2 Answer


2


あなたは間隔について話している。

間隔を設定する最適な方法は、開始時間と期間です。

class Shift( object ):
    def __init__( self, start, length ):
         self.start= start
         self.length= length
    def __repr__( self ):
         return "Shift(%d,%d)" % ( self.start, self.length )
    def ends( self ):
         return self.start + self.length

これらのオブジェクトをシリアル化できます。

[ Shift(9,6), Shift(76,2), Shift(298,6) ]

演算子を実装してシフトを比較し、それらが重複しているか、または一方に他方が含まれているかを確認できます。

なぜ長さ? 終了時間はどうですか?

間隔を特定の時間に開始し、指定された期間実行すると考えると、重複と封じ込めを検出するための数学の一部が非常に簡単に見えることがわかります。 このようにして行われたシフト間にギャップがないことを証明する方が少し簡単であることがわかりました。

「半開」間隔を使用します。 開始時間はシフトに含まれますが、終了時間は含まれません。

def contains( self, aTime ):
    return self.start <= aTime < self.start + self.length

def before( self, nextShift ):
    return self.start + self.length == nextShift.start

def after( self, prevShift ):
    return prevShift.ends() == self.start

日時に変換するには、週の始まりの基準日が必要です。 その後、いくつかの計算を実行して、シフトの開始時間を計算できます。 長さは(通常)間隔です。

def startDatetime( self, week_start_datetime ):
    offset= datetime.timedelta( seconds= self.start*30*60 )
    return week_start_datetime + offset

def lengthTimedelta( self ):
    return datetime.timedelta( seconds= self.length*30*60 )

def endDatetime( self, week_start_datetime ):
    return self.startDatetime( week_start_datetime ) + self.lengthTimedelta()


1


さて、範囲を抽出するコードが用意されていると仮定します(つまり、 1,2,3,4は[1,4]に変換されます)、標準の日付/時刻演算を使用できない理由がわかりません。

from datetime import datetime, timedelta

def get_shift(start_of_week, start, end):
    """Returns a 2-tuple of datetimes"""
    HALF_HOUR = timedelta(minutes=30)
    return start_of_week + start * HALF_HOUR, start_of_week + (end + 1) * HALF_HOUR

`start_of_week`は月曜日00:00でなければなりません。 これを使用するには、特定の週の「月曜日00:00」を計算する方法が必要です。

この関数は、渡された日付を含む週の月曜日00:00を返します。 たとえば、 `start_of_week_taining(datetime.now())`を試してください。

def start_of_week_containing(dt):
    while dt.weekday() > 0:
        dt = dt - timedelta(days=1)
    return datetime(dt.year, dt.month, dt.day, 0, 0, 0)

完全な例:

start_of_week = start_of_week_containing(datetime.now())
shift_start, shift_end = get_shift(start_of_week, 4, 9)
# now shift_start and shift_end will contain datetime objects