![](/img/trans.png)
[英]How to get dates for => recent friday,friday of last week , friday of 2nd last week,friday of 3rd last wk ,friday of nth last wk from a single code?
[英]How can I get the 3rd Friday of a month in Python?
我正在尝试从雅虎获取股票数据。 财务使用 Python 2.7,9. 但我只需要本月第三个星期五的数据,我有一个 function 来获取数据。 但需要一种获取日期的方法:我想要这样的东西:
def get_third_fris(how_many):
# code and stuff
return list_of_fris
因此调用get_third_fris(6)
将返回当前日期之后的第 3 个星期五的 6 项长列表。 日期需要是 Unix 时间戳。
(我对time
或datetime
几乎没有经验,所以请解释你的代码在做什么。)
谢谢!
您可以使用calendar
模块列出周,然后获取该周的星期五。
import calendar
c = calendar.Calendar(firstweekday=calendar.SUNDAY)
year = 2015; month = 2
monthcal = c.monthdatescalendar(year,month)
third_friday = [day for week in monthcal for day in week if \
day.weekday() == calendar.FRIDAY and \
day.month == month][2]
您可以格式化为 Unix 时间戳,但这很重要。 我会向您推荐这个优秀的答案,其中包含基于您的日期是否时区感知的信息。
我们不需要导入除日期时间以外的任何内容。 我们可以假设一周有 7 天,而工作日 0 == 星期一。
import datetime
def third_friday(year, month):
"""Return datetime.date for monthly option expiration given year and
month
"""
# The 15th is the lowest third day in the month
third = datetime.date(year, month, 15)
# What day of the week is the 15th?
w = third.weekday()
# Friday is weekday 4
if w != 4:
# Replace just the day (of month)
third = third.replace(day=(15 + (4 - w) % 7))
return third
您可以使用标准的 Python 函数来查找本月的第三个星期五:
from datetime import timedelta, date
import calendar
def next_third_friday(d):
""" Given a third friday find next third friday"""
d += timedelta(weeks=4)
return d if d.day >= 15 else d + timedelta(weeks=1)
def third_fridays(d, n):
"""Given a date, calculates n next third fridays"""
# Find closest friday to 15th of month
s = date(d.year, d.month, 15)
result = [s + timedelta(days=(calendar.FRIDAY - s.weekday()) % 7)]
# This month's third friday passed. Find next.
if result[0] < d:
result[0] = next_third_friday(result[0])
for i in range(n - 1):
result.append(next_third_friday(result[-1]))
return result
我们可以应用上面的函数来获取下一个星期五的时间戳:
import time
def timestamp(d):
return int(time.mktime(d.timetuple()))
fridays = third_fridays(date.today(), 2)
print(fridays)
print(map(timestamp, fridays))
输出:
[datetime.date(2015, 3, 20), datetime.date(2015, 4, 17)]
[1426802400, 1429218000]
假设你想要一个每第三个星期五的范围,你可以只使用熊猫,示例代码:
import pandas as pd
pd.date_range('2017-12-02','2020-08-31',freq='WOM-3FRI')
Output:
DatetimeIndex(['2017-12-15', '2018-01-19', '2018-02-16', '2018-03-16',
'2018-04-20', '2018-05-18', '2018-06-15', '2018-07-20',
'2018-08-17', '2018-09-21', '2018-10-19', '2018-11-16',
'2018-12-21', '2019-01-18', '2019-02-15', '2019-03-15',
'2019-04-19', '2019-05-17', '2019-06-21', '2019-07-19',
'2019-08-16', '2019-09-20', '2019-10-18', '2019-11-15',
'2019-12-20', '2020-01-17', '2020-02-21', '2020-03-20',
'2020-04-17', '2020-05-15', '2020-06-19', '2020-07-17',
'2020-08-21'],
dtype='datetime64[ns]', freq='WOM-3FRI')
一个更直接的答案怎么样:
import calendar
c = calendar.Calendar(firstweekday=calendar.SATURDAY)
monthcal = c.monthdatescalendar(my_year, my_month)
monthly_expire_date = monthcal[2][-1]
它易于使用 dateutil 获取下一个星期五
import dateutil.parser as dparse
from datetime import timedelta
next_friday = dparse.parse("Friday")
one_week = timedelta(days=7)
friday_after_next = next_friday + one_week
last_friday = friday_after_next + one_week
这利用了这样一个事实,即星期五之间总是有一周的时间......尽管我不确定这是否能回答您的问题,但它至少应该为您提供一个良好的起点
from dateutil.relativedelta import relativedelta, FR # $ pip install python-dateutil
def third_friday_dateutil(now):
"""the 3rd Friday of the month, not the 3rd Friday after today."""
now = now.replace(day=1) # 1st day of the month
now += relativedelta(weeks=2, weekday=FR)
return now
或者使用dateutil.rrule
:
from datetime import date, timedelta
from dateutil.rrule import rrule, MONTHLY, FR
def third_friday_rrule(now):
return rrule(MONTHLY, count=1, byweekday=FR, bysetpos=3, dtstart=now.replace(day=1))[0]
def get_third_fris_rrule(how_many):
return list(rrule(MONTHLY, count=how_many, byweekday=FR, bysetpos=3, dtstart=date.today()+timedelta(1)))
这是一个蛮力解决方案(快 15 倍):
#!/usr/bin/env python
import calendar
from datetime import date, timedelta
from itertools import islice
DAY = timedelta(1)
WEEK = 7*DAY
def fridays(now):
while True:
if now.weekday() == calendar.FRIDAY:
while True:
yield now
now += WEEK
now += DAY
def next_month(now):
"""Return the first date that is in the next month."""
return (now.replace(day=15) + 20*DAY).replace(day=1)
def third_friday_brute_force(now):
"""the 3rd Friday of the month, not the 3rd Friday after today."""
return next(islice(fridays(now.replace(day=1)), 2, 3))
def get_third_fris(how_many):
result = []
now = date.today()
while len(result) < how_many:
fr = third_friday_brute_force(now)
if fr > now: # use only the 3rd Friday after today
result.append(fr)
now = next_month(now)
return result
print(get_third_fris(6))
[datetime.date(2015, 3, 20),
datetime.date(2015, 4, 17),
datetime.date(2015, 5, 15),
datetime.date(2015, 6, 19),
datetime.date(2015, 7, 17),
datetime.date(2015, 8, 21)]
我概括了我的答案,以便任何人都可以在一个月的任何Nth
工作日使用它并使用最少的默认库。 我的用途是查找当年的 DST(夏令时)日期(3 月的第 2 个星期日和 11 月的第 1 个星期日)。
# Libraries:
from datetime import datetime
# Function:
def get_nth_day_of_month(year, month, Nth, weekday):
# Process is to find out what weekday the 1st of the month is
# And then go straight to the desired date by calculating it
first_of_month_weekday = datetime(year, month, 1).weekday()
day_desired = 7 * (Nth-1) + (weekday - first_of_month_weekday)
if day_desired < 1 : day_desired += 7 #correction for some 1st-weekday situations
return datetime(year, month, day_desired)
# Config:
year = 2022
month = 3 #DST starts in March
weekday = 6 #sunday
Nth = 2 #2nd sunday
dst_start = get_nth_day_of_month(year, month, Nth, weekday)
就我而言,这会产生今年夏令时的开始:
In [2]: dst_start
Out [2]: datetime.datetime(2022, 3, 13, 0, 0)
然后在 2022 年夏令时结束时:
month = 11
Nth = 1
dst_end = get_nth_day_of_month(year, month, Nth, weekday)
结果是:
In[4]: dst_end
Out[4]: datetime.datetime(2022, 11, 5, 0, 0)
因此,在 2022 年,DST 从 2022-03-13 运行到 2022-11-05。
标准:天数从星期一 = 0 到星期日 = 6
没有外部库的纯 python。
返回预期的月份日期。
注意:基于@autonopy 的回答,但有效。
from datetime import datetime
def get_nth_day_of_month(year, month, Nth, weekday):
first_of_month_weekday = datetime(year, month, 1).weekday()
# Find weekday offset from beginning of month
day_offset = (weekday - first_of_month_weekday) + 1
if day_offset < 1:
day_offset += 7 # correction for some 1st-weekday situations
# Add N weeks
return 7 * (Nth - 1) + day_offset
测试:
>>> # first Monday of Nov 2021
>>> get_nth_day_of_month(2021, 11, 1, 0)
1
>>> # first Monday of January 2022
>>> get_nth_day_of_month(2022, 1, 1, 0)
3
>>> # first Monday of May 2022
>>> get_nth_day_of_month(2022, 5, 1, 0)
2
>>> # Mother's day 2022
>>> get_nth_day_of_month(2022, 5, 2, 0)
9
我概括了@pourhaus 的答案以找到任何一个月的第 n 天:
def nth_day_of_month(month, year, day_of_week, n):
first_possible_day = {1: 1, 2: 8, 3: 15, 4: 22, 5: 29}[n]
d = datetime.date(year, month, first_possible_day)
w = d.weekday()
if w != day_of_week:
d = d.replace(day=(first_possible_day + (day_of_week - w) % 7))
return d
假设您使用熊猫:
def exp_friday(df):
mask = np.where((df.index.day > 14) &
(df.index.day < 22) &
(df.index.dayofweek == 4), True, False)
return df[mask]
这是一个通用函数,以列表形式为您提供特定周的所有日期。
def frecuencia_daymng(self, start_day, year, month, dayofweek):
"""dayofweek starts on MONDAY in 0 index"""
c = calendar.Calendar(firstweekday=start_day)
monthcal = c.monthdatescalendar(year, month)
ldates = []
for tdate in monthcal:
if tdate[dayofweek].month == month:
ldates.append(tdate[dayofweek])
return ldates
假设您想要 2020 年的所有星期一 10。
frecuencia_daymng(calendar.MONDAY, 2020, 10, 0)
这将为您提供输出。
[datetime.date(2020, 10, 5),
datetime.date(2020, 10, 12),
datetime.date(2020, 10, 19),
datetime.date(2020, 10, 26)]
所以现在你有这个月的第一个,第二个......等星期一。
我的建议是从每月的第一天开始,然后找到最近的星期五。
4 表示为来自 datetime.weekday() 方法的 Friday。
因此,我们然后从 4(Friday) 中减去该月第一天的工作日 如果结果为负,则找到的最接近的星期五是上个月,因此我们添加 7 天,否则我们已经有了第一个星期五。
然后结果就像再添加 14 天以获得第三个星期五一样简单,然后将代表第三个星期五的 timedelta 添加到该月的第一天。
from datetime import datetime, timedelta
def get_third_friday(year, month):
first_day_of_month = datetime(year, month, 1)
closest_friday = 4 - first_day_of_month.weekday()
if closest_friday < 0:
first_friday = closest_friday + 7
else:
first_friday = closest_friday
third_friday = first_friday + 14
return first_day_of_month + timedelta(third_friday)
这是一个已经有人想出来的解决方案: relativedelta模块是Python dateutil package ( pip install python-dateutil
) 的扩展。
import datetime
from dateutil import relativedelta
def third_fridays(n):
first_of_this_month = datetime.date.today().replace(day=1)
return (
first_of_this_month
+ relativedelta.relativedelta(weekday=relativedelta.FR(3), months=i)
for i in range(n)
)
这里的关键部分当然是weekday=relativedelta.FR(3)
,它准确说明了需要什么:该月的第三个星期五。 这是weekday
参数文档的相关部分,
工作日:
relativedelta 模块中可用的工作日实例之一(MO、TU 等)。 这些实例可能会收到一个参数 N,指定第 N 个工作日,它可以是正数或负数(如 MO(+1) 或 MO(-2))。
(对于 Python 的新手, return (...)
是一个生成器表达式,您可以将其视为要迭代的内容,例如, for friday in third_fridays(18): print(friday)
)
from dateutil.relativedelta import *
from datetime import *
def find_mth_friday(your_date,m):
mth_friday = your_date + relativedelta(day=1, weekday=FR(m)) #sets day=1 in your_date and adds m fridays to it.
mth_friday_timestamp = int(mth_friday.strftime("%s")) #converting datetime to unix timestamp
return mth_friday_timestamp
def get_third_fris(n):
output_timestamps = []
today = datetime.now() #gets current system date
for i in range(1,n+1): #value of i varies from 1 to 6 if n=6
next_month = today + relativedelta(months=+i) #adds i months to current system date
third_friday = find_mth_friday(next_month,3) #finds third friday of the month using 'find_mth_friday()', the function we defined
output_timestamps.append(third_friday)
return output_timestamps
print(get_third_fris(6)) #let's try invoking our function with n=6 dates
这就是你想要的吧?
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.