To convert UTC to JST, add 9 hours: 00:00 UTC is 09:00 JST. Japan has one time zone and hasn’t used daylight saving since 1951, so the conversion is the same on every date.
A worked conversion
The tool below starts at midnight UTC on Thursday, January 15, 2026:
2026-01-15 00:00 UTC (UTC+00:00, UTC)
2026-01-15 09:00 Asia/Tokyo (UTC+09:00, JST)
From 15:00 UTC on, Japan is already on the next date: 15:00 UTC on Thursday, January 15 is 00:00 JST on Friday, January 16. Logs and reports grouped by UTC day split a Japanese day at 09:00 local time.
Japan’s working day in UTC
09:00 to 18:00 JST is 00:00 to 09:00 UTC. A job scheduled at midnight UTC runs at the start of the Tokyo working day, and a 17:00 UTC release lands at 02:00 in Japan. Seoul (Asia/Seoul, KST) is also UTC+9 with no daylight saving, so it shows the same clock as Tokyo.
JST in code
The three letters are clear to people but not to software. Node.js 22 accepts timeZone: 'JST' and reads it as Asia/Tokyo; Python’s ZoneInfo("JST") raises ZoneInfoNotFoundError; GNU date doesn’t know the name and prints UTC:
TZ=JST date -d '2026-01-15 00:00 UTC'
# Thu Jan 15 00:00:00 JST 2026 wrong: that's UTC
TZ=Asia/Tokyo date -d '2026-01-15 00:00 UTC'
# Thu Jan 15 09:00:00 JST 2026
The old link Japan still works too, but Asia/Tokyo is the name to store.
new Date('2026-01-15T00:00:00Z').toLocaleString('ja-JP', { timeZone: 'Asia/Tokyo', timeZoneName: 'short' })
// '2026/1/15 9:00:00 JST'
With 'en-US' the label is GMT+9 instead of JST: it comes from the locale’s data, not the zone.
from datetime import datetime, timezone
from zoneinfo import ZoneInfo
datetime(2026, 1, 15, 0, 0, tzinfo=timezone.utc).astimezone(ZoneInfo("Asia/Tokyo")).isoformat()
# '2026-01-15T09:00:00+09:00'