2016-02-24 2 views
0

Учитывая объект datetime, как его округлить до следующего появления 8AM PST?Как округлить дату и время до определенного времени?

+1

Создайте новый DateTime, используйте вход с текущей датой и время года, месяца, дня и установить часы, мин, секунд как 8, 0, 0 соответственно – Ian

+2

@Ian: Это всегда было бы сегодня 8AM. Чтобы всегда округлить, вам нужно добавить еще один день сверху, если он не был до 8 утра. – jsfan

+0

связанный: [округление до ближайших 30 минут в python] (http://stackoverflow.com/q/32723150/4279) – jfs

ответ

1

Если результат является часовым поясом, известно, объект даты и времени в часовом поясе с нефиксированной UTC смещение, то вы не можете просто позвонить .replace() или .combine() - это может создать DateTime с неправильной UTC смещением. Вопрос аналогичен How do I get the UTC time of "midnight" for a given timezone? (00:00 используется вместо 08:00).

Предполагая, что 8 утра всегда существует и однозначно в PST:

from datetime import datetime, time as datetime_time, timedelta 
import pytz # $ pip install pytz 

def next_8am_in_pst(aware_dt, tz=pytz.timezone('America/Los_Angeles')): 
    pst_aware_dt = tz.normalize(aware_dt.astimezone(tz)) # convert to PST 
    naive_dt = round_up_to_8am(pst_aware_dt.replace(tzinfo=None)) 
    return tz.localize(naive_dt, is_dst=None) 

def round_up_to_8am(dt): 
    rounded = datetime.combine(dt, datetime_time(8)) 
    return rounded + timedelta(rounded < dt) 

Пример:

>>> str(next_8am_in_pst(datetime.now(pytz.utc))) 
'2016-02-25 08:00:00-08:00' 
+0

Спасибо, это работает через переход на летнее время. – camomilk

0

Я сделал ответ, основанный на некоторые идеи из комментариев:

def nextDay(d): 
    pstTime = d.astimezone(pytz.timezone('US/Pacific')) 
    pstTime = pstTime.replace(hour=8, minute=0, second=0, microsecond=0) 

    if pstTime < d: 
     pstTime += datetime.timedelta(days=1) 

    return pstTime 
+1

может закончиться с датами с переходом на DST – jfs

1

Просто проверить, является ли время до или после 8, а затем добавить в день, если это после того, как и построить новый DateTime.

import datetime 

def round_datetime(dt): 
    t = datetime.time(8) 
    # If time is after 8am, add a day. 
    if dt.time() > datetime.time(8): 
     dt += datetime.timedelta(days=1) 
    return datetime.datetime.combine(dt, t) 
+0

Спасибо, я не понимал, что вы можете разделить дату и время. – camomilk

+0

, если вход представляет собой объект datetime, учитывающий часовой пояс, тогда он более сложный (ваш код в порядке, если вход является наивным объектом datetime). – jfs

Смежные вопросы