Как создать список времени без високосного дня? - PullRequest
0 голосов
/ 03 февраля 2019

Мне нужно создавать список элементов datetime каждую минуту с 2007-01-01 00:00 до 2016-01-01 00:00, но без 29 февраля.Мой код следующий:

dates = []
date0 = datetime(2007, 1, 1, 0, 0)
delta = td(minutes=1)
while date0 < datetime(2016, 1, 1, 0, 0):
    if date0.date != date(2008, 2, 29) and date0.date != date(2012, 2, 29):
        dates.append(date0)
    date0 = date0 + delta

У меня должен быть список на 9 лет без 29.02.Но мой список дат все еще содержит 29 февраля 2008 и 2012 годов. Я пытался применить этот код:

while date0 < datetime(2016, 1, 1, 0, 0):
    if date0.month != 2 and date0.day != 29:
        dates.append(date0)
    date0 = date0 + delta 

, но в результате у меня есть список, который не содержит подходящего количества дней,только 8 лет и 14 дней.Есть ли у вас решение или идеи по решению проблемы?

Ответы [ 4 ]

0 голосов
/ 03 февраля 2019

Вот относительно эффективный способ Pure Python ™.Пропускаются високосные дни просто по , а не , включая их в таблицу _DAYS_IN_MONTH (поэтому ничего особенного не делается в зависимости от того, является ли текущий год, который обрабатывается, високосным).

Я не знаю точно, почему вы [думаете], что вам это нужно, но, возможно, было бы лучше сделать это с помощью функции генератора , которая избавила бы от необходимости хранить так много datatime объектов впамять в то же время.

from datetime import datetime

_DAYS_IN_MONTH = [31,28,31,30,31,30,31,31,30,31,30,31]  # Ignores leap days.

start_year, end_year = 2007, 2016
dates = []
for year in range(start_year, end_year):
    for month in range(1, 13):
        for day in range(1, _DAYS_IN_MONTH[month-1]+1):
            for hour in range(0, 24):
                for minute in range(0, 60):
                    dates.append(datetime(year, month, day, hour, minute))


print('len(dates): {:,d}'.format(len(dates)))  # -> len(dates): 4,730,400
0 голосов
/ 03 февраля 2019

Вы не можете сравнивать атрибуты объекта datetime с самим объектом, и это является причиной проблемы.

from datetime import datetime, timedelta

dates = []
date0 = datetime(2007, 1, 1, 0, 0)
delta = timedelta(minutes=1)


def get_leaps(startyear, endyear):
    leapyears = []
    for i in range(startyear, endyear):
        if (i%400 == 0)or ((i%4 == 0) and (i%100 != 0)):
            leapyears.append(i)
    for y in leapyears:
        for i in range(24):
            for j in range(60): 
                yield datetime(y, 2, 29, i, j))


while date0 < datetime(2016, 1, 1, 0, 0):
    if date0 not in get_leaps(2007, 2016):
        dates.append(date0)
    date0 += delta 

Это должно быть решением.Это ни в коем случае не оптимизировано и очень не пифонично, но посмотрите, сможете ли вы улучшить его.Завтра у меня экзамен по химии, и у меня нет времени.Ура! * * 1004

0 голосов
/ 03 февраля 2019

Вы можете легко это сделать с помощью pandas популярного пакета для обработки внешних данных:

In []:
import pandas as pd
dr = pd.date_range(start='1/1/2007', end='1/1/2016', freq='1min')
dates = dr[(dr.day != 29) | (dr.month != 2)]

len(dr), len(dates)

Out[]:
(4733281, 4730401)

На моем компьютере это займет около 700ms.

In []:
dates

Out[]:
DatetimeIndex(['2007-01-01 00:00:00', '2007-01-01 00:01:00', '2007-01-01 00:02:00', '2007-01-01 00:03:00',
               '2007-01-01 00:04:00', '2007-01-01 00:05:00', '2007-01-01 00:06:00', '2007-01-01 00:07:00',
               '2007-01-01 00:08:00', '2007-01-01 00:09:00',
               ...
               '2015-12-31 23:51:00', '2015-12-31 23:52:00', '2015-12-31 23:53:00', '2015-12-31 23:54:00',
               '2015-12-31 23:55:00', '2015-12-31 23:56:00', '2015-12-31 23:57:00', '2015-12-31 23:58:00',
               '2015-12-31 23:59:00', '2016-01-01 00:00:00'],
              dtype='datetime64[ns]', length=4730401, freq=None)
0 голосов
/ 03 февраля 2019

Как насчет:

if not (date0.month == 2 and date0.day == 29):
...