diff --git a/Lib/_strptime.py b/Lib/_strptime.py index 3311ec888714696..4e9f6527b032dfa 100644 --- a/Lib/_strptime.py +++ b/Lib/_strptime.py @@ -788,6 +788,9 @@ def parse_int(s): datetime_result = datetime_date.fromordinal( (julian - 1) + datetime_date(year, 1, 1).toordinal()) + if year != datetime_result.year: + year_start = datetime_date(datetime_result.year, 1, 1) + julian = datetime_result.toordinal() - year_start.toordinal() + 1 year = datetime_result.year month = datetime_result.month day = datetime_result.day diff --git a/Lib/test/test_strptime.py b/Lib/test/test_strptime.py index d70837ea63f5474..ead80bd2adc8661 100644 --- a/Lib/test/test_strptime.py +++ b/Lib/test/test_strptime.py @@ -873,6 +873,18 @@ def check(value, format, *expected): check('2009 0 6', '%Y %W %w', 2009, 1, 3, 0, 0, 0, 5, 3) check('2009 1 7', '%G %V %u', 2009, 1, 4, 0, 0, 0, 6, 4) + def test_julian_day_next_year(self): + for value, format, expected in ( + ('2016 52 0', '%Y %W %w', (2017, 1, 1, 6, 1)), + ('2015 52 5', '%Y %U %w', (2016, 1, 1, 4, 1)), + ('2019 366', '%Y %j', (2020, 1, 1, 2, 1)), + ): + with self.subTest(value=value, format=format): + result = time.strptime(value, format) + self.assertEqual( + (result.tm_year, result.tm_mon, result.tm_mday, + result.tm_wday, result.tm_yday), expected) + class CacheTests(unittest.TestCase): """Test that caching works properly.""" diff --git a/Misc/NEWS.d/next/Library/2026-09-30-01-09-20.gh-issue-73267.2gI9pf.rst b/Misc/NEWS.d/next/Library/2026-09-30-01-09-20.gh-issue-73267.2gI9pf.rst new file mode 100644 index 000000000000000..6596df2c4bdf3cb --- /dev/null +++ b/Misc/NEWS.d/next/Library/2026-09-30-01-09-20.gh-issue-73267.2gI9pf.rst @@ -0,0 +1,2 @@ +Fix :func:`time.strptime` returning an inconsistent day of year when a week +number or ordinal day resolves to a date in the following year.