Округление даты и времени до ближайшего часа

У меня есть вопрос, очень похожий на этот и этот, но я застрял на каком-то округлении проблема.

У меня есть временной ряд из файла netCDF, и я пытаюсь преобразовать их в формат даты и времени. Формат временного ряда — «дни с 1990-01-01 00:00:00». В конце концов я хочу вывести в формате .strftime('%Y%m%d.%H%M'). Так, например, я прочитал свой файл netCDF следующим образом

import netCDF4
nc = netCDF4.Dataset(file_name)
time = np.array(nc['time'][:])

у меня тогда есть

In [180]: time[0]
Out[180]: 365
In [181]: time[1]
Out[181]: 365.04166666651145

я тогда сделал

In [182]: start = datetime.datetime(1990,1,1)
In [183]: delta = datetime.timedelta(time[1])
In [184]: new_time = start + delta
In [185]: print(new_time.strftime('%Y%m%d.%H%M'))
19910101.0059

Есть ли способ «округлить» до ближайшего часа, чтобы я получил 19910101.0100?


person Hawky    schedule 05.01.2018    source источник
comment
Что представляет собой 365.04166666651145?   -  person Sohaib Farooqi    schedule 05.01.2018
comment
Дней с 1990-01-01 00:00:00 @GarbageCollector   -  person Hawky    schedule 05.01.2018
comment
С тех пор до сегодняшнего дня? Нет, это не так... Есть гораздо лучшие способы получить дни с тех пор, как   -  person OneCricketeer    schedule 05.01.2018
comment
А как вы определяете ближайший час? 29 минут округляется в меньшую сторону? 30 минут округляется?   -  person OneCricketeer    schedule 05.01.2018
comment
Я получил время (в днях) из файла netCDF, как было указано изначально. Это довольно распространенный формат даты в наборах данных netCDF. Вывод в файле netCDF ежечасный (например, 365, 365.04166666651145, 365.08333333348855 и т. д.), но при загрузке файла где-то есть ошибка округления. Поэтому мне не нужно иметь дело с округлением минут - это будет просто округление миллисекунд вверх/вниз. Я отредактировал исходный вопрос, чтобы уточнить, откуда берется time.   -  person Hawky    schedule 05.01.2018
comment
Если вы используете pandas, см. этот ответ   -  person Pavel    schedule 10.12.2018


Ответы (2)


Вы можете округлить в меньшую сторону с помощью datetime.replace() и округлить в большую сторону на добавление часа к округленному значению с помощью datetime.timedelta(hours=1).

import datetime

def round_to_hour(dt):
    dt_start_of_hour = dt.replace(minute=0, second=0, microsecond=0)
    dt_half_hour = dt.replace(minute=30, second=0, microsecond=0)

    if dt >= dt_half_hour:
        # round up
        dt = dt_start_of_hour + datetime.timedelta(hours=1)
    else:
        # round down
        dt = dt_start_of_hour

    return dt

Обратите внимание: поскольку мы используем replace, значения, которые мы не заменяем (например, часовой пояс — tzinfo), будут сохранены.

person John Carter    schedule 05.01.2018

Я не думаю, что datetime обеспечивает способ округления времени, вам придется предоставить код, чтобы сделать это самостоятельно. Что-то вроде этого должно работать:

def round_to_hour(dt):
    round_delta = 60 * 30
    round_timestamp = datetime.datetime.fromtimestamp(dt.timestamp() + round_delta)
    round_dt = datetime.datetime.fromtimestamp(round_timestamp)

    return round_dt.replace(microsecond=0, second=0, minute=0)
person Turn    schedule 05.01.2018
comment
небольшая ошибка с этим - в настоящее время это отбрасывает tzinfo - person John Carter; 05.01.2018