From 92929d826598c69a14530455b9561107b9bf2847 Mon Sep 17 00:00:00 2001 From: Jason Yalim Date: Sun, 26 Oct 2025 16:55:36 -0700 Subject: [PATCH 1/9] provide support for %F token in strptime; add test for it and %T --- Lib/_strptime.py | 2 ++ Lib/test/test_strptime.py | 26 ++++++++++++++++++++++++++ 2 files changed, 28 insertions(+) diff --git a/Lib/_strptime.py b/Lib/_strptime.py index d011ddf8b181c3..17221b925e177c 100644 --- a/Lib/_strptime.py +++ b/Lib/_strptime.py @@ -418,6 +418,8 @@ def __init__(self, locale_time=None): mapping['W'] = mapping['U'].replace('U', 'W') base.__init__(mapping) + # %F %T %R %r %X %x %c (some shorthands and locales) + base.__setitem__('F', self.pattern('%Y-%m-%d')) base.__setitem__('T', self.pattern('%H:%M:%S')) base.__setitem__('R', self.pattern('%H:%M')) base.__setitem__('r', self.pattern(self.locale_time.LC_time_ampm)) diff --git a/Lib/test/test_strptime.py b/Lib/test/test_strptime.py index 40e114aada67eb..3c97f94ab4b7cd 100644 --- a/Lib/test/test_strptime.py +++ b/Lib/test/test_strptime.py @@ -649,6 +649,32 @@ def test_mar1_comes_after_feb29_even_when_omitting_the_year(self): time.strptime("Feb 29", "%b %d"), time.strptime("Mar 1", "%b %d")) + def test_shorthand_year_month_day(self): + # Test that token '%F' is equivalent to '%Y-%m-%d' + formats = dict(short="%F",long="%Y-%m-%d") + test_date = "2025-10-26" + shorthand = time.strptime(test_date,formats["short"]) + long_hand = time.strptime(test_date,formats["long"]) + self.assertEqual(shorthand,long_hand) + # ensure datetime functionality + import datetime + shorthand = datetime.datetime.strptime(test_date,formats["short"]) + long_hand = datetime.datetime.strptime(test_date,formats["long"]) + assert shorthand == long_hand + + def test_shorthand_hour_minute_second(self): + # Test that token '%T' is equivalent to '%H:%M:%S' + formats = dict(short="%T",long="%H:%M:%S") + test_time = "15:00:00" + shorthand = time.strptime(test_time,formats["short"]) + long_hand = time.strptime(test_time,formats["long"]) + self.assertEqual(shorthand,long_hand) + # ensure datetime functionality + import datetime + shorthand = datetime.datetime.strptime(test_time,formats["short"]) + long_hand = datetime.datetime.strptime(test_time,formats["long"]) + assert shorthand == long_hand + class Strptime12AMPMTests(unittest.TestCase): """Test a _strptime regression in '%I %p' at 12 noon (12 PM)""" From b1bf9b4e9b9424e5500bc6e9340559b75bc14aa4 Mon Sep 17 00:00:00 2001 From: "blurb-it[bot]" <43283697+blurb-it[bot]@users.noreply.github.com> Date: Mon, 27 Oct 2025 00:13:05 +0000 Subject: [PATCH 2/9] =?UTF-8?q?=F0=9F=93=9C=F0=9F=A4=96=20Added=20by=20blu?= =?UTF-8?q?rb=5Fit.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../next/Library/2025-10-27-00-13-04.gh-issue-140644.WkozE0.rst | 1 + 1 file changed, 1 insertion(+) create mode 100644 Misc/NEWS.d/next/Library/2025-10-27-00-13-04.gh-issue-140644.WkozE0.rst diff --git a/Misc/NEWS.d/next/Library/2025-10-27-00-13-04.gh-issue-140644.WkozE0.rst b/Misc/NEWS.d/next/Library/2025-10-27-00-13-04.gh-issue-140644.WkozE0.rst new file mode 100644 index 00000000000000..b1bd5d9b28f3d9 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2025-10-27-00-13-04.gh-issue-140644.WkozE0.rst @@ -0,0 +1 @@ +Add `'%F'` support to `datetime.datetime.strptime`, a C99+ `time.h` format token. From d84fd544ddcf11853882fd583a1c2d4777e52eaa Mon Sep 17 00:00:00 2001 From: "Jason Yalim, PhD" <4813268+jyalim@users.noreply.github.com> Date: Tue, 28 Oct 2025 14:10:06 -0700 Subject: [PATCH 3/9] rm comment as recommended Co-authored-by: Stan Ulbrych <89152624+StanFromIreland@users.noreply.github.com> --- Lib/_strptime.py | 1 - 1 file changed, 1 deletion(-) diff --git a/Lib/_strptime.py b/Lib/_strptime.py index 17221b925e177c..8b62ea734b7d11 100644 --- a/Lib/_strptime.py +++ b/Lib/_strptime.py @@ -418,7 +418,6 @@ def __init__(self, locale_time=None): mapping['W'] = mapping['U'].replace('U', 'W') base.__init__(mapping) - # %F %T %R %r %X %x %c (some shorthands and locales) base.__setitem__('F', self.pattern('%Y-%m-%d')) base.__setitem__('T', self.pattern('%H:%M:%S')) base.__setitem__('R', self.pattern('%H:%M')) From cb8d7d3d6d4ff1f9f3629d769474b1349173ba35 Mon Sep 17 00:00:00 2001 From: "Jason Yalim, PhD" <4813268+jyalim@users.noreply.github.com> Date: Tue, 28 Oct 2025 14:10:55 -0700 Subject: [PATCH 4/9] Update Misc/NEWS.d/next/Library/2025-10-27-00-13-04.gh-issue-140644.WkozE0.rst Co-authored-by: Stan Ulbrych <89152624+StanFromIreland@users.noreply.github.com> --- .../next/Library/2025-10-27-00-13-04.gh-issue-140644.WkozE0.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Misc/NEWS.d/next/Library/2025-10-27-00-13-04.gh-issue-140644.WkozE0.rst b/Misc/NEWS.d/next/Library/2025-10-27-00-13-04.gh-issue-140644.WkozE0.rst index b1bd5d9b28f3d9..0cf1830e82bdae 100644 --- a/Misc/NEWS.d/next/Library/2025-10-27-00-13-04.gh-issue-140644.WkozE0.rst +++ b/Misc/NEWS.d/next/Library/2025-10-27-00-13-04.gh-issue-140644.WkozE0.rst @@ -1 +1 @@ -Add `'%F'` support to `datetime.datetime.strptime`, a C99+ `time.h` format token. +Add `'%F'` support to :meth:`~datetime.datetime.strptime`, a C99+ ``time.h`` format code. From 634eceaf40bd681478d8a8ac8a0c5d1328c04b8f Mon Sep 17 00:00:00 2001 From: "Jason Yalim, PhD" <4813268+jyalim@users.noreply.github.com> Date: Tue, 28 Oct 2025 14:13:59 -0700 Subject: [PATCH 5/9] Rename NEWS blurbit to match new github issue name --- ....WkozE0.rst => 2025-10-27-00-13-04.gh-issue-140715.WkozE0.rst} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename Misc/NEWS.d/next/Library/{2025-10-27-00-13-04.gh-issue-140644.WkozE0.rst => 2025-10-27-00-13-04.gh-issue-140715.WkozE0.rst} (100%) diff --git a/Misc/NEWS.d/next/Library/2025-10-27-00-13-04.gh-issue-140644.WkozE0.rst b/Misc/NEWS.d/next/Library/2025-10-27-00-13-04.gh-issue-140715.WkozE0.rst similarity index 100% rename from Misc/NEWS.d/next/Library/2025-10-27-00-13-04.gh-issue-140644.WkozE0.rst rename to Misc/NEWS.d/next/Library/2025-10-27-00-13-04.gh-issue-140715.WkozE0.rst From 2e940376645defcc50bb65e226dd47f0aa4d310e Mon Sep 17 00:00:00 2001 From: "Jason Yalim, PhD" <4813268+jyalim@users.noreply.github.com> Date: Tue, 28 Oct 2025 14:19:02 -0700 Subject: [PATCH 6/9] Update test_strptime.py to use unittest methods, as requested --- Lib/test/test_strptime.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Lib/test/test_strptime.py b/Lib/test/test_strptime.py index 3c97f94ab4b7cd..2182ba755b3f50 100644 --- a/Lib/test/test_strptime.py +++ b/Lib/test/test_strptime.py @@ -660,7 +660,7 @@ def test_shorthand_year_month_day(self): import datetime shorthand = datetime.datetime.strptime(test_date,formats["short"]) long_hand = datetime.datetime.strptime(test_date,formats["long"]) - assert shorthand == long_hand + self.assertEqual(shorthand,long_hand) def test_shorthand_hour_minute_second(self): # Test that token '%T' is equivalent to '%H:%M:%S' @@ -673,7 +673,7 @@ def test_shorthand_hour_minute_second(self): import datetime shorthand = datetime.datetime.strptime(test_time,formats["short"]) long_hand = datetime.datetime.strptime(test_time,formats["long"]) - assert shorthand == long_hand + self.assertEqual(shorthand,long_hand) class Strptime12AMPMTests(unittest.TestCase): """Test a _strptime regression in '%I %p' at 12 noon (12 PM)""" From c23b7318cf58028ed16056a308d72895074d0128 Mon Sep 17 00:00:00 2001 From: "Jason Yalim, PhD" <4813268+jyalim@users.noreply.github.com> Date: Tue, 28 Oct 2025 14:36:01 -0700 Subject: [PATCH 7/9] simplify news per recommendation Co-authored-by: Stan Ulbrych <89152624+StanFromIreland@users.noreply.github.com> --- .../next/Library/2025-10-27-00-13-04.gh-issue-140715.WkozE0.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Misc/NEWS.d/next/Library/2025-10-27-00-13-04.gh-issue-140715.WkozE0.rst b/Misc/NEWS.d/next/Library/2025-10-27-00-13-04.gh-issue-140715.WkozE0.rst index 0cf1830e82bdae..19d281c7cc9c49 100644 --- a/Misc/NEWS.d/next/Library/2025-10-27-00-13-04.gh-issue-140715.WkozE0.rst +++ b/Misc/NEWS.d/next/Library/2025-10-27-00-13-04.gh-issue-140715.WkozE0.rst @@ -1 +1 @@ -Add `'%F'` support to :meth:`~datetime.datetime.strptime`, a C99+ ``time.h`` format code. +Add `'%F'` support to :meth:`~datetime.datetime.strptime`. From e77ff968e3a3e6bca3e90acde00a9a5c1f41bb85 Mon Sep 17 00:00:00 2001 From: "Jason Yalim, PhD" <4813268+jyalim@users.noreply.github.com> Date: Tue, 28 Oct 2025 14:37:13 -0700 Subject: [PATCH 8/9] Remove datetime tests from test_strptime.py (added to `datetimetester.py` instead) --- Lib/test/test_strptime.py | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/Lib/test/test_strptime.py b/Lib/test/test_strptime.py index 2182ba755b3f50..02617a58130335 100644 --- a/Lib/test/test_strptime.py +++ b/Lib/test/test_strptime.py @@ -656,11 +656,6 @@ def test_shorthand_year_month_day(self): shorthand = time.strptime(test_date,formats["short"]) long_hand = time.strptime(test_date,formats["long"]) self.assertEqual(shorthand,long_hand) - # ensure datetime functionality - import datetime - shorthand = datetime.datetime.strptime(test_date,formats["short"]) - long_hand = datetime.datetime.strptime(test_date,formats["long"]) - self.assertEqual(shorthand,long_hand) def test_shorthand_hour_minute_second(self): # Test that token '%T' is equivalent to '%H:%M:%S' @@ -669,11 +664,6 @@ def test_shorthand_hour_minute_second(self): shorthand = time.strptime(test_time,formats["short"]) long_hand = time.strptime(test_time,formats["long"]) self.assertEqual(shorthand,long_hand) - # ensure datetime functionality - import datetime - shorthand = datetime.datetime.strptime(test_time,formats["short"]) - long_hand = datetime.datetime.strptime(test_time,formats["long"]) - self.assertEqual(shorthand,long_hand) class Strptime12AMPMTests(unittest.TestCase): """Test a _strptime regression in '%I %p' at 12 noon (12 PM)""" From ffbc21513046d84d51b834feba12798498c321aa Mon Sep 17 00:00:00 2001 From: "Jason Yalim, PhD" <4813268+jyalim@users.noreply.github.com> Date: Tue, 28 Oct 2025 14:42:15 -0700 Subject: [PATCH 9/9] Tests moved to datetimetester.py --- Lib/test/datetimetester.py | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/Lib/test/datetimetester.py b/Lib/test/datetimetester.py index 7df27206206268..6abb704f08865f 100644 --- a/Lib/test/datetimetester.py +++ b/Lib/test/datetimetester.py @@ -1212,6 +1212,20 @@ def test_strptime_leap_year(self): date.strptime('20-03-14', '%y-%m-%d') date.strptime('02-29,2024', '%m-%d,%Y') + def test_strptime_C99_shorthand_year_month_day(self): + formats = dict(short="%F",long="%Y-%m-%d") + test_date = "2025-10-26" + shorthand = datetime.strptime(test_date,formats["short"]) + long_hand = datetime.strptime(test_date,formats["long"]) + self.assertEqual(shorthand,long_hand) + + def test_strptime_C99_shorthand_hour_minute_second(self): + formats = dict(short="%T",long="%H:%M:%S") + test_time = "15:00:00" + shorthand = datetime.strptime(test_time,formats["short"]) + long_hand = datetime.strptime(test_time,formats["long"]) + self.assertEqual(shorthand,long_hand) + class SubclassDate(date): sub_var = 1