如何创建没有闰日的日期时间列表?
How to create list of datetimes without a leap day?
我需要从 2007-01-01 00:00 到 2016-01-01 00:00 每分钟创建一个日期时间元素列表,但没有 2 月 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
没有29.02我应该有9年的单子。但是我的日期列表仍然包含 2008 年 2 月 29 日和 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 天。
您对解决该问题有任何解决方案或想法吗?
怎么样:
if not (date0.month == 2 and date0.day == 29):
您无法将 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
这应该是解决方案。这绝不是优化的,而且非常不符合 pythonic,但看看你是否可以改进它。我明天有化学考试,我没有时间。干杯!
您可以使用 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)
这是一种相对高效的纯 Python™ 方法。跳过闰日的方式很简单 not 将它们包含在 _DAYS_IN_MONTH
table 中(因此根据当前年份是否被处理,没有什么特别的是闰年)。
我不确切地知道你为什么[认为]你需要这个,但最好通过 generator function 来完成,这样就不需要存储那么多 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
我需要从 2007-01-01 00:00 到 2016-01-01 00:00 每分钟创建一个日期时间元素列表,但没有 2 月 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
没有29.02我应该有9年的单子。但是我的日期列表仍然包含 2008 年 2 月 29 日和 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 天。 您对解决该问题有任何解决方案或想法吗?
怎么样:
if not (date0.month == 2 and date0.day == 29):
您无法将 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
这应该是解决方案。这绝不是优化的,而且非常不符合 pythonic,但看看你是否可以改进它。我明天有化学考试,我没有时间。干杯!
您可以使用 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)
这是一种相对高效的纯 Python™ 方法。跳过闰日的方式很简单 not 将它们包含在 _DAYS_IN_MONTH
table 中(因此根据当前年份是否被处理,没有什么特别的是闰年)。
我不确切地知道你为什么[认为]你需要这个,但最好通过 generator function 来完成,这样就不需要存储那么多 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