복붙노트

[PYTHON] 파이썬 - Ceil, datetime, 다음 1/4 분기

PYTHON

파이썬 - Ceil, datetime, 다음 1/4 분기

이 datetime을 상상해 봅시다.

>>> import datetime
>>> dt = datetime.datetime(2012, 10, 25, 17, 32, 16)

나는 시간의 다음 1/4에 그것을 ceil하고 싶다.

datetime.datetime(2012, 10, 25, 17, 45)

나는 상상한다.

>>> quarter = datetime.timedelta(minutes=15)
>>> import math
>>> ceiled_dt = math.ceil(dt / quarter) * quarter

물론 이것은 작동하지 않습니다.

해결법

  1. ==============================

    1.이것은 마이크로 초를 고려합니다!

    이것은 마이크로 초를 고려합니다!

    import math
    
    def ceil_dt(dt):
        # how many secs have passed this hour
        nsecs = dt.minute*60 + dt.second + dt.microsecond*1e-6  
        # number of seconds to next quarter hour mark
        # Non-analytic (brute force is fun) way:  
        #   delta = next(x for x in xrange(0,3601,900) if x>=nsecs) - nsecs
        # analytic way:
        delta = math.ceil(nsecs / 900) * 900 - nsecs
        #time + number of seconds to quarter hour mark.
        return dt + datetime.timedelta(seconds=delta)
    
    t1 = datetime.datetime(2017, 3, 6, 7, 0)
    assert ceil_dt(t1) == t1
    
    t2 = datetime.datetime(2017, 3, 6, 7, 1)
    assert ceil_dt(t2) == datetime.datetime(2017, 3, 6, 7, 15)
    
    t3 = datetime.datetime(2017, 3, 6, 7, 15)
    assert ceil_dt(t3) == t3
    
    t4 = datetime.datetime(2017, 3, 6, 7, 16)
    assert ceil_dt(t4) == datetime.datetime(2017, 3, 6, 7, 30)
    
    t5 = datetime.datetime(2017, 3, 6, 7, 30)
    assert ceil_dt(t5) == t5
    
    t6 = datetime.datetime(2017, 3, 6, 7, 31)
    assert ceil_dt(t6) == datetime.datetime(2017, 3, 6, 7, 45)
    
    t7 = datetime.datetime(2017, 3, 6, 7, 45)
    assert ceil_dt(t7) == t7
    
    t8 = datetime.datetime(2017, 3, 6, 7, 46)
    assert ceil_dt(t8) == datetime.datetime(2017, 3, 6, 8, 0)
    

    델타의 설명 :

  2. ==============================

    2.

    def ceil(dt):
        if dt.minute % 15 or dt.second:
            return dt + datetime.timedelta(minutes = 15 - dt.minute % 15,
                                           seconds = -(dt.second % 60))
        else:
            return dt
    

    이것은 당신에게 :

    >>> ceil(datetime.datetime(2012,10,25, 17,45))
    datetime.datetime(2012, 10, 25, 17, 45)
    >>> ceil(datetime.datetime(2012,10,25, 17,45,1))
    datetime.datetime(2012, 10, 25, 18, 0)
    >>> ceil(datetime.datetime(2012,12,31,23,59,0))
    datetime.datetime(2013,1,1,0,0)
    
  3. ==============================

    3.@ 마크 디킨슨은 지금까지 최고의 공식을 제안했다.

    @ 마크 디킨슨은 지금까지 최고의 공식을 제안했다.

    def ceil_dt(dt, delta):
        return dt + (datetime.min - dt) % delta
    

    Python 3에서 임의의 시간 델타 (15 분이 아님)의 경우 :

    #!/usr/bin/env python3
    import math
    from datetime import datetime, timedelta
    
    def ceil_dt(dt, delta):
        return datetime.min + math.ceil((dt - datetime.min) / delta) * delta
    
    print(ceil_dt(datetime(2012, 10, 25, 17, 32, 16), timedelta(minutes=15)))
    # -> 2012-10-25 17:45:00
    

    중간 수레를 피하기 위해 divmod ()를 사용할 수 있습니다 :

    def ceil_dt(dt, delta):
        q, r = divmod(dt - datetime.min, delta)
        return (datetime.min + (q + 1)*delta) if r else dt
    

    예:

    >>> ceil_dt(datetime(2012, 10, 25, 17, 32, 16), timedelta(minutes=15))
    datetime.datetime(2012, 10, 25, 17, 45)
    >>> ceil_dt(datetime.min, datetime.resolution) 
    datetime.datetime(1, 1, 1, 0, 0)
    >>> ceil_dt(datetime.min, 2*datetime.resolution)
    datetime.datetime(1, 1, 1, 0, 0)
    >>> ceil_dt(datetime.max, datetime.resolution)
    datetime.datetime(9999, 12, 31, 23, 59, 59, 999999)
    >>> ceil_dt(datetime.max, 2*datetime.resolution)
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
      File "<stdin>", line 3, in ceil_dt
    OverflowError: date value out of range
    >>> ceil_dt(datetime.min+datetime.resolution, datetime.resolution)
    datetime.datetime(1, 1, 1, 0, 0, 0, 1)
    >>> ceil_dt(datetime.min+datetime.resolution, 2*datetime.resolution)
    datetime.datetime(1, 1, 1, 0, 0, 0, 2)
    >>> ceil_dt(datetime.max-datetime.resolution, datetime.resolution)
    datetime.datetime(9999, 12, 31, 23, 59, 59, 999998)
    >>> ceil_dt(datetime.max-datetime.resolution, 2*datetime.resolution)
    datetime.datetime(9999, 12, 31, 23, 59, 59, 999998)
    >>> ceil_dt(datetime.max-2*datetime.resolution, datetime.resolution)
    datetime.datetime(9999, 12, 31, 23, 59, 59, 999997)
    >>> ceil_dt(datetime.max-2*datetime.resolution, 2*datetime.resolution)
    datetime.datetime(9999, 12, 31, 23, 59, 59, 999998)
    >>> ceil_dt(datetime.max-timedelta(1), datetime.resolution)
    datetime.datetime(9999, 12, 30, 23, 59, 59, 999999)
    >>> ceil_dt(datetime.max-timedelta(1), 2*datetime.resolution)
    datetime.datetime(9999, 12, 31, 0, 0)
    >>> ceil_dt(datetime.min, datetime.max-datetime.min)
    datetime.datetime(1, 1, 1, 0, 0)
    >>> ceil_dt(datetime.max, datetime.max-datetime.min)
    datetime.datetime(9999, 12, 31, 23, 59, 59, 999999)
    
  4. ==============================

    4.정확한 분을 계산하고 분, 초를 0으로 설정 한 후 datetime 객체에 추가해야합니다.

    정확한 분을 계산하고 분, 초를 0으로 설정 한 후 datetime 객체에 추가해야합니다.

    import datetime
    
    def quarter_datetime(dt):
        minute = (dt.minute//15+1)*15
        return dt.replace(minute=0, second=0)+datetime.timedelta(minutes=minute)
    
    for minute in [12, 22, 35, 52]:
        print quarter_datetime(datetime.datetime(2012, 10, 25, 17, minute, 16))
    

    모든 경우에 적용됩니다.

    2012-10-25 17:15:00
    2012-10-25 17:30:00
    2012-10-25 17:45:00
    2012-10-25 18:00:00
    
  5. from https://stackoverflow.com/questions/13071384/python-ceil-a-datetime-to-next-quarter-of-an-hour by cc-by-sa and MIT license