【问题标题】:Best way to serialize a range of hours to meaningful data将一系列小时序列化为有意义的数据的最佳方法
【发布时间】:2009-12-22 13:03:56
【问题描述】:

我的网络应用程序的一部分涉及使用拖放选择器为每天创建“约会”(班次)。目前,这些数据被序列化为这样的:

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

其中每个数字代表一周中的第 n 个半小时(所以 304 是一周中的第 300 个半小时,或周六上午 8 点)。

然后我在服务器上用 Python 把它解析成更合理的东西:

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

但是我在将它们整齐地转换为datetime 对象时遇到了麻烦,主要是因为...首先发送到服务器的数据很俗气。

我的问题是这样的: 使用 Javascript 和 Python 序列化所选“班次”并将其转换为 datetime 对象的“最佳”方法是什么

我有一个 live version 我想出的伪劣 HTML/Javascript。我在客户端使用 Javascript/jQuery,在服务器上使用 Python/Django。

【问题讨论】:

    标签: javascript jquery python serialization


    【解决方案1】:

    你说的是间隔。

    设置间隔的最佳方式是开始时间和持续时间。

    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()
    

    【讨论】:

    • ...但我仍然没有任何日期时间对象。
    【解决方案2】:

    好吧,假设您有提取范围的代码(即 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_containing(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
    

    【讨论】:

    • 需要在最后一行将end 更改为(end + 1),看起来像。
    • 什么是 start_of_week? start = 0 == start_of_week 吗?
    • 已编辑以修复和澄清。 start_of_week 是特定周的星期一 00:00。
    • 是的:如果 start == 0,则返回的元组的第一项是 start_of_week。
    猜你喜欢
    • 2017-10-15
    • 2011-07-09
    • 1970-01-01
    • 2015-09-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-11-06
    相关资源
    最近更新 更多