|
1 | 1 | from __future__ import annotations |
2 | 2 |
|
| 3 | +from datetime import datetime |
| 4 | +from datetime import timedelta |
| 5 | +from datetime import timezone |
| 6 | +from zoneinfo import ZoneInfo |
| 7 | + |
| 8 | +import pytest |
| 9 | + |
| 10 | +from dateutil import tz |
| 11 | + |
3 | 12 | import pendulum |
4 | 13 |
|
5 | 14 | from tests.conftest import assert_datetime |
@@ -36,3 +45,54 @@ def test_astimezone(): |
36 | 45 | d = d.astimezone(pendulum.timezone("Europe/Paris")) |
37 | 46 | assert d.timezone_name == "Europe/Paris" |
38 | 47 | assert_datetime(d, now.year, now.month, now.day, now.hour + 1, now.minute) |
| 48 | + |
| 49 | + |
| 50 | +class CustomDateTime(pendulum.DateTime): |
| 51 | + pass |
| 52 | + |
| 53 | + |
| 54 | +@pytest.mark.parametrize("datetime_class", [pendulum.DateTime, CustomDateTime]) |
| 55 | +@pytest.mark.parametrize( |
| 56 | + "target", |
| 57 | + [ |
| 58 | + pytest.param(tz.gettz("Etc/GMT+6"), id="dateutil-fixed-zone"), |
| 59 | + pytest.param(tz.gettz("Europe/Paris"), id="dateutil-dst-zone"), |
| 60 | + pytest.param(tz.tzoffset("offset", 19800), id="dateutil-offset"), |
| 61 | + pytest.param(timezone(timedelta(hours=5, minutes=30)), id="builtin"), |
| 62 | + pytest.param(ZoneInfo("Europe/Paris"), id="zoneinfo"), |
| 63 | + pytest.param(pendulum.timezone("Europe/Paris"), id="pendulum"), |
| 64 | + pytest.param(None, id="local"), |
| 65 | + ], |
| 66 | +) |
| 67 | +@pytest.mark.parametrize( |
| 68 | + "source", |
| 69 | + [ |
| 70 | + datetime(2024, 1, 15, 18, 15, 34, 123456, tzinfo=timezone.utc), |
| 71 | + datetime(2024, 7, 15, 18, 15, 34, 123456, tzinfo=timezone.utc), |
| 72 | + datetime(2024, 10, 27, 0, 30, tzinfo=timezone.utc), |
| 73 | + datetime(2024, 10, 27, 1, 30, tzinfo=timezone.utc), |
| 74 | + datetime(2024, 10, 27, 2, 30, tzinfo=ZoneInfo("Europe/Paris"), fold=1), |
| 75 | + datetime(2024, 1, 15, 18, 15, 34, 123456), |
| 76 | + ], |
| 77 | +) |
| 78 | +def test_astimezone_matches_datetime(datetime_class, target, source): |
| 79 | + value = datetime_class( |
| 80 | + source.year, |
| 81 | + source.month, |
| 82 | + source.day, |
| 83 | + source.hour, |
| 84 | + source.minute, |
| 85 | + source.second, |
| 86 | + source.microsecond, |
| 87 | + tzinfo=source.tzinfo, |
| 88 | + fold=source.fold, |
| 89 | + ) |
| 90 | + |
| 91 | + expected = source.astimezone(target) |
| 92 | + actual = value.astimezone(target) |
| 93 | + |
| 94 | + assert type(actual) is datetime_class |
| 95 | + assert actual.tzinfo == expected.tzinfo |
| 96 | + assert actual.isoformat() == expected.isoformat() |
| 97 | + assert actual.timestamp() == expected.timestamp() |
| 98 | + assert actual.fold == expected.fold |
0 commit comments