Dev.to WebDev πŸ›  Dev πŸ‘ 0 πŸ“– 4 min read

Counting statute days in JavaScript: security deposit deadlines in five US states

Statutes write deadlines as "within N days", and the two things that trip up code are what counts as a day and what happens when the last day lands on a weekend. Security-deposit return rules for US landlords are a clean

Statutes write deadlines as "within N days", and the two things that trip up code are what counts as a day and what happens when the last day lands on a weekend. Security-deposit return rules for US landlords are a clean example, because five states give five different answers to the same question. This is the date math, plus the traps.

The function

Day 1 is the day after the start date. Optionally skip Saturdays and Sundays. Everything else (time zones, DST) goes away if you work in UTC dates.

function addDays(startISO, n, weekdaysOnly) {
  const [y, m, d] = startISO.split("-").map(Number);
  const t = new Date(Date.UTC(y, m - 1, d));
  for (let i = 0; i < n; ) {
    t.setUTCDate(t.getUTCDate() + 1);
    if (!weekdaysOnly || t.getUTCDay() % 6) i++; // % 6 is 0 on Sunday and Saturday
  }
  return t;
}

Parsing "2026-05-29" with new Date(...) directly would be read as UTC midnight and then printed in local time, which can show the previous day in the Americas. Building the date with Date.UTC and formatting with timeZone: "UTC" avoids that.

Five states, same move-out date

Move-out on Friday, May 29, 2026:

State Rule (as written in the statute) Deadline
California itemized statement within 21 calendar days after the tenant has vacated (Civ. Code 1950.5(h)(1)) Friday, June 19, 2026
Texas refund on or before the 30th day after the tenant surrenders the premises (Prop. Code 92.103(a)) Sunday, June 28, 2026
Florida 15 days to return a deposit with no claim, 30 days to send notice of a claim (Fla. Stat. 83.49(3)) Saturday, June 13 / Sunday, June 28, 2026
Arizona 14 days, excluding Saturdays, Sundays and legal holidays (A.R.S. 33-1321(D)) Thursday, June 18, 2026 (earliest possible, see below)
Michigan notice of damages within 30 days, suit or refund within 45 (MCL 554.609, 554.613) Sunday, June 28 / Monday, July 13, 2026

The traps

1. Weekday-only counting is the exception. Only Arizona's text excludes weekends; the other four have no such exclusion. Arizona skips them, so 14 "days" from May 29 is June 18, not June 12. Reusing a calendar-day function for Arizona gives a deadline six days too early; reusing a weekday function for the others gives one far too late.

2. Holidays are not in the math. Arizona also excludes "other legal holidays", but the Act does not list them. A date picker cannot know which ones apply, so the honest output is "the earliest possible deadline": every holiday inside the window pushes the real one a weekday later, and mailing by the computed date is safe either way. Presenting the number as the deadline would be a bug.

3. Weekend deadlines do not roll to Monday. Several of the examples land on a Saturday or Sunday (Texas June 28, Florida June 13 and 28, Michigan June 28). The California, Texas and Florida texts have no rule moving a weekend deadline to the next business day, so the safe UI behaviour is to warn and say "act the business day before", not to silently show Monday. (I treat Michigan the same way, which is the cautious choice, not a claim about its text.)

4. The start date is the hard part. The statutes count from "the tenant has vacated" (California), "surrenders the premises" (Texas), "termination of the rental agreement" (Florida), "termination of the occupancy" (Michigan). Several do not say whether that is lease end, move-out or key return. Arizona's counts from the last of three events (tenancy terminated, possession delivered, tenant demanded the deposit), and the text does not say whether day 1 is the trigger date or the day after. The function above picks "the day after"; it is a labelled assumption in the tool, not a fact from the statute. When a rule is ambiguous, say which reading the code takes.

5. Two clocks from one date. Florida (15 and 30) and Michigan (30 and 45) run two deadlines from the same trigger, so model a list of rules per state rather than one number:

const MI = [
  { label: "Mail the notice of damages", days: 30 },
  { label: "Sue or return the balance", days: 45 },
];
MI.map(r => addDays("2026-05-29", r.days, false).toUTCString());

A quick test

The cheapest check that catches an off-by-one is a hand-computed table. Mine uses three start dates and all five states, compared against dates counted on a calendar:

const assert = require("node:assert");
assert.equal(addDays("2026-05-29", 21, false).toISOString().slice(0, 10), "2026-06-19");
assert.equal(addDays("2026-05-29", 14, true).toISOString().slice(0, 10), "2026-06-18");

If the weekday case matches by hand, the loop and the % 6 trick are right.

If you just want the dates

I put these rules in five free calculators (no sign-up, runs in the browser, each shows its statute citation and the caveats above): https://hexloomlabs.com/guides/tools/

This is date arithmetic on statute text, not legal advice. Confirm the rule and the start date with the current statute or a local attorney before relying on a deadline.

πŸ“° Read the original article on Dev.to WebDev

Originally published by Dev.to WebDev. Aggregated on AIWithGhost for educational purposes β€” full credit and traffic to the original publisher.