【问题标题】:Calculate year week number subtracting week number in Python计算年周数减去Python中的周数
【发布时间】:2018-04-13 03:33:56
【问题描述】:

我正在尝试查找自定义日期格式,例如 YYYYW。减去周数后为 201620。

到目前为止,我已经能够使用以下代码将像 YYYYW 这样的日期字符串转换为日期;

from datetime import datetime

myDate = "201642"
year = myDate[:4]
week = myDate[-2:]
day = '1'
myDate = year + " " + week + " " + day
print(myDate)
date = datetime.strptime(myDate, "%Y %W %w")
print(date)

但我无法找到一种可以减去例如的方法。从 201642 开始 43 周,得到类似 201552 的结果。

编辑 1:使用 cmets 的建议,这是解决方案。

从日期时间导入日期时间 从日期时间导入时间增量

myDate = "201642"
year = myDate[:4]
week = myDate[-2:]
day = '1'
myDate = year + " " + week + " " + day
print(myDate)
date = datetime.strptime(myDate, "%Y %W %w")
print(date)
new_date = date - timedelta(weeks=42)
str_new_date = datetime.strftime(new_date, '%Y%W')
print(str_new_date)

【问题讨论】:

  • 提示:一年有 52 周。只需使用数学。
  • 我确实考虑过这一点,但不确定它是否适用于闰年,因为它有 52.2 周
  • 您的代码是否必须处理小数周?您输入的整数年和周似乎暗示没有。
  • 好点,它还不是分数
  • 你有一个datetime 对象。从同一模块导入 timedelta 类型。然后你可以做date - timedelta(weeks=43),然后用strftime转换回你的字符串格式,你就完成了。 (尽管您可能想要使用 date 对象而不是 datetime。)

标签: python python-3.x python-2.7


【解决方案1】:

除了自己做数学,这里尝试使用日期时间。使用 ISO 周数做所有事情(使用来自this answer 的方法):

>>> import datetime
>>> date = '201642'
>>> weeks = 43
>>> year = date[:4]
>>> week = date[4:]

>>> start = iso_to_gregorian(int(year), int(week), 1)
>>> start
datetime.date(2016, 10, 17)
>>> start.isocalendar()
(2016, 42, 1)
>>> offset_weeks = datetime.timedelta(weeks=43)
>>> end = start - offset_weeks
>>> end
datetime.date(2015, 12, 21)
>>> end.isocalendar()
(2015, 52, 1)
>>> '{}{}'.format(*end.isocalendar())
'201552'

@Hildy 回答的修改版本如下:

In [29]: start = datetime.datetime.strptime(date + '0', '%Y%W%w')

In [30]: start
Out[30]: datetime.datetime(2016, 10, 23, 0, 0)

In [31]: start.strftime('%Y%W')
Out[31]: '201642'

In [32]: end = start - datetime.timedelta(weeks=43)

In [33]: end
Out[33]: datetime.datetime(2015, 12, 27, 0, 0)

In [34]: end.strftime('%Y%W')
Out[34]: '201551'

【讨论】:

  • 我应该选择谁的答案,你们都给出了相同的建议。请原谅我只是习惯了这样的礼仪。
  • 选择@Hildy 的回答。它更短。也许将两者结合在您的实际代码中。
【解决方案2】:

您实际上并没有在示例代码中正确解析日期,但既然您说您的实际代码可以,我们就忽略它。

所以,你有一个datetime 对象。你想从中减去 43 周。你所要做的就是……就是这样,使用timedelta

>>> dt = datetime.datetime(2016, 10, 21)
>>> dt - datetime.timedelta(weeks=43)
datetime.datetime(2015, 12, 25, 0, 0)

结果是同一时间,一周中的同一天,提前 43 周。


但值得注意的是,对于当地时间而言,由于跨越夏令时边界,“同一时间”可能会延迟一个小时。当您使用午夜时,关闭一个小时可能会特别令人困惑。所以这种工作通常最好使用date 对象而不是datetime 对象:

>>> dt = datetime.datetime(2016, 10, 21)
>>> dt.date()
datetime.date(2016, 10, 21)
>>> dt.date() - datetime.timedelta(weeks=43)
datetime.date(2015, 12, 25)

无论哪种方式,如果您想将其转回 YYYYWW 字符串,datetimedate 都有 strftime 方法:

>>> d2 = dt - datetime.timedelta(weeks=43)
>>> d2.strftime('%Y%W')
'201551'

【讨论】:

    【解决方案3】:

    这可以通过 dateutil 库中的相对增量来完成;应该注意的是,该库是 Python 2x 中标准库的一部分,但不是 3x...您必须安装它。

    接下来你需要知道的是,根据 Python docs,“当与 strptime() 方法一起使用时,%U%W 仅在星期几和指定年份。”

    试试这个:

    from dateutil.relativedelta import relativedelta
    from datetime import datetime
    
    #I've added the day number here, as described in the docs
    myDate = "2016042"
    # with '%w' added, strptime() will work
    date = datetime.strptime(myDate, "%Y%w%W")
    # now use relativedelta() to do the date math
    date = date - relativedelta(weeks=2)
    # finally, use strftime() to return the date back to the format you like
    myDate = date.strftime("%Y%W")
    
    print(string_date)
    

    我在 ETL 操作中使用它来计算诸如财政期间之类的东西,并且效果很好。正如其他人在这里所指出的,timedelta() 可以以类似的方式使用。

    【讨论】:

      猜你喜欢
      • 2021-09-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-10-26
      • 2013-02-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多