Skip to content

FIX: Special handling for ambiguous date formats#349

Open
TroyDowling wants to merge 1 commit intolucc:mainfrom
TroyDowling:fix-no-year-deprecation-warning
Open

FIX: Special handling for ambiguous date formats#349
TroyDowling wants to merge 1 commit intolucc:mainfrom
TroyDowling:fix-no-year-deprecation-warning

Conversation

@TroyDowling
Copy link

@TroyDowling TroyDowling commented Jan 15, 2026

This small patch revises the string_to_date function in typing.py to more gracefully handle parsing dates without a year. The motivation being to address the DeprecationWarning issued by Python in recent versions (and to avoid a possible breakage in the upcoming Python 3.15).

This closes #335 on the bug board.

  • Interpolates the placeholder year 1900 for the two ambiguous formats.
  • Formatted with ruff.

Before

................./home/troy/projects/khard/khard/helpers/typing.py:76: DeprecationWarning: Parsing dates i
nvolving a day of month without a year specified is ambiguous
and fails to parse leap day. The default behavior will change in Python 3.15
to either always raise an exception or to use a different default year (TBD).
To avoid trouble, add a specific year to the input & format.
See https://github.com/python/cpython/issues/70647.
  return datetime.strptime(string, fmt)
.................../home/troy/projects/khard/khard/cli.py:208: PendingDeprecationWarning: FileType is depr
ecated. Simply open files after parsing arguments.
  type=argparse.FileType("w"),
..........................................................................................................
....................................................................................ss....................
.....................................................................x....................................
.............................................
----------------------------------------------------------------------
Ran 399 tests in 0.326s

OK (skipped=2, expected failures=1)

After

..................................../home/troy/projects/khard/khard/cli.py:208: PendingDeprecationWarning:
 FileType is deprecated. Simply open files after parsing arguments.
  type=argparse.FileType("w"),
..........................................................................................................
....................................................................................ss....................
.....................................................................x....................................
.............................................
----------------------------------------------------------------------
Ran 399 tests in 0.327s

OK (skipped=2, expected failures=1)

and

$ python -W error::DeprecationWarning -m unittest test.test_helpers_typing.StringToDate
..........
----------------------------------------------------------------------
Ran 10 tests in 0.003s

OK

+ Python now throws a DeprecationWarning when trying to parse a date
  which has no year.
+ This small patch adds the special handling required to avoid this.
@aeneby
Copy link

aeneby commented Feb 15, 2026

Wouldn't this break for Feb 29th, though? Since 1900 was not a leap year.

@TroyDowling
Copy link
Author

Thanks for the feedback, @aeneby. I take your point. 1900-02-29 is not a valid date. I suppose this problem is inherent to dealing with these ambiguous cases. I see a few workarounds:

  1. Catch the resulting ValueError on "NotALeapYear" and use 1904 as a placeholder value.

This means two placeholder values, which seems messy and harder to maintain.

  1. Revise Khard in general to use a leap year as its placeholder value (such as 1904, the closest leap year.)

This requires a small change anywhere Khard compares to 1900, and presents an opportunity to pull the placeholder year out to a common variable somewhere.

  1. Treat the ambiguous cases as strings.

It appears (at a glance anyway) that the places string_to_date is used also expect and handle text records. See: contacts.py. It may be possible to simply return the ambiguous date cases directly as text.

What do you think? Is there an option I haven't considered?

@aeneby
Copy link

aeneby commented Feb 16, 2026 via email

@lucc
Copy link
Owner

lucc commented Feb 18, 2026

Reply to @TroyDowling's last comment:

  1. I don't like the idea of an extra placeholder, as you say, it's less maintainable
  2. 1904 could be used
  3. strings could also be used, you observed correctly that the birthday and anniversary properties on the VcardWrapper class return datetime|str|None but that is because Vcard v4 allows the BDAY to be any plain text besides being a date. The sorting in khal bdays would change for partial dates if we do this

More general:

As noted in #335 (comment) I would prefer a solution with a new type for partial dates.

I think this approach can still be accepted. I just added a failing test to main to show that the Feb 29 problem is already present. This PR does not improve or worsen the code in that regard. I understand that this PR only wants to fix the deprecation warning.

I suggest we postpone the Feb 29 problem for later. The proper solution can (and in my current opinion will) still be a new partial date type then.


Conclusion:

  • we can use 1900 or 1904 or strings in this PR
  • this PR can concentrate on the deprecation warning
  • we can postpone --02-29 to a separate issue

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

DeprecationWarning on python3.13

3 participants