Your user typed the right date, time and city, and the chart is still wrong. Look first at one line of your code: the one that turns the local clock time into world time (UTC).
That line needs the offset from UTC that was in force at that place, on that date. The trap is sending a fixed number, such as -5 for New York. A fixed number ignores daylight saving time. It also ignores old clock rules, like US war time from 1942 to 1945, or local sun time before 1883.
We measured the damage with our API. John Doe was born on Aug 15, 1990, at 10:30 AM in New York. Daylight saving time was on, so the right offset is UTC-4. Sent as UTC-5, his lagna (rising sign, the sign rising in the east at birth) moved 11.9 degrees, from Virgo into Libra. All nine planets changed house. The Moon moved 0.6 degrees.
The fix is short. Send the time zone name, such as America/New_York, not a number. Our API then reads the right offset for that exact moment. It refuses a clock time that never happened or happened twice, instead of guessing.
Below are five real mistakes, each one measured with real API calls.
What one wrong hour does to a chart
We sent John's birth four times. Only the time zone changed. Everything else stayed the same.
What we sent as | Offset used | Lagna | Moon | Moon's house |
|---|---|---|---|---|
| UTC-4 (EDT) | Virgo 19°56′ | Taurus 24°34′, Mrigashira | 9 |
| UTC-5 | Libra 1°48′ | Taurus 25°10′, Mrigashira | 8 |
| UTC-3 | Virgo 8°01′ | Taurus 23°59′, Mrigashira | 9 |
| UTC+0 | Leo 2°23′ | Taurus 22°12′, Rohini | 10 |
One hour moved the lagna 11.9 degrees either way. The Moon moved 0.6 degrees, which is about 36 arc minutes. That looks small, but the lagna is what decides the houses. Our API counts whole-sign houses: the lagna's sign is house 1, the next sign is house 2, and so on. When the lagna moved from Virgo to Libra, every planet slid back one house. The Sun went from house 11 to house 10.
The worst row is the last one. Some code sends the clock time as if it were already UTC. For John that is 4 hours off. His lagna moved 47.6 degrees, into Leo. His Moon crossed into a new nakshatra (birth star, one of 27 star groups), Rohini. Rohini's ruling planet is the Moon, not Mars, so his dasha timeline (planet periods) would start with a different planet.
A wrong chart does not look broken. Every planet still sits in a real sign, and the reading still sounds fine. It is simply the chart of someone born an hour later. A chatbot that guesses a chart makes the same mistake, as our AI astrologer guide shows with this same birth. For how each of the three main signs is found, see Moon sign, Sun sign and rising sign.
Mistake 1: a fixed offset that ignores daylight saving
A developer sees "New York is UTC-5" and hard-codes it. That is true in winter. From the second Sunday in March to the first Sunday in November, New York runs at UTC-4. Those have been the US rules since 2007.
A city name alone cannot give you the offset. The date decides it. So the offset cannot live in a city table next to the coordinates. It has to be worked out for each birth.
The same trap works the other way. Code that takes today's offset from the server clock gives a winter birth summer's offset. Either way, the chart moves by a full hour.
Mistake 2: old clock rules, such as US war time
Daylight saving rules change over the years, and sometimes for a few years only. During World War II, the US moved clocks one hour ahead all year. That "war time" ran from Feb 9, 1942, to Sep 30, 1945.
Take a birth in Chicago on Feb 10, 1944, at 10:30 AM. Today's rules say Chicago is UTC-6 in February. That is wrong for 1944. We sent America/Chicago, and the API used UTC-5 and named it CWT, Central War Time.
What we sent | Offset used | Lagna | Moon |
|---|---|---|---|
| UTC-5 (CWT) | Aries 2°12′, Ashwini | Leo 13°01′, Magha |
| UTC-6 | Aries 25°08′, Bharani | Leo 13°31′, Purva Phalguni |
Here one hour moved the lagna 22.9 degrees, not 11.9. The lagna does not move at a steady pace. Some signs rise faster than others, so the size of the error changes from chart to chart. The Moon also crossed into a new nakshatra.

Our post on how to choose an astrology API tests two more cases: the US winter of 1974 and India in the war.
Mistake 3: local sun time before 1883
Before Nov 18, 1883, US cities did not share time zones. Each town set its clocks by the Sun, so noon was when the Sun was highest there. This is called local mean time, or LMT. The time zone database keeps it, so a zone name covers old births too.
We sent a Chicago birth on Jun 1, 1880, at 10:30 AM. With America/Chicago, the API used UTC-5:50:36 and labelled it LMT. Sent as a plain -6, the time is off by 9.4 minutes.
That is a smaller error, but it still shows. The lagna moved 1.8 degrees, from Leo 5°12′ to Leo 7°02′. The Moon moved into the next pada (one of the 4 quarters of a nakshatra). The Moon's pada is used in kundli matching and in traditional baby naming, so those results can change too.
Mistake 4: a clock time that never happened
Clocks in the US jump forward at 2:00 AM on the day daylight saving starts. So the hour from 2:00 to 2:59 AM does not exist on that day.
In Chicago, that happened on Apr 2, 1995. We sent a birth at 2:30 AM that day with America/Chicago. The API did not return a chart. It returned HTTP 422 with this message:
1995-04-02T02:30:00 does not exist in America/Chicago, because the clocks jumped forward past it. Check the birth time, or send the UTC offset that was really in use.Then we sent the same time with fixed offsets. Both worked, and the two charts disagree. With -6 (standard time), the lagna is Capricorn 4°37′. With -5 (daylight time), it is Sagittarius 17°58′. That is a gap of 16.7 degrees and a different lagna sign.
So a time in the gap is a question for the user. The birth time may have a typo, or the record may use standard time. Show the API's message, and let the user fix the time or confirm the offset.
Mistake 5: a clock time that happened twice
When daylight saving ends, clocks go back from 2:00 AM to 1:00 AM. So every minute from 1:00 to 1:59 AM happens twice: first in daylight time, then in standard time. It last happened in Chicago on Nov 1, 2026.
We used the same night in 1995, Oct 29. We sent a Chicago birth at 1:30 AM with America/Chicago and nothing else. Again the API returned 422 and refused to guess:
1995-10-29T01:30:00 occurs twice in America/Chicago: once at UTC-5 and again at UTC-6 after the clocks went back. Send `timezone` as the offset you mean. Or send `timezone_fold`: 0 for the first time, 1 for the second.Here is what the two choices return:
What we added | Offset used | Lagna |
|---|---|---|
| UTC-5 (CDT) | Leo 2°37′, Magha |
| UTC-6 (CST) | Leo 14°18′, Purva Phalguni |
The two births are one hour apart in real time. The lagna differs by 11.7 degrees, and its nakshatra changes. The Moon stayed in Purva Ashadha both times. So ask the user. If the birth record names CDT or CST, use that.
Every answer from our API shows the offset it used, in meta.timezone. You can show that offset next to the chart, so a user can spot a wrong hour. Read how the API handles time zones in the conventions guide, or try a chart in the free kundli tool.

The right request
Send the local clock time as the user typed it. Add the latitude, the longitude and the IANA time zone name. IANA is the group that keeps the world's time zone database. Here is the request for John Doe, born Aug 15, 1990, at 10:30 AM in New York, to POST /v1/planets:
{
"year": 1990,
"month": 8,
"day": 15,
"hour": 10,
"minute": 30,
"latitude": 40.7128,
"longitude": -74.006,
"timezone": "America/New_York"
}Part of the answer tells you what the API did with the time zone:
{
"meta": {
"timezone": {
"source": "zone",
"offset_hours": -4,
"zone": "America/New_York",
"abbreviation": "EDT",
"dst": true,
"dst_hours": 1,
"ambiguous_resolved_by_fold": null
}
}
}A few more behaviors, each tested:
What you send | What the API does |
|---|---|
No | HTTP 422, "Field required", with |
A typo, such as | HTTP 422, "unknown timezone", with an example of a valid value |
A number, such as | Uses it exactly, with no zone history. |
So the API never fills in a missing time zone for you. The GET /v1/meta route lists what it supports. Today it knows 598 zone names, from the time zone database release tzdata 2026.4.
When is a number the right choice? When the birth record itself states the offset. Then send that number, and the API uses it as given.
What your code should do
Keep the zone name with the place. Your city search should return three things: latitude, longitude and the IANA name. Never keep only an offset for a city, because it changes with the date.
Send the local time, unchanged. Do not convert it to UTC in your own code. Every conversion you write is one more place for the hour to slip.
Handle the two 422s. A time that never happened and a time that happened twice both need the user. Show the message, then ask for the right time, or for "before or after the clocks changed".
Show the offset. Put meta.timezone.abbreviation or offset_hours on the chart screen. A user born in 1944 can then see that war time was applied.
For every field in meta.timezone, see the charts reference.

In every test above, the date, time and city stayed right. Only the offset changed, and the chart changed with it. Send the zone name, read back the offset, and let the user settle the hours that the clocks skipped or doubled.



