A Korean6PM time corresponded to different New York hours on different dates. Reading K-POP PULSE’s historical summer-time correction led me to a new small program that converts a supplied instant by region instead of memorizing an offset. This is a new shared implementation, not recovered operating code.
A date with no announced time does not acquire global clock values. An unannounced state keeps only the source date even if storage contains a midnight proxy. Choose regions for the website and reuse the program with its input example and actual CLI checks.
Receive the date and announcement state first
The input date belongs to source_zone, while time_announced supplies whether a clock was announced. The program does not read an announcement and decide that state; its caller must inspect the evidence. False retains the source date and returns an empty regional-time list rather than supplying a guessed clock.
A genuinely announced midnight uses true and an evidence-backed instant. The conversion then preserves an American previous-day result when appropriate. Hiding all midnight values or forcing regional dates to match the source date would lose another distinction.
Choose regions for the website’s readers
The explanatory input below uses the reviewed historical August19 Korean6PM shape. It is not a current observation of an event. The example lists UTC,New York andLondon, but the code is not limited to three cities. A website selects1–50 distinct supported region keys.
Display names and ordering belong to the interface. A computation key should not silently become a reader-friendly city name. Available time-zone data is required; an unavailable region produces an error rather than a guessed fixed offset. That makes the dependency part of the application contract.
Explore the implementation
Explanatory input. Supply an actually inspected announcement state and instant.
{
"date": "2026-08-19",
"source_zone": "Asia/Seoul",
"time_announced": true,
"start_at": "2026-08-19T18:00:00+09:00",
"zones": [
"UTC",
"America/New_York",
"Europe/London"
]
}A known instant requires an explicit offset
The function rejects a naive datetime. It reads the offset-bearing instant and checks whether its date in the source region matches the supplied announcement date. It then returns UTC and each selected region’s date, datetime, offset and abbreviation rather than subtracting an annual fixed number.
Where clocks move back, the same1:30 notation can represent two different instants. A new check converts two supplied UTC instants and retains their different offsets and fold values. A display can keep these distinctions instead of combining entries based only on clock text or abbreviation.
Define what this input contract does not infer
The module does not receive a local clock and invent its missing offset. It does not decide ambiguous or nonexistent local times, implement recurrence or model releases arriving at midnight separately in each region. Those are different contracts from converting a single established instant.
Source authenticity, changed announcements and clarity of the reader’s display remain separate responsibilities. This code handles supplied input and calculation without network, storage or publication. Output strings still need the interface’s appropriate text handling before insertion into a page.
Carry execution notes and checks with the code
The environment needs Python zoneinfo and available IANA time-zone data. Check the chosen keys on the computer where it will run. Supply JSON by standard input or an --input file. Success returns JSON and exit0; invalid data or unavailable regions return an error and exit2. CLI input is bounded to256KiB.
Twenty-four checks passed, covering one recorded input, synthetic summer/winter, previous day, unknown state, repeated clock and actual file/stdin execution. They do not establish an original-site patch or calendar/search behavior. Rerun the packaged checks in the target environment and inspect the actual supplied evidence and display.
Calculate inside the boundary of known information
I want the module to carry both usable input and unresolved information. A known date can already support a useful notice; a later announced instant can add regional values. Websites with different cities and languages can adapt that interface while retaining the distinction.
The core implementation and ZIP below include the complete CLI, example, checks and notes. They disclose new code rather than an original program or customer dataset. When extending fields and presentation, check that announcement state, source date and offsets still remain connected.
Explore the implementation
New Python implementation; the ZIP includes the complete CLI and checks.
"""Project a supplied announced instant into named zones; preserve date-only uncertainty."""
import argparse,json,sys
from datetime import date,datetime,timezone
from pathlib import Path
from zoneinfo import ZoneInfo
def event_zone_times(record):
if type(record) is not dict or set(record)-{'date','source_zone','time_announced','start_at','zones'}:
raise ValueError('Unsupported event input')
if type(record.get('date')) is not str or type(record.get('time_announced')) is not bool:
raise ValueError('Explicit date and announcement state required')
day=date.fromisoformat(record['date'])
if day.isoformat()!=record['date']:raise ValueError('Use YYYY-MM-DD')
if type(record.get('source_zone')) is not str:raise ValueError('Source zone required')
source=ZoneInfo(record['source_zone'])
keys=record.get('zones')
if type(keys) is not list or not 1<=len(keys)<=50 or any(type(x) is not str for x in keys) or len(set(keys))!=len(keys):
raise ValueError('One to fifty distinct named zones required')
zones=[ZoneInfo(key) for key in keys]
supplied=record.get('start_at')
if supplied is not None and type(supplied) is not str:raise ValueError('Start must be a string or absent')
out={'source_date':day.isoformat(),'source_zone':source.key,'time_announced':record['time_announced'],'start_at_utc':None,'zone_times':[]}
if not record['time_announced']:return out
if supplied is None:raise ValueError('An announced time needs an explicit instant')
instant=datetime.fromisoformat(supplied.replace('Z','+00:00'))
if instant.tzinfo is None or instant.utcoffset() is None:raise ValueError('Explicit offset required')
if instant.astimezone(source).date()!=day:raise ValueError('Source date mismatch')
out['start_at_utc']=instant.astimezone(timezone.utc).isoformat()
for zone in zones:
local=instant.astimezone(zone)
out['zone_times'].append({'zone':zone.key,'date':local.date().isoformat(),'datetime':local.isoformat(),'abbreviation':local.tzname(),'fold':local.fold})
return out
def main():
parser=argparse.ArgumentParser();parser.add_argument('--input',type=Path);args=parser.parse_args()
try:
if args.input:
with args.input.open('rb') as f:raw=f.read(262145)
else:raw=sys.stdin.buffer.read(262145)
if len(raw)>262144:raise ValueError('Input limit exceeded')
result=event_zone_times(json.loads(raw.decode('utf-8')))
except (ValueError,TypeError,KeyError,OSError,OverflowError,RecursionError):
print(json.dumps({'ok':False,'error':'Invalid input or unavailable time-zone data'}));return 2
print(json.dumps({'ok':True,'event':result},ensure_ascii=False));return 0
if __name__=='__main__':raise SystemExit(main())