Working with dates and time
Date arithmetic looks trivial and is not, because the calendar is a set of conventions rather than a measuring system. Months have no fixed length, offsets change by legislation, and two hours each year are either missing or duplicated. Most scheduling and payroll bugs come from one of these.
Days are exact, months are not
The interval between two dates in days is unambiguous: convert both to a day number and subtract. Month lengths and leap years take care of themselves.
Months have no fixed length, so there is no single correct month count. From 31 January to 28 February is 28 days — one month, or 0.93 of one? Both readings are defensible. Calendar counting increments when the day-of-month is reached, so 15 January to 15 March is exactly two months. Average-length counting divides days by 30.44, the mean Gregorian month, which suits statistics and not anniversaries.
Years work the same way, using 365.2425 days as the mean. This is why an age computed by division can differ by a day from the calendar answer around a birthday, and why financial and legal documents specify their day-count convention rather than leaving it to inference.
The Gregorian leap rule is worth knowing precisely: years divisible by 4, except those divisible by 100, unless also divisible by 400. So 2000 was a leap year and 1900 was not. The correction brings the average year to 365.2425 days against a tropical year of 365.2422, accurate to about a day in 3,200 years.
Inclusive and exclusive counting
Subtracting two dates gives the exclusive count — day boundaries crossed. From 1 March to 5 March is 4.
Counting days of a hotel stay, an event, or a rental usually wants the inclusive count of 5, because both endpoints are days you pay for. Adding one converts between them.
Which is right is entirely domain-specific, and getting it wrong is an off-by-one that survives inspection because both answers look reasonable. Hotel nights are exclusive: Monday check-in to Friday check-out is four nights. Conference days are inclusive. Legal deadlines follow their own rule, commonly excluding the first day, including the last, and extending to the next working day when the deadline falls on a weekend or holiday.
Business days add another layer. The base calculation is full weeks times five plus weekdays in the partial week, but holidays are jurisdiction-specific and calendars disagree — financial markets, courts, and banks each maintain their own. A settlement period in business days depends on which calendar governs, which is why cross-border contracts specify it.
An offset is not a time zone
This distinction is behind most scheduling errors. An offset such as UTC−5 is a fact about one instant. A time zone such as America/New_York is a set of rules producing the correct offset for any instant, including historical changes and future transitions.
New York is UTC−5 in winter and UTC−4 in summer, so storing −5 as a property of a New York meeting is correct for about a third of the year. The bug surfaces at the transition as recurring meetings that shift by an hour for some participants and not others.
Offsets also change by political decision. Countries have moved zones, abolished daylight saving, and altered transition dates with weeks of notice. Any future-dated time stored as an offset is a bet on legislation. Store UTC plus a zone identifier for anything recurring or scheduled ahead; use an offset only for a timestamp that has already occurred.
Not all offsets are whole hours, and a surprising amount of code assumes they are. India is UTC+5:30, Nepal UTC+5:45, the Chatham Islands UTC+12:45. Offsets span UTC−12 to UTC+14, a 26-hour range, which means three calendar dates can be in progress at once.
The two broken hours
When clocks go forward, a local hour ceases to exist. In a zone shifting at 2 am, the time 2:30 am never occurs on that date. A validator that accepts it produces an invalid instant, and a job scheduled for it either runs at a different time or not at all.
When clocks go back, a local hour occurs twice, an hour apart in real time. A local timestamp in that hour is genuinely ambiguous and cannot be resolved to an instant without additional information.
The results are predictable and annual: duplicate transaction records, jobs that run twice or skip, and shift durations computed an hour out. Southern hemisphere zones transition at the opposite time of year, so code that handles one hemisphere can fail on the other.
The reliable defence is to schedule in UTC and convert only for display. It is also worth noting that transition dates differ between regions — the United States and Europe change on different weekends, so the New York to London gap is five hours for most of the year and four for a couple of weeks each spring and autumn.
For communication across zones: state the zone by city name or IANA identifier rather than abbreviation, since CST means both North American Central and China Standard Time and IST means Indian, Irish, and Israeli. Prefer 24-hour notation, and quote UTC alongside local time for anything important.
Time arithmetic for payroll
Payroll runs on decimal hours while clocks run on base 60, and the conversion is where timecard errors originate. Seven hours 45 minutes is 7.75 hours; writing 7.45 is a 0.30 hour error per entry. Divide minutes by 60: 15 is 0.25, 30 is 0.50, 45 is 0.75.
Overtime under the United States Fair Labor Standards Act is per workweek, not per pay period. Fifty hours one week and thirty the next is 80 total and ten hours of overtime, not zero — averaging across weeks is not permitted and is a common source of back-pay claims. Some states add daily overtime; California pays time and a half over eight hours and double time over twelve.
The overtime rate is based on the regular rate of pay, which includes non-discretionary bonuses, shift differentials, and commissions rather than just the base wage. Computing overtime on the base rate alone underpays anyone with a production bonus.
Rounding to quarter-hour increments is federally permitted if neutral over time. The seven-minute rule — minutes 1 to 7 round down, 8 to 14 round up — implements that neutrality. One-directional rounding is systematic underpayment and has produced substantial class actions, and some jurisdictions now disallow rounding entirely where an electronic system records exact minutes.
Finally, short rest breaks of 20 minutes or less are compensable work time and cannot be deducted. Only bona fide meal periods, normally 30 minutes with the employee fully relieved of duty, may be unpaid — and a meal break interrupted by work is not one.
Frequently asked questions
Why is a month count approximate?
Because months are 28 to 31 days, so there is no single correct answer. Average-length counting uses 30.44 days; calendar counting increments on the day-of-month.
Should I count inclusively or exclusively?
Depends on the domain. Hotel nights are exclusive, conference days inclusive. Subtraction gives the exclusive count; add one for inclusive.
Why does storing a UTC offset cause bugs?
Because the offset for a location changes with daylight saving and by legislation. Store UTC plus a zone identifier for anything recurring or future-dated.
How do I convert minutes to decimal hours?
Divide by 60. Forty-five minutes is 0.75 hours, not 0.45.
Can overtime be averaged over two weeks?
No. Overtime is calculated per workweek. Fifty hours followed by thirty is ten hours of overtime even though the total is 80.