The time in a Kalshi ticker is Eastern, not UTC
Two markets, two offsets, one time zone. What it broke here, and the field to use instead.
A field note. Short, verifiable, and the cause of two bugs in this lab on the same day.
Every Kalshi ticker carries a date and a time. KXBTC15M-26JUL301945-45 reads as 30 July 2026, 19:45. The question is 19:45 where. The answer is New York, and if you parse it as UTC every clock in your code is four or five hours wrong.
The exchange's own close_time field settles it. Two markets from the public API, checked on 29 September 2026:
| Ticker | Time in the ticker | close_time from the API |
Offset |
|---|---|---|---|
| KXBTC15M-26JUL301945-45 | 19:45 | 2026-07-30T23:45:00Z | 4 hours |
| KXBTC15M-25DEC101700-00 | 17:00 | 2025-12-10T22:00:00Z | 5 hours |
Four hours in July, five in December. That is not a fixed offset. It is daylight saving time, which means the ticker clock is America/New_York, and a parser that hard codes minus four is wrong for four months of the year.
What it did to us
Two things broke on 3 August, and neither looked like a time zone bug.
The esports miner reported that matches ended five to six hours after their scheduled start. Real matches run one to two hours. The rest was the offset, and it took an afternoon to see.
The crypto copilot's market list went blank. Its close of window function parsed the ticker as UTC, so every live market looked four hours expired and was filtered out. That looked exactly like a stale feed. I blamed the websocket roster first, wrongly, then found the parser.
What to do instead
Prefer the market's close_time, open_time and expiration_time from the API. They are true UTC with a Z on the end and the exchange maintains them. If you must parse a ticker, attach ZoneInfo("America/New_York") and convert. Never treat the digits as UTC and never add a fixed offset.
One more from the same family. Our database stores ISO timestamps with a T in the middle. SQLite's datetime('now') prints a space. A string comparison between the two passes stale rows silently, because the T sorts after the space. Compute cutoffs in Python and pass them in.
Any analysis anchored on ticker derived times that assumed UTC is suspect. Ours from before 3 August were checked.
Watch the 20 second version