这是我目前的代码
class TimeSeries():
def year(year):
today = datetime.now()
start_date = today+relativedelta(years=-1)
mint, maxt = datetime.min.time(), datetime.max.time()
for st in rrule(MONTHLY, count=24, bymonthday=(1,-1,), dtstart=start_date):
yield st.combine(st, mint)
这是从这个输出:
for y in TimeSeries().year():
print(y)
2013-01-31 00:00:00
2013-02-01 00:00:00
2013-02-28 00:00:00
2013-03-01 00:00:00
2013-03-31 00:00:00
2013-04-01 00:00:00
2013-04-30 00:00:00
2013-05-01 00:00:00
2013-05-31 00:00:00
2013-06-01 00:00:00
2013-06-30 00:00:00
2013-07-01 00:00:00
2013-07-31 00:00:00
2013-08-01 00:00:00
2013-08-31 00:00:00
2013-09-01 00:00:00
2013-09-30 00:00:00
2013-10-01 00:00:00
2013-10-31 00:00:00
2013-11-01 00:00:00
2013-11-30 00:00:00
2013-12-01 00:00:00
2013-12-31 00:00:00
2014-01-01 00:00:00
问题是如何强制计数从2013-01-01 00:00:00和月末开始,如2013-01-31 23:59:59等等。 循环结束于2014-01-31 23:59:59而不是2014-01-01 00:00:00
结束另外,我喜欢在一行上创建开始日期和结束日期:
2013-03-01 00:00:00 2013-03-31 23:59:59
2013-04-01 00:00:00 2013-03-30 23:59:59
...
...
2014-01-01 00:00:00 2014-01-31 23:59:59
有什么建议吗?
答案 0 :(得分:0)
首先,您确定要2013-03-31 23:59:59
吗?传统上,日期间隔被指定为半开间隔 - 就像Python中的范围一样。原因是23:59:59
实际上不是一天的结束。
最明显的是,23:59:59.001
晚于此,但在同一天。 Python datetime
对象包括微秒,所以这不仅仅是一个“meh,无论如何”的问题 - 如果你,例如,调用now()
,你可以得到一个错误的时间晚于你的“结束“在同一天。
不太明显,在leap second的某一天,23:59:60
也会在同一天发布。
但如果你真的想要这个,那么有两种明显的方法可以实现它:
您已经在迭代日期而不是日期时间并手动组合时间。当你处理第1天与第-1天时,这是显而易见的,因为约会的day
成员将是1
或者不是。{1}}成员。所以:
class TimeSeries():
def year(year):
today = datetime.now()
start_date = today+relativedelta(years=-1)
mint, maxt = datetime.min.time(), datetime.max.time()
for st in rrule(MONTHLY, count=24, bymonthday=(1, -1,), dtstart=start_date):
yield st.combine(st, mint if st.day=1 else maxt)
或者,不是迭代第一天和最后几天,只是迭代第一天,然后减去第二天以获得上个月的最后一秒:
class TimeSeries():
def year(year):
today = datetime.now()
start_date = today+relativedelta(years=-1)
mint, maxt = datetime.min.time(), datetime.max.time()
for st in rrule(MONTHLY, count=24, bymonthday=(1,), dtstart=start_date):
dt = st.combine(st, mint)
yield dt - timedelta(seconds=1)
yield dt
至于成对打印这些......好吧,正如所写的那样,这是一个不明确的问题。列表中的第一个值是一对中的第二个值 - 除非您在一个月的第一天运行它。同样,最后一个日期是一对中的第一个值,除非你在31日运行它。那么,你想用它们做什么?
如果这不明显,请查看您的示例。您的第一个值为2013-01-31 00:00:00
,但您的第一对价格不是从2013-01-31开始的。
2013-01-01
,并且总会有对。2013-01-31
,并且总会有对。None
作为缺失值。无论你真正想要什么规则都可以轻松编码。然后你可能想要{开始,结束)元组yield
,所以print
循环可以这样做:
for start, end in TimeSeries().year():
print(start, end)