Time zone converter with DST gap and overlap handling

Convert a clock reading from one IANA time zone to another. When the reading falls in a daylight saving gap (it never happens) or overlap (it happens twice), the page tells you and lets you choose what to do instead of guessing silently. Nothing you type leaves your browser.

The tool

If the time does not exist (clocks jump forward)
If the time happens twice (clocks go back)

How to use

  1. Type the clock reading in Local date and time as YYYY-MM-DD hh:mm:ss (a T instead of the space is accepted, and so is a fraction of a second). The button next to it fills in the current time in the source zone.
  2. Choose the Source zone: the place where that clock reading is true. Use the filter box to narrow the list, then pick from it. Zone names look like America/New_York.
  3. Choose Convert to. It starts on the time zone your browser reports.
  4. Say what to do with a reading that does not name exactly one instant. If the time does not exist: shift it later by the length of the gap, shift it earlier by the same amount, or reject it. If the time happens twice: use the earlier instant, the later instant, or reject it.
  5. Read the result. The page states whether the reading exists once, does not exist or happens twice, shows the resulting instant in the target zone, in UTC and as an epoch number, and, for a skipped or repeated reading, what it did. The 24-hour bar shows the target day with the offset in force across it, so a clock change inside that day is visible.

The conversion itself goes through the instant: the clock reading and source zone are turned into one point on the UTC time-line, and that point is shown in the target zone. If you already have an epoch number, the epoch converter shows it in any zone directly.

Worked examples

Every result printed here is recomputed by an automated test from the same engine as the tool. The zone transitions behind them are also checked against Python's zoneinfo and Go's time package in the tests.

Noon in New York, before and after the US clocks changed

On 8 March 2026 New York's offset changes from -05:00 to -04:00, so the same noon is one hour earlier in UTC the next day, and Jakarta (no daylight saving, always +07:00) sees it move.

From America/New_York to Asia/Jakarta

Input: 2026-03-07 12:00:00

Output: exists once; 2026-03-08T00:00:00+07:00; UTC 2026-03-07T17:00:00Z; epoch 1772902800

From America/New_York to Asia/Jakarta

Input: 2026-03-08 12:00:00

Output: exists once; 2026-03-08T23:00:00+07:00; UTC 2026-03-08T16:00:00Z; epoch 1772985600

The three weeks when New York and London are 4 hours apart

The same 09:00 in New York, converted to London on three dates in 2026:

From America/New_York to Europe/London

Input: 2026-02-20 09:00:00

Output: exists once; 2026-02-20T14:00:00+00:00; UTC 2026-02-20T14:00:00Z; epoch 1771596000

From America/New_York to Europe/London

Input: 2026-03-20 09:00:00

Output: exists once; 2026-03-20T13:00:00+00:00; UTC 2026-03-20T13:00:00Z; epoch 1774011600

From America/New_York to Europe/London

Input: 2026-04-20 09:00:00

Output: exists once; 2026-04-20T14:00:00+01:00; UTC 2026-04-20T13:00:00Z; epoch 1776690000

On 20 March the US is already on daylight time (-04:00) and London is still on standard time (+00:00), so 09:00 in New York is 13:00 in London, not 14:00.

An offset that is not a whole hour

From Asia/Kathmandu to Asia/Jakarta

Input: 2026-10-03 12:00:00

Output: exists once; 2026-10-03T13:15:00+07:00; UTC 2026-10-03T06:15:00Z; epoch 1791008100

Nepal's offset is +05:45, so noon there is 06:15 UTC. Code that stores an offset as a number of whole hours cannot represent this.

A time in the spring-forward gap

New York skips from 01:59:59 to 03:00:00 on 8 March 2026, so 02:30 never appears. The three choices give three answers, shown here converted to London:

From America/New_York to Europe/London; skipped time: Shift later

Input: 2026-03-08 02:30:00

Output: does not exist; 2026-03-08T07:30:00+00:00; UTC 2026-03-08T07:30:00Z; epoch 1772955000

From America/New_York to Europe/London; skipped time: Shift earlier

Input: 2026-03-08 02:30:00

Output: does not exist; 2026-03-08T06:30:00+00:00; UTC 2026-03-08T06:30:00Z; epoch 1772951400

From America/New_York; skipped time: Reject

Input: 2026-03-08 02:30:00

Result: does not exist; rejected

"Shift later" lands on 03:30 New York time (07:30 UTC), "shift earlier" on 01:30 (06:30 UTC); the two differ by exactly the one-hour gap.

Other gaps, all in the same engine:

From Europe/Berlin to Asia/Jakarta; Shift later

Input: 2026-03-29 02:30:00

Output: does not exist; 2026-03-29T08:30:00+07:00; UTC 2026-03-29T01:30:00Z; epoch 1774747800

From Australia/Sydney to Europe/London; Shift later

Input: 2026-10-04 02:30:00

Output: does not exist; 2026-10-03T17:30:00+01:00; UTC 2026-10-03T16:30:00Z; epoch 1791045000

From Australia/Lord_Howe to Asia/Jakarta; Shift later

Input: 2026-10-04 02:15:00

Output: does not exist; 2026-10-03T22:45:00+07:00; UTC 2026-10-03T15:45:00Z; epoch 1791042300

Lord Howe Island's gap is only 30 minutes long. Gaps are not always at 02:00 either: São Paulo's 2018 change skipped midnight, and Samoa removed a whole day in 2011.

From America/Sao_Paulo to Europe/London; Shift later

Input: 2018-11-04 00:30:00

Output: does not exist; 2018-11-04T03:30:00+00:00; UTC 2018-11-04T03:30:00Z; epoch 1541302200

From Pacific/Apia to Europe/London; Shift later

Input: 2011-12-30 12:00:00

Output: does not exist; 2011-12-30T22:00:00+00:00; UTC 2011-12-30T22:00:00Z; epoch 1325282400

A time in the fall-back overlap

At 02:00 on 1 November 2026 New York's clocks go back to 01:00, so 01:30 happens twice. With the source zone set to New York, the page lists both instants as epoch numbers (the first is the earlier):

Source America/New_York

Input: 2026-11-01 01:30:00

Both instants: 1793511000 (-04:00) and 1793514600 (-05:00)

From America/New_York to Europe/London; Earlier one

Input: 2026-11-01 01:30:00

Output: happens twice; 2026-11-01T05:30:00+00:00; UTC 2026-11-01T05:30:00Z; epoch 1793511000

From America/New_York to Europe/London; Later one

Input: 2026-11-01 01:30:00

Output: happens twice; 2026-11-01T06:30:00+00:00; UTC 2026-11-01T06:30:00Z; epoch 1793514600

The two readings are one hour apart. Other overlaps:

Source Europe/Berlin

Input: 2026-10-25 02:30:00

Both instants: 1792888200 (+02:00) and 1792891800 (+01:00)

Source Australia/Sydney

Input: 2026-04-05 02:30:00

Both instants: 1775316600 (+11:00) and 1775320200 (+10:00)

What your language does with the same clock time

The same two questions asked in several languages. The ones marked as executed were run while this page was written, on a machine with the 2026c time zone database, and print exactly what is shown. The JavaScript runs used TZ=America/New_York as the process time zone.

New York 02:30 on 8 March 2026 (does not exist)

JavaScript (Node.js)

// process time zone: America/New_York
console.log(new Date(2026, 2, 8, 2, 30).toISOString());

Output when run with TZ=America/New_York: 2026-03-08T07:30:00.000Z The skipped 02:30 is read with the offset from before the jump (-05:00), which gives 07:30 UTC, shown as 03:30 in New York.

Python 3 (zoneinfo)

from datetime import datetime, timezone
from zoneinfo import ZoneInfo
d = datetime(2026, 3, 8, 2, 30, tzinfo=ZoneInfo("America/New_York"))
print(d.isoformat())
print(d.astimezone(timezone.utc).isoformat())

Output when run: 2026-03-08T02:30:00-05:00 | 2026-03-08T07:30:00+00:00 Python keeps the impossible wall time 02:30 and labels it -05:00; only converting it to UTC reveals the shifted instant.

Go

loc, _ := time.LoadLocation("America/New_York")
d := time.Date(2026, 3, 8, 2, 30, 0, 0, loc)
fmt.Println(d.Format(time.RFC3339))
fmt.Println(d.UTC().Format(time.RFC3339))

Output when run: 2026-03-08T01:30:00-05:00 | 2026-03-08T06:30:00Z Go moved the time earlier. Its documentation says the result is correct in one of the two zones involved but does not guarantee which.

New York 01:30 on 1 November 2026 (happens twice)

JavaScript (Node.js)

// process time zone: America/New_York
console.log(new Date(2026, 10, 1, 1, 30).toISOString());

Output when run with TZ=America/New_York: 2026-11-01T05:30:00.000Z The earlier of the two instants (05:30 UTC, offset -04:00).

Python 3 (zoneinfo)

from datetime import datetime, timezone
from zoneinfo import ZoneInfo
ny = ZoneInfo("America/New_York")
for fold in (0, 1):
    d = datetime(2026, 11, 1, 1, 30, tzinfo=ny, fold=fold)
    print(fold, d.isoformat(), d.astimezone(timezone.utc).isoformat())

Output when run: 0 2026-11-01T01:30:00-04:00 2026-11-01T05:30:00+00:00 | 1 2026-11-01T01:30:00-05:00 2026-11-01T06:30:00+00:00 fold=0 is the earlier instant, fold=1 the later one (PEP 495). Python returns both when asked; the default is fold=0.

Go

loc, _ := time.LoadLocation("America/New_York")
d := time.Date(2026, 11, 1, 1, 30, 0, 0, loc)
fmt.Println(d.Format(time.RFC3339))
fmt.Println(d.UTC().Format(time.RFC3339))

Output when run: 2026-11-01T01:30:00-04:00 | 2026-11-01T05:30:00Z In this run Go chose the earlier instant. Its documentation does not guarantee which one it picks.

What goes wrong

The usual ways clock times go wrong between zones.

Converting with a fixed offset instead of a zone

"New York is UTC-5" is true until 8 March 2026 and false after it. The two noons in the first worked example show it: the same noon in New York is 17:00 UTC on 7 March and 16:00 UTC on 8 March. A fixed offset is correct for one instant only; a zone name carries the rules.

Assuming the gap between two places is constant

New York and London differ by 5 hours for most of the year, 4 hours between the US change on 8 March and the UK change on 29 March 2026, and again between the UK change on 25 October and the US change on 1 November. A recurring meeting set in one zone moves in the other zone's clock when only one of them changes.

Silently accepting a time that does not exist

Many libraries accept 02:30 on 8 March in New York without complaint and return a plausible instant. As the snippets above show, which instant depends on the library: Python keeps the impossible time and only reveals the shift when you convert, JavaScript shows 03:30, and Go gave 01:30. If the time came from a person, the safest course is to ask them; this tool's "reject" option exists for that.

Mixing up which side of the overlap is meant

A log line or a booking that says only "01:30" on 1 November in New York is ambiguous by an hour. Store the offset with it (-04:00 or -05:00) or store the instant.

Zone abbreviations

"IST" means India Standard Time, Irish Standard Time or Israel Standard Time depending on who wrote it (see the FAQ). The tool takes zone names, and there is no reliable way to turn an abbreviation into one.

Rules that changed after your software was built

Offsets for future dates are predictions. An application with an old copy of the time zone database will convert a date after a rule change with the old rule. The UTC instant is right only if the clock reading was right under the rules that actually apply on the day.

Limits & gotchas

  • Zone data comes from your browser. The list of zones and every offset are the browser's own copy of the IANA time zone database. Browsers update it with their releases, so a very recent rule change may be missing, and two browsers can disagree. This site does not download any zone data. While testing we saw a Node release with 2024b data and the 2026c data on the build machine disagree about Africa/Casablanca after 2026-09-20.
  • Future offsets are predictions. The IANA database records the history and the predicted future of civil time. A government can change the rule at short notice, and then a conversion made earlier for a date after the change is wrong.
  • Only zone names, not abbreviations or bare offsets, are accepted as zones. To convert from a fixed offset, use the ISO 8601 validator (it reads -05:00 in a timestamp) or the epoch converter.
  • The "skipped time" shift is the gap length, as the tool computes it. Shift later gives the result a JavaScript Date or Java ZonedDateTime gives; shift earlier is the mirror image. Other systems use other conventions (see the snippets), and neither choice is "the" standard answer.
  • Range. Dates are limited to the range of a JavaScript Date (about the years -271821 to +275760). Before 1970 many zones used local mean time or had other rules; the database records them only as far as its authors could document, and the page does not warn about that.
  • Calendar. Dates are in the proleptic Gregorian calendar, including before the date a country adopted it.
  • Leap seconds are not modelled: a reading of 23:59:60 is not accepted here (the ISO 8601 validator explains it).

FAQ

What happens to a clock time that falls in the spring-forward gap?

It never appears on a wall clock, so there is no single right answer, and software disagrees. JavaScript's Date and Java's ZonedDateTime move the time forward by the length of the gap (02:30 in New York on 8 March 2026 becomes 03:30). Python's datetime keeps the impossible 02:30 and gives it the offset from before the jump when fold=0 (PEP 495); Temporal's default, "compatible", matches JavaScript Date. In the run made for this page Go moved the time the other way, to 01:30. This tool lets you choose: shift later, shift earlier, or reject the input.

Which instant do I get when a clock time happens twice?

JavaScript's Date and Temporal's default pick the earlier of the two instants, and Python picks the earlier one unless you set fold=1. Java keeps the previous offset when the zoned date-time already has one, and otherwise uses the earlier offset. Go's documentation does not guarantee which one it returns. This tool defaults to the earlier one and can show you both (the two epoch numbers for 01:30 on 1 November 2026 in New York are 1793511000 and 1793514600) or reject the time.

Should I store a local time or a UTC time?

It depends on what the time means. For something that already happened, store the instant (UTC or an epoch number) and, if you need to show it locally, the zone name. For a future appointment that people will attend by the wall clock, such as a 09:00 meeting in Berlin, store the local date-time and the zone name, because the IANA database records only the predicted future of civil time and its release notes show rules being changed ahead of time (Morocco, Alberta and Manitoba in 2026). A UTC instant computed today from a future local time can be an hour off after such a change.

Why does 09:00 in New York map to a different London time in March?

The two places change their clocks on different dates. In 2026 the US moved on 8 March and the UK on 29 March, so for three weeks the gap between New York and London is 4 hours instead of 5 (see the worked examples, and the DST finder for any zone). Plan around those weeks specifically.

Can I type an abbreviation such as EST or IST?

No. Abbreviations are not unique: the IANA time zone theory document lists IST as India, as Irish time and as Israel. This tool takes zone names of the form Area/Location (for example America/New_York), which identify a place and carry its full rule history, from the list your browser provides.

Sources

  • IANA: Theory and pragmatics of the tz code and data Used for: The database records the history and the predicted future of civil time scales; names have the form Area/Location (for example Asia/Calcutta was renamed Asia/Kolkata, with the old name kept as a link); the abbreviation list shows that one abbreviation can mean different things (IST appears for India, for Irish time and for Israel).
  • IANA: News for the tz database Used for: Recent rule changes made on short notice: release 2026c (2026-07-08) lists Alberta moving to permanent -06 and Morocco to permanent +00 from 2026-09-20; release 2026e (2026-09-29) lists Manitoba moving to permanent -05 on 2026-10-31.
  • Python Software Foundation: PEP 495: Local Time Disambiguation Used for: The terms fold (clocks moved back, ambiguous local times) and gap (clocks moved forward, missing local times); the fold attribute; at a gap or fold, fold=0 uses the UTC offset in effect before the transition and fold=1 the offset after it ("the interpretation of the fold attribute is consistent in the fold and gap cases").
  • Python Software Foundation: datetime: Basic date and time types Used for: datetime.fold: "Used to disambiguate wall times during a repeated interval"; the values 0 and 1 mean the earlier and later of the two moments.
  • Python Software Foundation: zoneinfo: IANA time zone support Used for: ZoneInfo reads the IANA database and honours fold: the offset from before the transition is used when fold=0 and the offset after when fold=1; datetime + timedelta(days=1) is wall-clock arithmetic.
  • The Go Authors: Go package time: Date Used for: Time.UnixNano is undefined for dates before the year 1678 or after 2262 (it must fit an int64). time.Date: in a transition that skips or repeats times (the doc's example is the US, 2011), "Date returns a time that is correct in one of the two zones involved in the transition, but it does not guarantee which."
  • Oracle: Java SE 21: java.time.ZonedDateTime Used for: For a local date-time that falls in a gap, the zoned date-time is shifted forward by the length of the gap, ending in the later offset; for an overlap the previous offset is retained if there is one, otherwise the earlier offset is used. plusDays works on the local time-line (adding days to the local date-time and converting back), whereas plusHours works on the instant time-line, so adding one hour is always a duration of one hour. Java is not installed on the machine used to build this site, so Java behaviour here is described from the documentation, not executed.
  • MDN Web Docs: Date Used for: The supported range (April 20, 271821 BC to September 13, 275760 AD, plus or minus 100,000,000 days); that Date ignores leap seconds; Number.MAX_SAFE_INTEGER is 9,007,199,254,740,991; the date-time string format (a simplification of ISO 8601, 24:00:00 allowed, expanded years of + or - followed by six digits, -000000 disallowed); and that setting a local time inside a DST transition follows the Temporal "compatible" disambiguation: if the local time corresponds to two instants the earlier one is chosen, and if it does not exist the result goes forward by the gap duration (with the New York 2024 example).
  • MDN Web Docs: Temporal.ZonedDateTime.from() Used for: The disambiguation option for a local time that is skipped or repeated: "compatible" (default), "earlier", "later" or "reject".
  • Ecma International / TC39: ECMAScript Language Specification: Time Values and Time Range; Date.parse; time zone offset helper operations Used for: A time value is milliseconds since 1970-01-01T00:00:00Z with every day exactly 86,400,000 ms (leap seconds are ignored); the range is +-8.64e15 ms (+-100,000,000 days); for a local time that is skipped or repeated, the offset in use before the transition is applied; a skipped local time yields no instant in the time-zone-to-epoch operation.
  • MDN Web Docs: Intl.supportedValuesOf() Used for: "timeZone" is a valid key and the call returns a sorted array of unique values supported by the implementation.

Every document above was opened and read on 2026-10-03. Documentation changes; if a page here disagrees with the current docs, trust the docs and tell us.