当前位置:  开发笔记 > 编程语言 > 正文

查找datetime.isocalendar()的反转的最佳方法是什么?

如何解决《查找datetime.isocalendar()的反转的最佳方法是什么?》经验,为你挑选了3个好方法。

Python datetime.isocalendar()方法返回(ISO_year, ISO_week_number, ISO_weekday)给定datetime对象的元组.是否有相应的反函数?如果没有,是否有一种简单的方法来计算一年,周数和星期几的日期?



1> Ben James..:

我最近不得不自己解决这个问题,并提出了这个解决方案:

import datetime

def iso_year_start(iso_year):
    "The gregorian calendar date of the first day of the given ISO year"
    fourth_jan = datetime.date(iso_year, 1, 4)
    delta = datetime.timedelta(fourth_jan.isoweekday()-1)
    return fourth_jan - delta 

def iso_to_gregorian(iso_year, iso_week, iso_day):
    "Gregorian calendar date for the given ISO year, week and day"
    year_start = iso_year_start(iso_year)
    return year_start + datetime.timedelta(days=iso_day-1, weeks=iso_week-1)

一些测试用例:

>>> iso = datetime.date(2005, 1, 1).isocalendar()
>>> iso
(2004, 53, 6)
>>> iso_to_gregorian(*iso)
datetime.date(2005, 1, 1)

>>> iso = datetime.date(2010, 1, 4).isocalendar()    
>>> iso
(2010, 1, 1)
>>> iso_to_gregorian(*iso)
datetime.date(2010, 1, 4)

>>> iso = datetime.date(2010, 1, 3).isocalendar()
>>> iso
(2009, 53, 7)
>>> iso_to_gregorian(*iso)
datetime.date(2010, 1, 3)


汤姆:从第1周的正式ISO定义(包含一年中第一个星期四的那一周)来看,1月4日是第1周可以开始的最新版本.

2> jwg..:
import datetime

def iso_to_gregorian(iso_year, iso_week, iso_day):
    "Gregorian calendar date for the given ISO year, week and day"
    fourth_jan = datetime.date(iso_year, 1, 4)
    _, fourth_jan_week, fourth_jan_day = fourth_jan.isocalendar()
    return fourth_jan + datetime.timedelta(days=iso_day-fourth_jan_day, weeks=iso_week-fourth_jan_week)

这是改编自@ BenJames的非常好的答案.你不必知道一年的第一天.您只需要知道一个日期的例子,该日期肯定在同一个ISO年份,以及该日期的ISO日历周和日期.

1月4日只是一个例子,因为正如本指出的那样,1月4日总是属于同一个ISO年和格里高利年,并且是一年中的第一天.

由于周数长度相同,因此您可以简单地减去所需日期的ISO与您在两种表格中知道的日期的ISO之间的天数和周数,并添加该天数和周数.(这些数字是正数还是负数并不重要,因此您可以选择其他一些"固定日期",例如12月28日.)

编辑

我纠正了这一点,因为正如@JoSo所指出的那样,格里高利年的第一天也属于ISO年份,是1月4日而不是1月5日.正如解释所说,选择哪个日期作为参考点并不重要,但选择Jan 4会使这个选择变得不那么"神奇".


@GeorgeSolymosi我使用假设Python测试库来搜索任何有效的`datetime`对象,这个对象的函数不是`isocalendar`的反转.它没有找到任何/请参阅https://github.com/jwg4/qual/blob/master/qual/tests/test_iso.py这当然不是保证 - 我有兴趣听到任何错误.如果您完成代码的逻辑,您可能会或可能不会确信它是正确的.

3> Martijn Piet..:

对于Python 3.6,你可以使用新的%G,%u%V指令.请参阅问题12006和更新的文档:

%G
ISO 8601年代表包含ISO周(%V)大部分年份的世纪.

%u
工作日的ISO 8601为十进制数,其中1为星期一.

%V
ISO 8601周作为十进制数,星期一作为一周的第一天.第01周是包含1月4日的一周.

给定一个包含年份,周数和工作日数字的字符串,可以很容易地将这些字符串解析为日期:

from datetime import datetime

datetime.strptime('2002 01 1', '%G %V %u').date()

或者作为整数输入的函数:

from datetime import datetime

def date_from_isoweek(iso_year, iso_weeknumber, iso_weekday):
    return datetime.strptime(
        '{:04d} {:02d} {:d}'.format(iso_year, iso_weeknumber, iso_weekday),
        '%G %V %u').date()

推荐阅读
大大炮
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有