【问题标题】:Getting the date of the last day of this [week/month/quarter/year]获取此 [周/月/季度/年] 的最后一天的日期
【发布时间】:2015-08-13 19:30:17
【问题描述】:

有没有办法用datetimepandas 或其他日期&时间工具?

【问题讨论】:

  • 是的。获取今天的datetime 对象并将相关字段设置为最大值
  • @unutbu,snap() 方法仍然可以用于一些基本检查:如果捕捉日期早于给定日期,则将给定日期向前移动给定间隔并再次捕捉,然后返回一天。
  • @TigerhawkT3:是的,这可行,但我认为使用 searchsorted 可能更容易。

标签: python python-3.x pandas


【解决方案1】:

仅使用datetime

>>> d = datetime.date.today()

一周的最后一天:

# This was wrong earlier.
>>> d + datetime.timedelta(days=5 - d.weekday())
datetime.date(2015, 8, 15)

一个月的最后一天:

>>> datetime.date(year=(d.year + int(d.month % 12 == 0)), month=(d.month + 1) % 12, day=1) - datetime.timedelta(days=1)
datetime.date(2015, 8, 31)

季度最后一天:

>>> datetime.date(year=d.year, month=((d.month % 3) + 1) * 3 + 1, day=1) - datetime.timedelta(days=1)
datetime.date(2015, 9, 30)

一年的最后一天:

>>> datetime.date(year=d.year, month=12, day=31)
datetime.date(2015, 12, 31)

编辑:这一切都很丑陋,使用更高级别的第三方库可能是最好的,除非有令人信服的理由不这样做(而且似乎没有在这里)。

【讨论】:

  • 不错!也许您想缩短代码并使用from datetime import date, timedelta 稍微提高可读性并稍后删除datetime 命名空间。
  • 小错误:weekday0..6 范围内。因此,您可能会在第一个示例中返回昨天。
  • 谢谢。固定的。幸运的是,它今天有效。虽然周末是模棱两可的。我假设是周六的美国大会。
【解决方案2】:

您可以将pandas.DateOffset 添加到DateTimeIndexTimestampdatetime.datedatetime.datetime

dates = pd.date_range('2015-8-13', periods=4, freq='3D')
# DatetimeIndex(['2015-08-13', '2015-08-16', '2015-08-19', '2015-08-22'],
# dtype='datetime64[ns]', freq='3D', tz=None)

捕捉到一周的最后一天(例如,星期日):

In [232]: dates+offsets.Week(weekday=6)
Out[232]: DatetimeIndex(['2015-08-16', '2015-08-23', '2015-08-23', '2015-08-23'], dtype='datetime64[ns]', freq=None, tz=None)

捕捉到该月的最后一天:

In [207]: dates+offsets.MonthEnd()
Out[207]: DatetimeIndex(['2015-08-31', '2015-08-31', '2015-08-31', '2015-08-31'], dtype='datetime64[ns]', freq=None, tz=None)

捕捉到本季度的最后一天:

In [212]: dates+offsets.QuarterEnd()
Out[215]: DatetimeIndex(['2015-09-30', '2015-09-30', '2015-09-30', '2015-09-30'], dtype='datetime64[ns]', freq=None, tz=None)

捕捉到一年中的最后一天:

In [219]: dates+offsets.YearEnd()
Out[222]: DatetimeIndex(['2015-12-31', '2015-12-31', '2015-12-31', '2015-12-31'], dtype='datetime64[ns]', freq=None, tz=None)

请注意,添加偏移量总是会提前日期。例如,2015-08-16 是星期天,添加 offsets.Week(weekday=6) 会将其提前 2015-08-23:

In [233]: pd.Timestamp('2015-8-16')+offsets.Week(weekday=6)
Out[233]: Timestamp('2015-08-23 00:00:00')

为防止这种情况发生,您可以从 dates 中减去一天:

In [234]: dates - offsets.Day() + offsets.Week(weekday=6)
Out[237]: DatetimeIndex(['2015-08-16', '2015-08-16', '2015-08-23', '2015-08-23'], dtype='datetime64[ns]', freq=None, tz=None)

【讨论】:

  • 链接文档显示“最近”。它只会向前冲吗?
  • @TigerhawkT3:感谢您的更正。更新后的答案确实“向前冲”。
【解决方案3】:
import datetime
from dateutil.relativedelta import relativedelta, SU

def last_day_of_week(year, week_num):
    # assuming sunday is the last day of week
    # weeks= is an offset, hence the minus one
    return datetime.date(year, 1, 1) + relativedelta(weekday=SU(1), weeks=week_num - 1)

def last_day_of_month(year, month):
    return datetime.date(year, month, 1) + relativedelta(months=1, days=-1)

def last_day_of_year(year):
    return datetime.date(year, 1, 1) + relativedelta(years=1, days=-1)

【讨论】:

  • 我猜last_day_of_year(N) == last_day_of_month(N, 12) 但你永远不知道,也许有一天几年会有 13 个月......
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-01-09
  • 1970-01-01
  • 2013-01-05
相关资源
最近更新 更多