Move one holiday check only after a frozen cutoff table holds. A messy ship function hides three clocks in one return. An early extract can flip a same-day answer without a failing test.
Start from the boolean you have
Same-day shipping rules fail in quiet local ways. A holiday string can miss the zoned date. A VIP hour bump can cross a trusted cutoff.
This module is only a labeled teaching example. It is not a trace from a live warehouse. Keep every instant inside fixtures you already control.
The safe order is fixed for this cut. Lock the current booleans before any production edit.
Move one predicate only after that lock. Leave every other branch untouched in this pass.
The function under change
Four rules share one boolean return in this file. Holidays, blackouts, local cutoff, and weekends collapse together.
A mixed edit can change two rules at once. The diff can still look tidy after that slip.
from datetime import time
from zoneinfo import ZoneInfo
HOLIDAYS = {"2026-11-26", "2026-12-25"}
BLACKOUT = {"air"}
def can_ship_today(now, warehouse_tz, carrier, vip):
local = now.astimezone(ZoneInfo(warehouse_tz))
cutoff = time(15, 0) if carrier != "air" else time(12, 0)
if vip:
cutoff = time(cutoff.hour + 1, 0)
stamp = local.date().isoformat()
if stamp in HOLIDAYS or carrier in BLACKOUT:
return False
if local.time() >= cutoff:
return False
if local.weekday() >= 5:
return False
return True
Do not format this file as the opening move. Characterization is the opening move for this cut. The extract waits until all twelve rows pass.
Twelve rows, not a wish list
Each row binds one instant, zone, carrier, and flag. The expected cell is today's boolean, not a wish.
Record behavior you may later reject on purpose. A row without an owner does not enter.
The October rows below assume US daylight time. New York is four hours behind UTC then. Los Angeles is seven hours behind UTC then.
The November and December rows use standard time. Chicago is six hours behind UTC on row 8. Los Angeles is eight hours behind UTC in December.
Tokyo stays nine hours ahead of UTC all year. Row 12 depends on that fixed nine-hour offset.
| # | UTC instant | Zone | Carrier | VIP | Expected |
|---|---|---|---|---|---|
| 1 | 2026-10-13T18:59:00Z | America/New_York | ground | false | true |
| 2 | 2026-10-13T19:00:00Z | America/New_York | ground | false | false |
| 3 | 2026-10-13T19:30:00Z | America/New_York | ground | true | true |
| 4 | 2026-10-13T20:00:00Z | America/New_York | ground | true | false |
| 5 | 2026-10-13T15:59:00Z | America/New_York | air | false | false |
| 6 | 2026-10-17T15:00:00Z | America/New_York | ground | false | false |
| 7 | 2026-11-26T15:00:00Z | America/New_York | ground | false | false |
| 8 | 2026-11-26T16:00:00Z | America/Chicago | ground | true | false |
| 9 | 2026-12-25T18:00:00Z | America/Los_Angeles | ground | false | false |
| 10 | 2026-10-14T21:00:00Z | America/Los_Angeles | ground | false | true |
| 11 | 2026-10-14T22:00:00Z | America/Los_Angeles | ground | false | false |
| 12 | 2026-11-25T16:00:00Z | Asia/Tokyo | ground | false | false |
These expected cells follow the function and offsets above. Recompute each cell before you adopt the file.
Row 1 sits one minute before the local cutoff. Row 2 is the cutoff, and the check is inclusive.
Row 3 stays allowed only because VIP adds one hour. Row 4 lands on that VIP cutoff and stays denied.
Row 5 is the dead branch for air. Air sits in the blackout set, so noon never runs. Keep that denial, and do not repair air here.
Row 6 is Saturday morning in New York. The clock is before cutoff, yet weekend denies.
Rows 7 and 8 are local holidays, so VIP loses. Row 9 is Christmas in Los Angeles, also denied.
Row 10 is 14:00 in Los Angeles and still allowed. Row 11 is 15:00 there and must be denied.
Row 12 is the date-shift trap in this table. UTC is still 25 November at that instant.
Tokyo is already 26 November at 01:00. The holiday set must use the local date.
1. Put the table in pytest
Hard-code every expected boolean in the test. Do not call the function to mint expectations. A generated oracle will bless the next bad edit.
from datetime import datetime
import pytest
from shipping.cutoff import can_ship_today
ROWS = [
("2026-10-13T18:59:00Z", "America/New_York", "ground", False, True),
("2026-10-13T19:00:00Z", "America/New_York", "ground", False, False),
("2026-10-13T19:30:00Z", "America/New_York", "ground", True, True),
("2026-10-13T20:00:00Z", "America/New_York", "ground", True, False),
("2026-10-13T15:59:00Z", "America/New_York", "air", False, False),
("2026-10-17T15:00:00Z", "America/New_York", "ground", False, False),
("2026-11-26T15:00:00Z", "America/New_York", "ground", False, False),
("2026-11-26T16:00:00Z", "America/Chicago", "ground", True, False),
("2026-12-25T18:00:00Z", "America/Los_Angeles", "ground", False, False),
("2026-10-14T21:00:00Z", "America/Los_Angeles", "ground", False, True),
("2026-10-14T22:00:00Z", "America/Los_Angeles", "ground", False, False),
("2026-11-25T16:00:00Z", "Asia/Tokyo", "ground", False, False),
]
def _parse(stamp):
parsed = datetime.fromisoformat(stamp.replace("Z", "+00:00"))
offset = parsed.utcoffset()
if offset is None or offset.total_seconds() != 0:
raise AssertionError("fixture must be UTC")
return parsed
@pytest.mark.parametrize("stamp,zone,carrier,vip,expected", ROWS)
def test_cutoff_table(stamp, zone, carrier, vip, expected):
now = _parse(stamp)
assert can_ship_today(now, zone, carrier, vip) is expected
Run that file before you touch production code. This pytest file is a proposal, not a recorded lab run.
python -m pytest tests/test_cutoff_table.py -q
Twelve passes is the gate you require first. A failure here means the fixture is wrong. Fix the row or the zone assumption, then stop.
2. Read a red row before you edit
A flipped row names the rule you disturbed. Use the map below before any second attempt.
| Red row | Likely slip | Required response |
|---|---|---|
| 1 or 2 | Inclusive cutoff edge moved | Restore the >= check |
| 3 or 4 | VIP hour bump changed | Leave VIP math in place |
| 5 | Blackout no longer returns first | Put BLACKOUT back in the caller |
| 6 | Weekend used the UTC weekday | Keep local.weekday()
|
| 7, 8, or 9 | Holiday stamp missed the local date | Restore local isoformat
|
| 12 | Holiday check used the UTC date | Pass local.date() only |
Do not add a thirteenth row during the extract. A new row is a new contract for reviewers. Park it until a person owns the instant.
3. Move only the holiday predicate
The smallest safe change is a rename of one condition. Blackout, cutoff, VIP, and weekend stay put.
The new helper receives the local date only. It must not receive the original UTC instant.
def is_observed_holiday(local_date):
return local_date.isoformat() in HOLIDAYS
def can_ship_today(now, warehouse_tz, carrier, vip):
local = now.astimezone(ZoneInfo(warehouse_tz))
cutoff = time(15, 0) if carrier != "air" else time(12, 0)
if vip:
cutoff = time(cutoff.hour + 1, 0)
if is_observed_holiday(local.date()) or carrier in BLACKOUT:
return False
if local.time() >= cutoff:
return False
if local.weekday() >= 5:
return False
return True
Inspect the diff before you trust a passing run. The helper should be the only new name. No cutoff constant should change in that diff.
git diff -U3 -- shipping/cutoff.py
Re-run the same twelve rows after the move. The command does not change between the two runs. Only the exit status decides the next step.
python -m pytest tests/test_cutoff_table.py -q
If any row flips, restore the function at once. Do not patch forward with a second helper. One red cell means the cut changed behavior.
4. Use a second machine only after local passes
Disclosure: This article was prepared as part of MonkeyCode's product outreach. The notes below are method limits, not a product ranking.
A free model pass can list risks in the function. Ask for risks, not a rewritten shipping module.
Map each risk onto a row you already own. Drop any suggested instant that lacks an owner.
A free server option can run the same pytest file. Treat that run as a second environment only.
Your laptop table remains the source of expected booleans. Matching exit codes is the only comparison required.
Do not ask the model for hardware or quota claims. Those facts sit outside this refactor method entirely. The method is the frozen table plus one move.
Limits of this cut
The table locks twelve booleans, not the whole domain. It will not catch a warehouse missing from fixtures. It will not notice a holiday added after the file.
Zone data comes from the machine under test. A host with stale tzdata can fake a passing run.
On Windows, confirm ZoneInfo can load the zone names. Pin the Python version in the project file you use.
Re-check row 12 after any zone-data update. Treat a mismatch as a host issue, not a logic win.
This pattern is a poor fit for some teams. Skip it when the function opens a network or file. Skip it when the body reads the system clock.
Skip it when now cannot be injected as an argument. Skip it for tax, payment capture, or dosing logic. A wrong boolean there is not a shipping miss.
Also skip it when you want a full rewrite now. That goal fights the one-predicate gate on purpose. The gate allows one predicate, then a fresh review.
What not to bundle
Leave the dead air cutoff alone in this pass. Leave the VIP hour math alone as well.
Leave weekend numbering on the local date object. Each of those can be a later, separate change.
The same twelve rows should still be running. Do not retire the file after one extract.
A later change still starts from this table. Add rows only when a person owns the new instant.
Then move one branch and read the diff. Then stop, even if another cleanup looks obvious.
When the local table already passes, stop editing. A free server run can then sit beside review. Use it only as a second environment check.
Top comments (0)