Python:查找从今天开始两个月并且从星期一开始的日期
Python: Find date beginning two months prior to today AND start on a Monday
所以我是 python 的初学者,并且一直在使用 datetime、time 和 timedelta 库。我正在尝试创建一段代码,从今天(无论今天是什么时候)开始给我大约两个月前 (exact_two_months_date) 的日期。要注意的是,我想找到大约那个日期。两个月前并在那个星期的星期一开始实际的 start_date。所以从理论上讲,实际开始日期不会恰好是两个月前。从今天开始就是两个月前的周一开始的一周
Example pseudocode:
today = '20150425' ## '%Y%m%d' ... Saturday
exact_two_months_date = '20150225' ## EXACTLY two months ago ... Wednesday
start_date = '20150223' ## this is the Monday of that week two months ago
那么如何找到上面的'start_date'呢?如果恰好两个月前的那一天是周六或周日开始的,那么我只想去下周一。希望这很清楚并且有意义......一旦我找到开始日期,我想每天(仅工作日)增加到 'today'。
感谢任何反馈,谢谢。
老实说,我发现与 datetime
s 一起工作是我必须经常做的最困难的事情,而且我犯了很多错误,所以我将完成这个并展示一些我经常遇到的失败。开始了。
两个约束条件:1) 两个月前的日期,2) 那一周的星期一
两个月前的日期
好的,所以 Python 的 datetime
库有一个名为 replace
的有用方法,它似乎对这里有帮助:
>>> import datetime
>>> now = datetime.date.today()
>>> today
datetime.date(2015, 4, 25)
>>> today.month
4
>>> two_months_ago = today.replace(month=today.month-2)
>>> two_months_ago
datetime.date(2015, 2, 25)
>>> two_months_ago.month
2
但是等等:负数呢?那行不通:
>>> older = datetime.date(2015, 01, 01)
>>> older.replace(month=older.month-2)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ValueError: month must be in 1..12
所以有两种解决方案:
1) 我可以构建一个向前或向后循环的 1-12 范围,或者
2) 要找到两个月前的日期,我只需将日期的 day
部分替换为我所在月份的 1st
日,然后返回 1 天上个月然后然后用我想要的那一天替换上个月的那一天。
(如果你仔细想想,你会发现,如果我在一个月的第 31 天着陆,而且天数比这少,那么这些中的任何一个都可能会出现错误,例如。这是 [=13 的部分原因=]很难。)
def previous_month(date):
current_day = date.day
first_day = date.replace(day=1)
last_day_prev_month = first_day - datetime.timedelta(days=1)
prev_month_day = last_day_prev_month.replace(day=current_day)
return prev_month_day
>>> today = datetime.date.today()
>>> older = previous_month(today)
>>> older
datetime.date(2015, 3, 25)
好吧,假设我们已经很接近了,我们需要进行一些错误检查,以确保我们想要的日期是我们到达的月份内的有效日期。最终,问题是"two months ago" 比我们大声说出来时所想的要多得多。
接下来,我们将解决第二个问题:如何到达该周的星期一?
好吧,datetime
对象有一个工作日方法,所以这部分应该不会太难 here's a nice SO answer on how to do that。
简单的版本是:使用工作日整数的差异来计算返回多少天,然后使用 datetime.timedelta(days=days_difference)
。
要点:与 datetime
一起工作可能很困难。
使用 python-dateutil
计算日期
如果可以选择依赖第三方包,那么 ☞ python-dateutil
提供了一种方便的方法来计算日期。
浏览 ☞ relativedelta to see the wealth of supported parameters. The more calculations a package needs to do with dates, the more a helper module like dateutil
justifies its dependency. For more inspiration on what it has to offer see the ☞ examples page 的文档。
快速运行-通过:
>>> import datetime
>>> from dateutil.relativedelta import relativedelta
>>> today = datetime.date.today()
>>> two_m_ago = today - relativedelta(months=2)
>>> # print two_m_ago ~> datetime.date(2015, 2, 25)
>>> monday = two_m_ago - datetime.timedelta(days=two_m_ago.weekday())
>>> # print monday ~> datetime.date(2015, 2, 23)
通过 weekday()
获取星期一
一旦我们在变量 two_m_ago
中有了两个月前的日期,我们就从中减去 weekday()
的索引。该索引在星期一为 0
,在星期日一直到 6
。如果 two_m_ago
已经是星期一,则减去 0
不会导致任何更改。
这样的事情对你有用吗?
import datetime
today = datetime.date.today()
delta = datetime.timedelta(days=60) # ~ 2 months
thatDay = today - delta
# subtract weekdays to get monday
thatMonday = thatDay - datetime.timedelta(days=thatDay.weekday())
Python 中的日期操作非常复杂。使用 arrow
包大大简化了这些操作,您将节省大量时间。
首先安装它
pip install arrow
现在你的问题:
import arrow
# get local current time
now = arrow.now('local')
# move 2 months back
old = now.replace(months=-2)
# what day of the week was that?
dow = old.isoweekday()
# reset old to Monday, for instance at 9:32 in the morning (this is just an example, just to show case)
old = old.replace(days=-dow, hour=9, minute=32, second=0)
print('now is {now}, we went back to {old}'.format(now=now.isoformat(), old=old.isoformat()))
输出:
now is 2015-04-25T20:37:38.174000+02:00, we went back to 2015-02-22T09:32:00.174000+01:00
请注意,各种格式、时区等现在都是透明的,您只需要依赖一个包。
所以我是 python 的初学者,并且一直在使用 datetime、time 和 timedelta 库。我正在尝试创建一段代码,从今天(无论今天是什么时候)开始给我大约两个月前 (exact_two_months_date) 的日期。要注意的是,我想找到大约那个日期。两个月前并在那个星期的星期一开始实际的 start_date。所以从理论上讲,实际开始日期不会恰好是两个月前。从今天开始就是两个月前的周一开始的一周
Example pseudocode:
today = '20150425' ## '%Y%m%d' ... Saturday
exact_two_months_date = '20150225' ## EXACTLY two months ago ... Wednesday
start_date = '20150223' ## this is the Monday of that week two months ago
那么如何找到上面的'start_date'呢?如果恰好两个月前的那一天是周六或周日开始的,那么我只想去下周一。希望这很清楚并且有意义......一旦我找到开始日期,我想每天(仅工作日)增加到 'today'。
感谢任何反馈,谢谢。
老实说,我发现与 datetime
s 一起工作是我必须经常做的最困难的事情,而且我犯了很多错误,所以我将完成这个并展示一些我经常遇到的失败。开始了。
两个约束条件:1) 两个月前的日期,2) 那一周的星期一
两个月前的日期
好的,所以 Python 的 datetime
库有一个名为 replace
的有用方法,它似乎对这里有帮助:
>>> import datetime
>>> now = datetime.date.today()
>>> today
datetime.date(2015, 4, 25)
>>> today.month
4
>>> two_months_ago = today.replace(month=today.month-2)
>>> two_months_ago
datetime.date(2015, 2, 25)
>>> two_months_ago.month
2
但是等等:负数呢?那行不通:
>>> older = datetime.date(2015, 01, 01)
>>> older.replace(month=older.month-2)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ValueError: month must be in 1..12
所以有两种解决方案:
1) 我可以构建一个向前或向后循环的 1-12 范围,或者
2) 要找到两个月前的日期,我只需将日期的 day
部分替换为我所在月份的 1st
日,然后返回 1 天上个月然后然后用我想要的那一天替换上个月的那一天。
(如果你仔细想想,你会发现,如果我在一个月的第 31 天着陆,而且天数比这少,那么这些中的任何一个都可能会出现错误,例如。这是 [=13 的部分原因=]很难。)
def previous_month(date):
current_day = date.day
first_day = date.replace(day=1)
last_day_prev_month = first_day - datetime.timedelta(days=1)
prev_month_day = last_day_prev_month.replace(day=current_day)
return prev_month_day
>>> today = datetime.date.today()
>>> older = previous_month(today)
>>> older
datetime.date(2015, 3, 25)
好吧,假设我们已经很接近了,我们需要进行一些错误检查,以确保我们想要的日期是我们到达的月份内的有效日期。最终,问题是"two months ago" 比我们大声说出来时所想的要多得多。
接下来,我们将解决第二个问题:如何到达该周的星期一?
好吧,datetime
对象有一个工作日方法,所以这部分应该不会太难 here's a nice SO answer on how to do that。
简单的版本是:使用工作日整数的差异来计算返回多少天,然后使用 datetime.timedelta(days=days_difference)
。
要点:与 datetime
一起工作可能很困难。
使用 python-dateutil
计算日期
如果可以选择依赖第三方包,那么 ☞ python-dateutil
提供了一种方便的方法来计算日期。
浏览 ☞ relativedelta to see the wealth of supported parameters. The more calculations a package needs to do with dates, the more a helper module like dateutil
justifies its dependency. For more inspiration on what it has to offer see the ☞ examples page 的文档。
快速运行-通过:
>>> import datetime
>>> from dateutil.relativedelta import relativedelta
>>> today = datetime.date.today()
>>> two_m_ago = today - relativedelta(months=2)
>>> # print two_m_ago ~> datetime.date(2015, 2, 25)
>>> monday = two_m_ago - datetime.timedelta(days=two_m_ago.weekday())
>>> # print monday ~> datetime.date(2015, 2, 23)
通过 weekday()
获取星期一
一旦我们在变量 two_m_ago
中有了两个月前的日期,我们就从中减去 weekday()
的索引。该索引在星期一为 0
,在星期日一直到 6
。如果 two_m_ago
已经是星期一,则减去 0
不会导致任何更改。
这样的事情对你有用吗?
import datetime
today = datetime.date.today()
delta = datetime.timedelta(days=60) # ~ 2 months
thatDay = today - delta
# subtract weekdays to get monday
thatMonday = thatDay - datetime.timedelta(days=thatDay.weekday())
Python 中的日期操作非常复杂。使用 arrow
包大大简化了这些操作,您将节省大量时间。
首先安装它
pip install arrow
现在你的问题:
import arrow
# get local current time
now = arrow.now('local')
# move 2 months back
old = now.replace(months=-2)
# what day of the week was that?
dow = old.isoweekday()
# reset old to Monday, for instance at 9:32 in the morning (this is just an example, just to show case)
old = old.replace(days=-dow, hour=9, minute=32, second=0)
print('now is {now}, we went back to {old}'.format(now=now.isoformat(), old=old.isoformat()))
输出:
now is 2015-04-25T20:37:38.174000+02:00, we went back to 2015-02-22T09:32:00.174000+01:00
请注意,各种格式、时区等现在都是透明的,您只需要依赖一个包。