Driver FixRecommendedSound, Wi-Fi or graphics acting up? Check drivers firstFind missing or outdated drivers fast.Check DriversOctober DealsAmazon USOctober deal check: compare before you payAmazon US: current deals, useful picks and tech finds.Check DealsPC HealthRecommendedCrashes, freezes, slowdowns? Check your PC nowSpot repairable issues before they interrupt work.Check PC×
Skip to content
World desk4 min

Fix Python End-Date Checks That Expire at Midnight

A date parsed without a time becomes midnight. Match the comparison to the rule: compare dates for inclusive calendar-day validity, or use timezone-aware datetimes for exact deadlines.
Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Because parsing a date-only string gives its missing time a value of midnight. If end is parsed from "2026-08-20", the comparison is against 2026-08-20 00:00:00—not the end of August 20. For a rule that includes the whole calendar date, compare dates in the policy’s intended timezone. Keep datetime comparisons for rules that specify an exact time.

What the comparison actually asks

Consider this pattern:

end = datetime.strptime(RUNTIME.free_window_end, "%Y-%m-%d")
return datetime.now() <= end

With the input "2026-08-20", strptime returns a datetime at midnight on August 20. Python’s documentation explains that components not supplied to strptime come from the default 1900-01-01T00:00:00.000; for this format, the date is supplied but the time remains midnight. That is documented behavior, not a parser error. Python datetime documentation

As an Amazon Associate I earn from qualifying purchases.

datetime.now() returns the current local date and time when called without a timezone. So at 09:00 on August 20, the code compares 09:00 with 00:00 on that same date. The comparison is false. The <= operator is doing what it says; the right-hand value represents the start of the date, while the likely requirement is to include the entire date.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

First decide what “end date” means

A calendar date and a precise instant are different contracts. Choose the one the configuration is intended to express before changing the comparison.

Policy Meaning of the configured value Appropriate comparison Boundary to test
Inclusive calendar date The entire named date is valid in a specified timezone. Compare the current date in that timezone with the configured date. Valid late on the final date; invalid when the next date begins.
Exact instant Validity ends at a particular time and timezone or offset. Compare timezone-aware datetimes representing the intended instants. Test immediately before, at, and after the deadline.
Exclusive next-date boundary Validity ends at the start of the day after the final included date. Compare the current instant with that explicitly defined boundary. Test immediately before and at the boundary.

Make a whole calendar date inclusive

If the setting is a date such as 2026-08-20, keep it as a date and compare it with today in the timezone that defines the policy:

from datetime import date, datetime
from zoneinfo import ZoneInfo

policy_tz = ZoneInfo("America/New_York")
end_date = date.fromisoformat(RUNTIME.free_window_end)
today = datetime.now(policy_tz).date()

return today <= end_date

This expresses “valid through the configured date” directly. Replace the example timezone with the one the application’s policy actually uses; the correct choice depends on what “today” means to the product. If the policy is intentionally based on the server’s local calendar, use that local calendar consistently instead.

Alternatively, if the existing code has already parsed a datetime and the contract is definitely date-only, compare the date parts:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
return datetime.now().date() <= end.date()

This short form uses the machine’s local date on the left. It is suitable only when that local calendar is the intended policy timezone. Converting both values to dates is not a general fix for expiration logic: it discards time-of-day information.

Keep an exact deadline as a timezone-aware datetime

If the rule says “until 17:00 UTC” or names another precise instant, store that instant with an explicit timezone or offset. For a UTC deadline, compare aware values:

from datetime import datetime, timezone

end = datetime.fromisoformat(RUNTIME.free_window_end)
now = datetime.now(timezone.utc)

return now <= end

This assumes the configured ISO datetime includes a UTC offset, such as +00:00. If it does not, define how the value should be interpreted rather than silently treating it as UTC. Python’s datetime.now() without a timezone is local and naive; datetime.now(timezone.utc) is aware and represents UTC. Ordering comparisons between a naive and an aware datetime raise TypeError. Python datetime documentation

Local naive datetimes are not inherently wrong when both the stored events and current time are intentionally expressed in the same local-time convention. In a Python issue discussion on January 24, 2022, Python committer Paul Ganssle noted: “Of course, if you are consuming a bunch of event dates stored in local time and you want to compare them to the current time, then datetime.now() would be appropriate.” Python issue discussion

Free tools Windows power users keep installed

One-click scans. No signup required.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

Use the next day only when the boundary is explicit

Another way to represent an inclusive date is an exclusive boundary at midnight on the following date: the interval includes times before that boundary, but not the boundary itself. This can make interval checks clear, provided the application defines the timezone and constructs the next local midnight according to that timezone’s calendar rules.

Do not assume that every local day is exactly 24 hours. Daylight-saving transitions can change the elapsed time between consecutive local midnights. Python documents cases where local times are ambiguous or repeated; these rules matter when constructing local-time boundaries. PEP 495 – Local Time Disambiguation

Test the boundary, not just an ordinary date

Make the current time controllable in tests so the cases verify the contract rather than depending on the clock when the test runs. For an inclusive calendar-date policy ending on August 20, check:

  • A moment shortly after midnight on August 20: valid.
  • A late moment on August 20: valid.
  • A moment just after the next date begins: invalid.
  • A clearly earlier valid date: valid.

Name tests to make the policy visible, for example, test_end_date_includes_late_time_on_final_day. For an exact timestamp policy, test immediately before, exactly at, and immediately after the deadline, including conversions from any supported timezone. The source article describes these boundary cases as a safeguard. The reported incident and code example

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

What is known about the reported 12-hour block

The author of the linked DEV Community article reports that this comparison blocked requests for 12 hours. The Python behavior explains how a date parsed at midnight can make an intended inclusive end date expire as it begins, but the incident duration and operational account are the author’s report; the cited Python documentation does not independently confirm that production incident.

Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.

Leave a Reply

Your email address will not be published. Required fields are marked *

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

More from the Wire

  1. World desk4 min
    How to Spot an AI Voice Scam Before Sending MoneyDon’t rely on how a caller sounds. Pause, call back through a known number, and verify the emergency with another trusted person before sending money.
  2. Mountain View desk4 min
    Google’s SynthID Detector: How to Check AI-Generated Images, Video and AudioGoogle’s SynthID Detector looks for an embedded watermark in supported images, video and audio. Here is what its results do—and do not—show.
  3. Redmond desk20 min
    How to create a link to File or Folder in Windows 11Windows 11 gives you several ways to point to a file or folder without moving or duplicating it. You can create a desktop shortcut,…
Recommended PC Tool
Recommended PC Tool
Crashes, No Sound, or Screen Glitches?Free driver scan
PC Slower Than It Used to Be?Free scan - under a minute

Two free Windows tools

One Free Minute Could Fix That PC

Before you go - each of these free tools takes about a minute and tackles what quietly slows a Windows PC down.

Special offer. View Outbyte info, uninstall instructions, EULA, and Privacy Policy.