How the Spain vacaciones anuales calculator is verified

Inputs

InputFieldType
Days you work per weekdaysPerWeeknumber
Leave year starts (YYYY-MM-DD)leaveYearStartstring
Leave year ends (YYYY-MM-DD)leaveYearEndstring
First day worked in it (YYYY-MM-DD)workStartstring
Last day worked in it (YYYY-MM-DD)workEndstring
Days already takendaysTakennumber

The formula

Each derived value below is computed by the Valem engine from the expression shown, in this order. Nothing else runs — there is no hidden code path.

Derived valueFieldFormula (JSONata)
Year Length DaysyearLengthDays$proRataDays(leaveYearStart, leaveYearEnd)
Present DayspresentDays$proRataDays(workStart, workEnd)
Accrual FractionaccrualFraction($f := presentDays / yearLengthDays; $f > 1 ? 1 : $f)
Calendar Days EntitledcalendarDaysEntitled$const.statutoryCalendarDays * accrualFraction
Days EntitleddaysEntitled$round(calendarDaysEntitled / $const.daysPerCalendarWeek * $n(daysPerWeek), 1)
Days RemainingdaysRemaining($r := daysEntitled - $n(daysTaken); $r < 0 ? 0 : $round($r, 1))

Rates and thresholds

The expressions above read these as $const. They are the figures the annual refresh replaces, so they live as data rather than being written into the formulas — which is what makes a year-on-year change a one-line diff instead of an edit to arithmetic.

ConstantValue
statutoryCalendarDays30
daysPerCalendarWeek7

Test vectors (6)

Every case is executed against this model on each build, by the Java engine and independently by a JavaScript one. A mismatch of a single cent fails the build, so the page cannot ship advertising a figure the model no longer produces.

Case 1 — E1 a full year on a five-day week: 30 calendar days is 21.4 working days, not 30

given daysPerWeek5
given leaveYearStart2026-01-01
given leaveYearEnd2026-12-31
given workStart2026-01-01
given workEnd2026-12-31
given daysTaken0
expect calendarDaysEntitled30
expect daysEntitled21.4

Case 2 — E2 a six-day week gets more working days out of the same 30 calendar ones

given daysPerWeek6
given leaveYearStart2026-01-01
given leaveYearEnd2026-12-31
given workStart2026-01-01
given workEnd2026-12-31
given daysTaken0
expect calendarDaysEntitled30
expect daysEntitled25.7

Case 3 — E3 half a leave year

given daysPerWeek5
given leaveYearStart2026-01-01
given leaveYearEnd2026-12-31
given workStart2026-01-01
given workEnd2026-06-30
given daysTaken0
expect presentDays181
expect yearLengthDays365
expect daysEntitled10.6

Case 4 — E4 a work period wider than the leave year manufactures nothing

given daysPerWeek5
given leaveYearStart2026-01-01
given leaveYearEnd2026-12-31
given workStart2020-01-01
given workEnd2030-12-31
given daysTaken0
expect accrualFraction1
expect daysEntitled21.4

Case 5 — E5 days already taken come off the remainder

given daysPerWeek5
given leaveYearStart2026-01-01
given leaveYearEnd2026-12-31
given workStart2026-01-01
given workEnd2026-12-31
given daysTaken10
expect daysRemaining11.4

Case 6 — E6 taking more than the entitlement never goes negative

given daysPerWeek5
given leaveYearStart2026-01-01
given leaveYearEnd2026-12-31
given workStart2026-01-01
given workEnd2026-12-31
given daysTaken40
expect daysRemaining0

Sources

Check it yourself — and reuse it

The whole model as JSON — inputs, outputs, formulas, vectors and sources in one re-runnable document.

This model is published under CC BY 4.0: use it, adapt it, build on it, with attribution. The licence covers the model — the expression of each rule and the arrangement of the catalog. The rates and thresholds are law, and nobody licenses those; the sources above are where they come from.

← Back to the Spain vacaciones anuales calculator

Built with Valem — a live, verifiable calculator you can fork and embed.