Ceil a datetime to next quarter of an hour

后端 未结 6 1442
花落未央
花落未央 2020-12-03 07:38

Let\'s imagine this datetime

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

I\'d l

6条回答
  •  眼角桃花
    2020-12-03 08:00

    @Mark Dickinson suggested the best formula so far:

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

    In Python 3, for an arbitrary time delta (not just 15 minutes):

    #!/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
    

    To avoid intermediate floats, divmod() could be used:

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

    Example:

    >>> 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 "", line 1, in 
      File "", 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)
    

提交回复
热议问题