|
| 1 | +from datetime import datetime |
| 2 | + |
| 3 | +import pytest |
| 4 | + |
| 5 | +from pandas._libs import tslib |
| 6 | + |
| 7 | +from pandas import Timestamp |
| 8 | + |
| 9 | + |
| 10 | +@pytest.mark.parametrize( |
| 11 | + "date_str, exp", |
| 12 | + [ |
| 13 | + ("2011-01-02", datetime(2011, 1, 2)), |
| 14 | + ("2011-1-2", datetime(2011, 1, 2)), |
| 15 | + ("2011-01", datetime(2011, 1, 1)), |
| 16 | + ("2011-1", datetime(2011, 1, 1)), |
| 17 | + ("2011 01 02", datetime(2011, 1, 2)), |
| 18 | + ("2011.01.02", datetime(2011, 1, 2)), |
| 19 | + ("2011/01/02", datetime(2011, 1, 2)), |
| 20 | + ("2011\\01\\02", datetime(2011, 1, 2)), |
| 21 | + ("2013-01-01 05:30:00", datetime(2013, 1, 1, 5, 30)), |
| 22 | + ("2013-1-1 5:30:00", datetime(2013, 1, 1, 5, 30)), |
| 23 | + ("2013-1-1 5:30:00+01:00", Timestamp(2013, 1, 1, 5, 30, tz="UTC+01:00")), |
| 24 | + ], |
| 25 | +) |
| 26 | +def test_parsers_iso8601(date_str, exp): |
| 27 | + # see gh-12060 |
| 28 | + # |
| 29 | + # Test only the ISO parser - flexibility to |
| 30 | + # different separators and leading zero's. |
| 31 | + actual = tslib._test_parse_iso8601(date_str) |
| 32 | + assert actual == exp |
| 33 | + |
| 34 | + |
| 35 | +@pytest.mark.parametrize( |
| 36 | + "date_str", |
| 37 | + [ |
| 38 | + "2011-01/02", |
| 39 | + "2011=11=11", |
| 40 | + "201401", |
| 41 | + "201111", |
| 42 | + "200101", |
| 43 | + # Mixed separated and unseparated. |
| 44 | + "2005-0101", |
| 45 | + "200501-01", |
| 46 | + "20010101 12:3456", |
| 47 | + "20010101 1234:56", |
| 48 | + # HHMMSS must have two digits in |
| 49 | + # each component if unseparated. |
| 50 | + "20010101 1", |
| 51 | + "20010101 123", |
| 52 | + "20010101 12345", |
| 53 | + "20010101 12345Z", |
| 54 | + ], |
| 55 | +) |
| 56 | +def test_parsers_iso8601_invalid(date_str): |
| 57 | + msg = f'Error parsing datetime string "{date_str}"' |
| 58 | + |
| 59 | + with pytest.raises(ValueError, match=msg): |
| 60 | + tslib._test_parse_iso8601(date_str) |
| 61 | + |
| 62 | + |
| 63 | +def test_parsers_iso8601_invalid_offset_invalid(): |
| 64 | + date_str = "2001-01-01 12-34-56" |
| 65 | + msg = f'Timezone hours offset out of range in datetime string "{date_str}"' |
| 66 | + |
| 67 | + with pytest.raises(ValueError, match=msg): |
| 68 | + tslib._test_parse_iso8601(date_str) |
| 69 | + |
| 70 | + |
| 71 | +def test_parsers_iso8601_leading_space(): |
| 72 | + # GH#25895 make sure isoparser doesn't overflow with long input |
| 73 | + date_str, expected = ("2013-1-1 5:30:00", datetime(2013, 1, 1, 5, 30)) |
| 74 | + actual = tslib._test_parse_iso8601(" " * 200 + date_str) |
| 75 | + assert actual == expected |
| 76 | + |
| 77 | +@pytest.mark.parametrize( |
| 78 | + "date_str, timespec, exp", |
| 79 | + [ |
| 80 | + ("2023-01-01 00:00:00", "auto", "2023-01-01T00:00:00"), |
| 81 | + ("2023-01-01 00:00:00", "seconds", "2023-01-01T00:00:00"), |
| 82 | + ("2023-01-01 00:00:00", "milliseconds", "2023-01-01T00:00:00.000"), |
| 83 | + ("2023-01-01 00:00:00", "microseconds", "2023-01-01T00:00:00.000000"), |
| 84 | + ("2023-01-01 00:00:00", "nanoseconds", "2023-01-01T00:00:00.000000000"), |
| 85 | + ("2023-01-01 00:00:00.001", "auto", "2023-01-01T00:00:00.001000"), |
| 86 | + ("2023-01-01 00:00:00.001", "seconds", "2023-01-01T00:00:00"), |
| 87 | + ("2023-01-01 00:00:00.001", "milliseconds", "2023-01-01T00:00:00.001"), |
| 88 | + ("2023-01-01 00:00:00.001", "microseconds", "2023-01-01T00:00:00.001000"), |
| 89 | + ("2023-01-01 00:00:00.001", "nanoseconds", "2023-01-01T00:00:00.001000000"), |
| 90 | + ("2023-01-01 00:00:00.000001", "auto", "2023-01-01T00:00:00.000001"), |
| 91 | + ("2023-01-01 00:00:00.000001", "seconds", "2023-01-01T00:00:00"), |
| 92 | + ("2023-01-01 00:00:00.000001", "milliseconds", "2023-01-01T00:00:00.000"), |
| 93 | + ("2023-01-01 00:00:00.000001", "microseconds", "2023-01-01T00:00:00.000001"), |
| 94 | + ("2023-01-01 00:00:00.000001", "nanoseconds", "2023-01-01T00:00:00.000001000"), |
| 95 | + ("2023-01-01 00:00:00.000000001", "auto", "2023-01-01T00:00:00.000000001"), |
| 96 | + ("2023-01-01 00:00:00.000000001", "seconds", "2023-01-01T00:00:00"), |
| 97 | + ("2023-01-01 00:00:00.000000001", "milliseconds", "2023-01-01T00:00:00.000"), |
| 98 | + ("2023-01-01 00:00:00.000000001", "microseconds", "2023-01-01T00:00:00.000000"), |
| 99 | + ("2023-01-01 00:00:00.000000001", "nanoseconds", "2023-01-01T00:00:00.000000001"), |
| 100 | + ("2023-01-01 00:00:00.000001001", "auto", "2023-01-01T00:00:00.000001001"), |
| 101 | + ("2023-01-01 00:00:00.000001001", "seconds", "2023-01-01T00:00:00"), |
| 102 | + ("2023-01-01 00:00:00.000001001", "milliseconds", "2023-01-01T00:00:00.000"), |
| 103 | + ("2023-01-01 00:00:00.000001001", "microseconds", "2023-01-01T00:00:00.000001"), |
| 104 | + ("2023-01-01 00:00:00.000001001", "nanoseconds", "2023-01-01T00:00:00.000001001"), |
| 105 | + ] |
| 106 | +) |
| 107 | +def test_iso8601_formatter(date_str: str, timespec: str, exp: str): |
| 108 | + # GH#53020 |
| 109 | + ts = Timestamp(date_str) |
| 110 | + assert ts.isoformat(timespec=timespec) == exp |
0 commit comments