练习

为了理解一个模块是如何工作的,通过一些例子通常是很有用的;在这一页中,有几个不同难度的练习可以用来学习如何使用 dateutil .

如果您有兴趣帮助改进 dateutil ,建议您尝试在没有资源的情况下完成这些练习 除了dateutil的文档 . 如果您发现文档不够清晰,无法完成这些练习,请在 dateutil issue tracker 让开发人员知道文档的哪些部分需要改进。

马丁路德金日

Martin Luther King, Jr Day 每年一月的第三个星期一是美国的假日吗?

如何生成一个 recurrence rule 从1986年第一次纪念马丁路德金日开始,就产生了这个节日?

测试脚本

要解决此练习,请将此脚本复制粘贴到文档中,更改 --- YOUR CODE --- 注释块。

# ------- YOUR CODE -------------#
from dateutil import rrule

MLK_DAY = <<YOUR CODE HERE>>

# -------------------------------#

from datetime import datetime
MLK_TEST_CASES = [
    ((datetime(1970, 1, 1), datetime(1980, 1, 1)),
     []),
    ((datetime(1980, 1, 1), datetime(1989, 1, 1)),
     [datetime(1986, 1, 20),
      datetime(1987, 1, 19),
      datetime(1988, 1, 18)]),
    ((datetime(2017, 2, 1), datetime(2022, 2, 1)),
     [datetime(2018, 1, 15, 0, 0),
      datetime(2019, 1, 21, 0, 0),
      datetime(2020, 1, 20, 0, 0),
      datetime(2021, 1, 18, 0, 0),
      datetime(2022, 1, 17, 0, 0)]
     ),
]

def test_mlk_day():
    for (between_args, expected) in MLK_TEST_CASES:
        assert MLK_DAY.between(*between_args) == expected

if __name__ == "__main__":
    test_mlk_day()
    print('Success!')

提出了解决这一问题的方法 here .

下周一会议

一个团队每周一上午10点有一个会议,需要一个功能来告诉他们,给定一个 datetime.datetime 对象,日期和时间是什么 next 星期一开会?使用 relativedelta .

测试脚本

要解决此练习,请将此脚本复制粘贴到文档中,更改 --- YOUR CODE --- 注释块。

# --------- YOUR CODE -------------- #
from dateutil import relativedelta

def next_monday(dt):
    <<YOUR CODE HERE>>

# ---------------------------------- #

from datetime import datetime
from dateutil import tz

NEXT_MONDAY_CASES = [
    (datetime(2018, 4, 11, 14, 30, 15, 123456),
     datetime(2018, 4, 16, 10, 0)),
    (datetime(2018, 4, 16, 10, 0),
     datetime(2018, 4, 16, 10, 0)),
    (datetime(2018, 4, 16, 10, 30),
     datetime(2018, 4, 23, 10, 0)),
    (datetime(2018, 4, 14, 9, 30, tzinfo=tz.gettz('America/New_York')),
     datetime(2018, 4, 16, 10, 0, tzinfo=tz.gettz('America/New_York'))),
]

def test_next_monday_1():
    for dt_in, dt_out in NEXT_MONDAY_CASES:
        assert next_monday(dt_in) == dt_out

if __name__ == "__main__":
    test_next_monday_1()
    print('Success!')

解析本地tzname

三个字符的时区缩写是 not 其独特之处在于它们不显式映射到时区。可以找到正在使用的时区缩写列表 here . 这意味着解析一个日期时间字符串,比如 '2018-01-01 12:30:30 CST' 没有上下文就模棱两可。使用 dateutil.parserdateutil.tz ,可以提供一个上下文,以便将这些本地名称转换为适当的时区。

问题1

解析一个来自美国的日期字符串,你只会从美国返回一个时间字符串 datetime 附加了IANA样式的时区。

注意:为了实验的目的,你可以忽略美国亚利桑那州和印第安纳州不遵守夏令时的部分地区。

测试脚本

要解决此练习,请将此脚本复制粘贴到文档中,更改 --- YOUR CODE --- 注释块。

# --------- YOUR CODE -------------- #
from dateutil.parser import parse
from dateutil import tz

def parse_func_us_jp_ind():
    <<YOUR CODE HERE>>

# ---------------------------------- #

from dateutil import tz
from datetime import datetime


PARSE_TZ_TEST_DATETIMES = [
    datetime(2018, 1, 1, 12, 0),
    datetime(2018, 3, 20, 2, 0),
    datetime(2018, 5, 12, 3, 30),
    datetime(2014, 9, 1, 23)
]

PARSE_TZ_TEST_ZONES = [
    tz.gettz('America/New_York'),
    tz.gettz('America/Chicago'),
    tz.gettz('America/Denver'),
    tz.gettz('America/Los_Angeles'),
    tz.gettz('Asia/Kolkata'),
    tz.gettz('Asia/Tokyo'),
]

def test_parse():
    for tzi in PARSE_TZ_TEST_ZONES:
        for dt in PARSE_TZ_TEST_DATETIMES:
            dt_exp = dt.replace(tzinfo=tzi)
            dtstr = dt_exp.strftime('%Y-%m-%d %H:%M:%S %Z')

            dt_act = parse_func_us_jp_ind(dtstr)
            assert dt_act == dt_exp
            assert dt_act.tzinfo is dt_exp.tzinfo

if __name__ == "__main__":
    test_parse()
    print('Success!')

问题2

考虑到你会 only 从印度或爱尔兰传递日期,写一个正确解析所有的函数 毫不含糊 时区字符串,以识别本地化到正确的IANA区域的日期时间,并且 模棱两可的 时区字符串默认为印度。

测试脚本

要解决此练习,请将此脚本复制粘贴到文档中,更改 --- YOUR CODE --- 注释块。

# --------- YOUR CODE -------------- #
from dateutil.parser import parse
from dateutil import tz

def parse_func_ind_ire():
    <<YOUR CODE HERE>>

# ---------------------------------- #
ISRAEL = tz.gettz('Asia/Jerusalem')
INDIA = tz.gettz('Asia/Kolkata')
PARSE_IXT_TEST_CASE = [
    ('2018-02-03 12:00 IST+02:00', datetime(2018, 2, 3, 12, tzinfo=ISRAEL)),
    ('2018-06-14 12:00 IDT+03:00', datetime(2018, 6, 14, 12, tzinfo=ISRAEL)),
    ('2018-06-14 12:00 IST', datetime(2018, 6, 14, 12, tzinfo=INDIA)),
    ('2018-06-14 12:00 IST+05:30', datetime(2018, 6, 14, 12, tzinfo=INDIA)),
    ('2018-02-03 12:00 IST', datetime(2018, 2, 3, 12, tzinfo=INDIA)),
]


def test_parse_ixt():
    for dtstr, dt_exp in PARSE_IXT_TEST_CASE:
        dt_act = parse_func_ind_ire(dtstr)
        assert dt_act == dt_exp, (dt_act, dt_exp)
        assert dt_act.tzinfo is dt_exp.tzinfo, (dt_act, dt_exp)

if __name__ == "__main__":
    test_parse_ixt()
    print('Success!')