使用时间和日期对象分析数据

时间:2010-08-13 18:28:58

标签: python django

我想解决一个相当独特的问题:

根据此样本数据(实际数据是非常多的记录,每张卡每天至少4张):

serial, card, rec_date, rec_time, retrieved_on
2976 00040  2010-07-29 18:57 2010-07-31 13:37:31 
2977 00040  2010-07-30 09:58 2010-07-31 13:37:31
2978 00040  2010-07-30 15:33 2010-07-31 13:37:31
2979 00040  2010-07-30 16:13 2010-07-31 13:37:31
2980 00040  2010-07-30 19:41 2010-07-31 13:37:31

记录来自时钟系统。

我想要做的是选择一组条目,按cardrec_date过滤,然后确定此人在白天工作的时间和每个工作时间的长度,如何他/她已经休息了许多休息时间,并在本周末获得了总工作时数。

从上面的列表中,2977是签入,然后2978是签出,依此类推。

我迷失了如何做到这一点,所以我认为这里有人会有一个想法。

我从其他地方导入其他数据后使用一个简单的类来存储这些数据:

class TimeClock(models.Model):
  serial = models.CharField(max_length = 16)
  card_no = models.CharField(max_length = 10)
  rec_date = models.DateField()
  rec_time = models.TimeField()
  oper_date = models.DateTimeField(default=datetime.today)

2 个答案:

答案 0 :(得分:2)

显然,TimeClock类本身就不适合你正在做的事情。

您需要总结TimeClock以创建可以使用的WorkIntervals。这些是显示工作范围(理论)开始和结束的TimeClock行对。

如果有人未能入时,你完全无法推断出正在发生的事情。 这不是“难”,这是不可能的。

此外,如果有人在午夜过夜,你无法推断出发生的事情。 这不是“难”,这是不可能的。

但是,我们会假装没有人在午夜过夜,也没有人无法进出(hahaha)

def make_pairs( tc_query_set ):
    start = None
    for row in tc_query_set:
         if start is None:
             start= row
             continue
         elif start.card == row.card and start.rec_date == row.rec_date:
             yield start, row
             start= None
         else:
             # May as well raise an exception -- the data cannot the processed
             yield start, None 
             start= row

您可以按如下方式使用。

data = TimeClock.objects.order_by('card','rec_date','rec_time').all()
for start, end in make_pairs( data ):
    WorkIntervals.objects.create( start.card, start.rec_date, start.rec_time, end.rec_time, ... )

现在您可以使用间隔。如果可以创建它们。

答案 1 :(得分:1)

嗯,这里有一堆独立的问题。我假设您已经获得了过滤数据,因此您的日志看起来像特定日期的唯一卡的所有事件。假设此数据存储为log中的字符串列表。然后:

import datetime
def dates( log ):
    ''' Yields consecutive datetimes in the log. '''
    for event in log:
        yield datetime.datetime.strptime( event[ 12 : 28 ], "%Y-%m-%d %H:%M" )

def time_clocked_in( log ):
    assert not len( log ) % 2
    total_time = datetime.timedelta( 0 )
    event_dates = dates( log )
    try:
        while 1:
            total_time -= next( event_dates ) - next( event_dates )
    except StopIteration:
        pass
    return total_time

log = [
    "2977 00040  2010-07-30 09:58 2010-07-31 13:37:31",
    "2978 00040  2010-07-30 15:33 2010-07-31 13:37:31",
    "2979 00040  2010-07-30 16:13 2010-07-31 13:37:31",
    "2980 00040  2010-07-30 19:41 2010-07-31 13:37:31"
]

print( time_clocked_in( log ) )
>>> 9:03:00