{
  "$comment": "Machine-readable companion to https://valem.run/calculators/slovakia/holiday-entitlement. Formula, inputs, outputs, engine-verified test vectors, cited sources and the re-runnable Valem ModelSpec behind the page.",
  "url": "https://valem.run/calculators/slovakia/holiday-entitlement",
  "dataUrl": "https://valem.run/calculators/slovakia/holiday-entitlement.json",
  "license": {
    "name": "CC BY 4.0",
    "url": "https://creativecommons.org/licenses/by/4.0/",
    "attribution": "Slovakia dovolenka model by Valem (https://valem.run/calculators/slovakia/holiday-entitlement), CC BY 4.0.",
    "note": "Covers the model — the expression of each rule and the arrangement of the catalog. The rates and thresholds themselves are law and are not licensed by anyone; the cited sources are where they come from."
  },
  "verificationUrl": "https://valem.run/calculators/slovakia/holiday-entitlement/verify",
  "country": "slovakia",
  "countryName": "Slovakia",
  "formula": "holiday-entitlement",
  "formulaName": "Dovolenka",
  "title": "Výmera Dovolenky 2026 — Štyri, Päť Alebo Osem Týždnňov",
  "answer": "§ 103 of the Zákonník práce sets a basic four weeks, five weeks for anyone who reaches at least 33 years of age by the end of the calendar year or who permanently cares for a child, and eight weeks for teachers, university lecturers and researchers. On a five-day week that is 20, 25 or 40 days.",
  "lang": "en",
  "currency": "EUR",
  "taxYear": "2026",
  "verification": {
    "claim": "internal-consistency",
    "statement": "The Valem engine reproduces this model's stated formula through 12 self-test cases (below, and re-runnable against the spec). That asserts internal consistency, NOT that the formula matches current law — the cited sources are the evidence for that, and carry the date each was last checked.",
    "selfTestCases": 12,
    "ratesAreIllustrative": false,
    "sourcesCheckedOn": "2026-10-11"
  },
  "sources": [
    {
      "label": "Zákonník práce 311/2001 Z. z. § 103 — slov-lex.sk, consolidation in force from 01.09.2026 (four weeks; five from age 33 or for permanent care of a child; eight for teachers and researchers)",
      "url": "https://www.slov-lex.sk/static/SK/ZZ/2001/311/20260901.html",
      "checked": "2026-10-11"
    },
    {
      "label": "Zákonník práce 311/2001 Z. z. § 101 and § 105 — slov-lex.sk (the 60-day gate, and the twelfth per 21 worked days that applies below it)",
      "url": "https://www.slov-lex.sk/static/SK/ZZ/2001/311/20260901.html",
      "checked": "2026-10-11"
    }
  ],
  "terminalOutput": "daysRemaining",
  "headlineOutput": "daysEntitled",
  "inputs": [
    {
      "name": "daysPerWeek",
      "type": "number",
      "label": "Days you work per week",
      "minimum": 1,
      "maximum": 7
    },
    {
      "name": "ageAtYearEnd",
      "type": "number",
      "label": "Age you reach by the end of this calendar year",
      "minimum": 15,
      "maximum": 100
    },
    {
      "name": "caresForChild",
      "type": "boolean",
      "label": "You permanently care for a child"
    },
    {
      "name": "educationOrResearchRole",
      "type": "boolean",
      "label": "You are a teacher, university lecturer or researcher under § 103(3)"
    },
    {
      "name": "monthsWorked",
      "type": "number",
      "label": "Full calendar months of continuous employment this year",
      "minimum": 0,
      "maximum": 12
    },
    {
      "name": "daysWorkedInYear",
      "type": "number",
      "label": "Days actually worked this year",
      "minimum": 0,
      "maximum": 366
    },
    {
      "name": "daysTaken",
      "type": "number",
      "label": "Days already taken",
      "minimum": 0
    }
  ],
  "outputs": [
    {
      "name": "weeksEntitled",
      "type": "number",
      "formula": "(educationOrResearchRole = true ? $const.weeksEducationResearch : (($n(ageAtYearEnd) >= $const.ageThresholdYears or caresForChild = true) ? $const.weeksFromAgeOrChildCare : $const.baseWeeks))"
    },
    {
      "name": "fullYearDays",
      "type": "number",
      "formula": "weeksEntitled * $n(daysPerWeek)"
    },
    {
      "name": "daysEntitled",
      "type": "number",
      "formula": "($full := fullYearDays; $gate := $n(daysWorkedInYear) >= $const.qualifyingDaysForYearLeave; $m := $clampFloorCap($n(monthsWorked), 0, $const.monthsPerYear); $byMonth := $full * $m / $const.monthsPerYear; $twelfths := $floor($n(daysWorkedInYear) / $const.daysPerTwelfth); $byWorkedDays := $full * $twelfths / $const.monthsPerYear; $raw := $gate ? $byMonth : $byWorkedDays; $round($clampFloorCap($raw, 0, $full), 1))"
    },
    {
      "name": "daysRemaining",
      "type": "number",
      "formula": "($r := daysEntitled - $n(daysTaken); $r < 0 ? 0 : $round($r, 1))"
    }
  ],
  "testCases": [
    {
      "description": "N1 the basic four weeks on a five-day week is 20 days",
      "given": {
        "daysPerWeek": 5,
        "ageAtYearEnd": 30,
        "caresForChild": false,
        "educationOrResearchRole": false,
        "monthsWorked": 12,
        "daysWorkedInYear": 250,
        "daysTaken": 0
      },
      "expect": {
        "weeksEntitled": 4,
        "fullYearDays": 20,
        "daysEntitled": 20
      }
    },
    {
      "description": "N2 reaching 33 by the year end is five weeks, so 25",
      "given": {
        "daysPerWeek": 5,
        "ageAtYearEnd": 33,
        "caresForChild": false,
        "educationOrResearchRole": false,
        "monthsWorked": 12,
        "daysWorkedInYear": 250,
        "daysTaken": 0
      },
      "expect": {
        "weeksEntitled": 5,
        "daysEntitled": 25
      }
    },
    {
      "description": "N3 the band is AT 33, so 32 is still on four weeks",
      "given": {
        "daysPerWeek": 5,
        "ageAtYearEnd": 32,
        "caresForChild": false,
        "educationOrResearchRole": false,
        "monthsWorked": 12,
        "daysWorkedInYear": 250,
        "daysTaken": 0
      },
      "expect": {
        "weeksEntitled": 4,
        "daysEntitled": 20
      }
    },
    {
      "description": "N4 caring for a child gives the same five weeks at any age",
      "given": {
        "daysPerWeek": 5,
        "ageAtYearEnd": 24,
        "caresForChild": true,
        "educationOrResearchRole": false,
        "monthsWorked": 12,
        "daysWorkedInYear": 250,
        "daysTaken": 0
      },
      "expect": {
        "weeksEntitled": 5,
        "daysEntitled": 25
      }
    },
    {
      "description": "N5 a teacher gets eight weeks, which beats the age band rather than adding to it",
      "given": {
        "daysPerWeek": 5,
        "ageAtYearEnd": 40,
        "caresForChild": false,
        "educationOrResearchRole": true,
        "monthsWorked": 12,
        "daysWorkedInYear": 250,
        "daysTaken": 0
      },
      "expect": {
        "weeksEntitled": 8,
        "daysEntitled": 40
      }
    },
    {
      "description": "N6 half a year of employment is six twelfths under § 102",
      "given": {
        "daysPerWeek": 5,
        "ageAtYearEnd": 30,
        "caresForChild": false,
        "educationOrResearchRole": false,
        "monthsWorked": 6,
        "daysWorkedInYear": 125,
        "daysTaken": 0
      },
      "expect": {
        "daysEntitled": 10
      }
    },
    {
      "description": "N7 below § 101's 60 days, § 105 pays per 21 worked days, not per month",
      "given": {
        "daysPerWeek": 5,
        "ageAtYearEnd": 30,
        "caresForChild": false,
        "educationOrResearchRole": false,
        "monthsWorked": 5,
        "daysWorkedInYear": 50,
        "daysTaken": 0
      },
      "expect": {
        "daysEntitled": 3.3
      }
    },
    {
      "description": "N8 at exactly 60 worked days the month rule takes over",
      "given": {
        "daysPerWeek": 5,
        "ageAtYearEnd": 30,
        "caresForChild": false,
        "educationOrResearchRole": false,
        "monthsWorked": 3,
        "daysWorkedInYear": 60,
        "daysTaken": 0
      },
      "expect": {
        "daysEntitled": 5
      }
    },
    {
      "description": "N9 fewer than 21 worked days earns nothing under § 105",
      "given": {
        "daysPerWeek": 5,
        "ageAtYearEnd": 30,
        "caresForChild": false,
        "educationOrResearchRole": false,
        "monthsWorked": 0,
        "daysWorkedInYear": 20,
        "daysTaken": 0
      },
      "expect": {
        "daysEntitled": 0
      }
    },
    {
      "description": "N10 a six-day week gets more days out of the same four weeks",
      "given": {
        "daysPerWeek": 6,
        "ageAtYearEnd": 30,
        "caresForChild": false,
        "educationOrResearchRole": false,
        "monthsWorked": 12,
        "daysWorkedInYear": 300,
        "daysTaken": 0
      },
      "expect": {
        "daysEntitled": 24
      }
    },
    {
      "description": "N11 days already taken come off the remainder",
      "given": {
        "daysPerWeek": 5,
        "ageAtYearEnd": 33,
        "caresForChild": false,
        "educationOrResearchRole": false,
        "monthsWorked": 12,
        "daysWorkedInYear": 250,
        "daysTaken": 10
      },
      "expect": {
        "daysRemaining": 15
      }
    },
    {
      "description": "N12 taking more than the entitlement never goes negative",
      "given": {
        "daysPerWeek": 5,
        "ageAtYearEnd": 30,
        "caresForChild": false,
        "educationOrResearchRole": false,
        "monthsWorked": 12,
        "daysWorkedInYear": 250,
        "daysTaken": 40
      },
      "expect": {
        "daysRemaining": 0
      }
    }
  ],
  "spec": {
    "id": "holiday-entitlement-slovakia",
    "version": "1.0.0",
    "schema": {
      "type": "object",
      "properties": {
        "daysPerWeek": {
          "type": "number",
          "maximum": 7,
          "minimum": 1
        },
        "ageAtYearEnd": {
          "type": "number",
          "maximum": 100,
          "minimum": 15
        },
        "caresForChild": {
          "type": "boolean"
        },
        "educationOrResearchRole": {
          "type": "boolean"
        },
        "monthsWorked": {
          "type": "number",
          "maximum": 12,
          "minimum": 0
        },
        "daysWorkedInYear": {
          "type": "number",
          "maximum": 366,
          "minimum": 0
        },
        "daysTaken": {
          "type": "number",
          "minimum": 0
        },
        "weeksEntitled": {
          "type": "number",
          "readOnly": true
        },
        "fullYearDays": {
          "type": "number",
          "readOnly": true
        },
        "daysEntitled": {
          "type": "number",
          "readOnly": true
        },
        "daysRemaining": {
          "type": "number",
          "readOnly": true
        }
      }
    },
    "constants": {
      "baseWeeks": 4,
      "weeksFromAgeOrChildCare": 5,
      "weeksEducationResearch": 8,
      "ageThresholdYears": 33,
      "qualifyingDaysForYearLeave": 60,
      "daysPerTwelfth": 21,
      "monthsPerYear": 12
    },
    "library": {
      "layers": [
        {
          "id": "statutory",
          "define": "(\n  /* Shared statutory helpers — the canonical copy (docs/sandbox/d8-statutory-families.md §5.4).\n     DO NOT EDIT A SPEC'S INLINED COPY. Edit this file and run `npm run sync:helpers`; a vitest\n     assertion and a Java assertion both require every inlined copy to be byte-identical to this one.\n\n     Why inlined rather than referenced: the `library` section's `ref` form — a library shared\n     between models — is still proposed, gated on the model-references design (see\n     ../../../../docs/design/library/jsonata-library.md). Inlining keeps each spec self-contained,\n     which is what lets `#e=` embedding, `#share=` import and MCP forking work with no resolver.\n\n     TWO TRAPS, both of which fail SILENTLY and both of which bit during the debt-payoff build:\n\n       1. A library function sees ONLY its arguments. It cannot read the consuming document — not\n          through a bare field name, not through `$`, not through `$$`. Everything these helpers\n          need is passed in. (`$const` is late-bound and so would resolve, but relying on it would\n          couple a shared helper to one spec's constant names.)\n       2. ONE null member wrecks a whole aggregate, and the two engines disagree about how. The JS\n          reference implementation THROWS (\"Argument 1 of function sum must be an array of\n          numbers\"); the Java port can instead yield null for the entire aggregate. Neither gives a\n          partial total, and the null-yielding form is the dangerous one because it is silent. So\n          callers coerce with `$n()` below before aggregating, which makes the behaviour identical\n          in both engines — measured, not assumed: see helpers.test.ts.\n\n       3. A PATH STEP DIRECTLY ON A CALL RESULT RETURNS NOTHING in the Java engine. This matters for\n          every caller of $amortize, which is the one helper here returning an object:\n\n              $amortize(p, r, n, 0).months            -> empty in Java, 360 in JS.  WRONG\n              ($a := $amortize(p, r, n, 0); $a.months) -> 360 in both.               RIGHT\n\n          Bind the result to a variable, then step into it. The JS reference accepts both forms, so\n          this is invisible until the page is served by the real engine, and it fails as a blank\n          field rather than an error. Measured with a probe, not inferred — the field simply does\n          not appear. */\n\n  /* Number coercion with an explicit zero default. The guard against trap 2. */\n  $n := function($v) { $v = null or $not($exists($v)) ? 0 : $number($v) };\n\n  /* ISO date -> its year / month / day parts. String slicing rather than $fromMillis formatting:\n     these are statutory dates (\"2026-04-06\"), and a timezone-sensitive round-trip through millis\n     can shift the day, which silently moves a service anniversary across a band boundary. */\n  $isoY := function($d) { $number($substring($d, 0, 4)) };\n  $isoM := function($d) { $number($substring($d, 5, 2)) };\n  $isoD := function($d) { $number($substring($d, 8, 2)) };\n\n  /* Whole years of completed service between two ISO dates. Counts an anniversary as reached only\n     when the month-and-day has arrived, which is what \"completed years of service\" means in every\n     severance statute — not a 365.25-day division, whose drift crosses a 5-year band boundary in\n     the wrong direction roughly one year in four. */\n  $yearsBetween := function($from, $to) { (\n    $y := $isoY($to) - $isoY($from);\n    $beforeAnniversary := $isoM($to) < $isoM($from)\n      or ($isoM($to) = $isoM($from) and $isoD($to) < $isoD($from));\n    $beforeAnniversary ? $y - 1 : $y\n  ) };\n\n  /* Whole completed months between two ISO dates, same convention. */\n  $monthsBetween := function($from, $to) { (\n    $m := ($isoY($to) - $isoY($from)) * 12 + ($isoM($to) - $isoM($from));\n    $isoD($to) < $isoD($from) ? $m - 1 : $m\n  ) };\n\n  /* Inclusive count of days between two ISO dates — both endpoints counted, because a leave year\n     runs from its first day to its last and an employee present on both is present for both.\n     Pro-rata accrual is then $proRataDays(a, b) / $proRataDays(yearStart, yearEnd). */\n  $proRataDays := function($from, $to) {\n    ($toMillis($to) - $toMillis($from)) / 86400000 + 1\n  };\n\n  /* Progressive charge across bands. `$bands` is ordered lowest-first, each {\"upTo\": n, \"rate\": r};\n     the final band's `upTo` is omitted or null to mean \"no ceiling\". Each band's rate applies ONLY\n     to the slice of the amount inside it — the single most common error in a hand-written bracket\n     walk is applying the top rate to the whole amount. Returns 0 for a non-positive amount. */\n  $bandedCharge := function($amount, $bands) { (\n    $a := $n($amount);\n    $a <= 0 ? 0 : $reduce($bands, function($acc, $band) { (\n      $ceiling := $exists($band.upTo) and $band.upTo != null ? $band.upTo : $a;\n      $top := $ceiling < $a ? $ceiling : $a;\n      $slice := $top - $acc.floor;\n      {\n        \"floor\": $top > $acc.floor ? $top : $acc.floor,\n        \"charge\": $acc.charge + ($slice > 0 ? $slice * $n($band.rate) : 0)\n      }\n    ) }, {\"floor\": 0, \"charge\": 0}).charge\n  ) };\n\n  /* Clamp into [floor, cap]. Either bound may be omitted (null) to leave that side open — a benefit\n     with a cap and no floor is as common as one with both. */\n  $clampFloorCap := function($value, $floor, $cap) { (\n    $v := $n($value);\n    $withFloor := $exists($floor) and $floor != null and $v < $floor ? $floor : $v;\n    $exists($cap) and $cap != null and $withFloor > $cap ? $cap : $withFloor\n  ) };\n\n  /* Level annuity payment for a principal over `$months` at `$annualRatePct` nominal, compounded\n     monthly. Falls back to straight-line division at a zero rate, where the standard formula\n     divides by zero. */\n  $annuityPayment := function($principal, $annualRatePct, $months) { (\n    $p := $n($principal);\n    $m := $n($months);\n    $i := $n($annualRatePct) / 1200;\n    $m <= 0 ? 0 : ($i = 0 ? $p / $m : $p * $i * $power(1 + $i, $m) / ($power(1 + $i, $m) - 1))\n  ) };\n\n  /* Amortisation schedule: one row per month until the balance clears or `$months` is reached.\n     Returns {\"payment\", \"months\", \"totalInterest\", \"schedule\": [{month, interest, principal,\n     balance}]}. `$extra` is an optional monthly overpayment.\n\n     A real month-by-month fold rather than a closed form, because an overpayment changes every\n     later row — the same reason debt-payoff simulates. Bounded by `$months`, so it always\n     terminates. */\n  $amortize := function($principal, $annualRatePct, $months, $extra) { (\n    $i := $n($annualRatePct) / 1200;\n    $pay := $annuityPayment($principal, $annualRatePct, $months) + $n($extra);\n    $r := $reduce([1..$n($months)], function($acc, $month) {\n      $acc.balance <= 0 ? $acc : (\n        /* The running balance is kept UNROUNDED and only the emitted row is rounded. Rounding the\n           balance each month instead accumulates drift: at 200,000 over 360 months it left 2.83\n           still owing in the final row, which would break the \"final balance is zero\" invariant\n           (§7.3) and look to a reader like the schedule does not pay the loan off. Lenders compute\n           on the exact balance and adjust the last payment, which is what this does. */\n        $interest := $acc.balance * $i;\n        $due := $acc.balance + $interest < $pay ? $acc.balance + $interest : $pay;\n        $principalPart := $due - $interest;\n        $balance := $acc.balance - $principalPart;\n        {\n          \"balance\": $balance,\n          \"totalInterest\": $acc.totalInterest + $interest,\n          \"schedule\": $append($acc.schedule, [{\n            \"month\": $month,\n            \"interest\": $round($interest, 2),\n            \"principal\": $round($principalPart, 2),\n            \"balance\": $round($balance, 2)\n          }])\n        }\n      )\n    }, {\"balance\": $n($principal), \"totalInterest\": 0, \"schedule\": []});\n    {\n      \"payment\": $round($pay, 2),\n      \"months\": $count($r.schedule),\n      \"totalInterest\": $round($r.totalInterest, 2),\n      \"schedule\": [$r.schedule]\n    }\n  ) };\n\n  [\"n\", \"isoY\", \"isoM\", \"isoD\", \"yearsBetween\", \"monthsBetween\", \"proRataDays\",\n   \"bandedCharge\", \"clampFloorCap\", \"annuityPayment\", \"amortize\"]\n)\n"
        }
      ]
    },
    "defaultValues": [
      {
        "path": "$",
        "expr": "{ 'daysPerWeek': 5, 'ageAtYearEnd': 30, 'caresForChild': false, 'educationOrResearchRole': false, 'monthsWorked': 12, 'daysWorkedInYear': 250, 'daysTaken': 0 }"
      }
    ],
    "derivations": [
      {
        "path": "$.weeksEntitled",
        "expr": "(educationOrResearchRole = true ? $const.weeksEducationResearch : (($n(ageAtYearEnd) >= $const.ageThresholdYears or caresForChild = true) ? $const.weeksFromAgeOrChildCare : $const.baseWeeks))"
      },
      {
        "path": "$.fullYearDays",
        "expr": "weeksEntitled * $n(daysPerWeek)"
      },
      {
        "path": "$.daysEntitled",
        "expr": "($full := fullYearDays; $gate := $n(daysWorkedInYear) >= $const.qualifyingDaysForYearLeave; $m := $clampFloorCap($n(monthsWorked), 0, $const.monthsPerYear); $byMonth := $full * $m / $const.monthsPerYear; $twelfths := $floor($n(daysWorkedInYear) / $const.daysPerTwelfth); $byWorkedDays := $full * $twelfths / $const.monthsPerYear; $raw := $gate ? $byMonth : $byWorkedDays; $round($clampFloorCap($raw, 0, $full), 1))"
      },
      {
        "path": "$.daysRemaining",
        "expr": "($r := daysEntitled - $n(daysTaken); $r < 0 ? 0 : $round($r, 1))"
      }
    ],
    "constraints": [],
    "viewDefinition": {
      "renderer": "builtin",
      "defaultView": "main",
      "views": [
        {
          "id": "main",
          "label": "Dovolenka",
          "layout": "vertical",
          "components": [
            {
              "id": "note",
              "type": "staticText",
              "text": "§ 103 Zákonníka práce: “Základná výmera dovolenky je najmenej štyri týždne.” Then two steps up, and they are unusually wide. Anyone who reaches at least 33 years of age by the end of the calendar year, or who permanently cares for a child, gets five weeks; teachers, university lecturers and researchers get eight. On a five-day week that is 20, 25 or 40 days — the widest spread of any country in this comparison, and the 40 is the largest figure anywhere in it."
            },
            {
              "id": "inputs",
              "type": "fieldSet",
              "label": "Vaše údaje",
              "components": [
                {
                  "id": "daysPerWeek",
                  "type": "numericField",
                  "label": "Days you work per week",
                  "bind": "$.daysPerWeek",
                  "helperText": "§ 103 counts in weeks, so your own week sets the day count."
                },
                {
                  "id": "ageAtYearEnd",
                  "type": "numericField",
                  "label": "Age you reach by the end of this calendar year",
                  "bind": "$.ageAtYearEnd",
                  "helperText": "§ 103(2) measures it “do konca príslušného kalendárneho roka”, so turning 33 in December gives you five weeks for the whole year."
                },
                {
                  "id": "caresForChild",
                  "type": "checkboxField",
                  "label": "You permanently care for a child",
                  "bind": "$.caresForChild",
                  "helperText": "§ 103(2) gives the same five weeks at any age."
                },
                {
                  "id": "educationOrResearchRole",
                  "type": "checkboxField",
                  "label": "You are a teacher, university lecturer or researcher under § 103(3)",
                  "bind": "$.educationOrResearchRole",
                  "helperText": "Eight weeks. § 103(3) lists the roles exactly; this is a declaration, not a job classifier."
                },
                {
                  "id": "monthsWorked",
                  "type": "numericField",
                  "label": "Full calendar months of continuous employment this year",
                  "bind": "$.monthsWorked",
                  "helperText": "§ 102: one twelfth of the year's leave for each one."
                },
                {
                  "id": "daysWorkedInYear",
                  "type": "numericField",
                  "label": "Days actually worked this year",
                  "bind": "$.daysWorkedInYear",
                  "helperText": "§ 101's gate is 60. Below it a different rule applies — § 105's twelfth per 21 worked days."
                },
                {
                  "id": "daysTaken",
                  "type": "numericField",
                  "label": "Days already taken",
                  "bind": "$.daysTaken"
                }
              ]
            },
            {
              "id": "sep",
              "type": "separatorLine"
            },
            {
              "id": "entitledTile",
              "type": "statTile",
              "label": "Days entitled",
              "value": "$.daysEntitled"
            },
            {
              "id": "remainingTile",
              "type": "statTile",
              "label": "Days remaining",
              "value": "$.daysRemaining"
            },
            {
              "id": "breakdown",
              "type": "keyValueList",
              "label": "How that is worked out",
              "items": [
                {
                  "label": "Weeks of leave (§ 103)",
                  "value": "$.weeksEntitled"
                },
                {
                  "label": "A full year on your week",
                  "value": "$.fullYearDays"
                }
              ]
            },
            {
              "id": "assumptions",
              "type": "staticText",
              "text": "The 60-day gate in § 101 is a branch, not a rounding: above it § 102 gives a twelfth per full calendar month of employment, and below it § 101's entitlement does not arise at all, so § 105 substitutes a twelfth per 21 days actually worked. Fifty worked days spread over five months is two twelfths, not five. Two rules this page states and does not compute: § 103(2)'s second sentence pro-rates the increase over four weeks for someone who starts or stops caring for a child part-way through the year, by days of care over days in the year; and § 106's dodatková dovolenka adds a week for named hazardous work. § 104 and § 104a change what a leave DAY means for uneven and flexible working time — under § 104a an employee is assessed “akoby pracoval päť dní v týždni” — and neither is modelled. Collective agreements may improve on all of it."
            },
            {
              "id": "sources",
              "type": "sourceList",
              "label": "Zdroje",
              "layers": 1,
              "exempt": [
                "monthsPerYear"
              ],
              "items": [
                {
                  "label": "Zákonník práce 311/2001 Z. z. § 103 — slov-lex.sk, consolidation in force from 01.09.2026 (four weeks; five from age 33 or for permanent care of a child; eight for teachers and researchers)",
                  "url": "https://www.slov-lex.sk/static/SK/ZZ/2001/311/20260901.html",
                  "date": "2026-10-11",
                  "covers": [
                    "baseWeeks",
                    "weeksFromAgeOrChildCare",
                    "weeksEducationResearch",
                    "ageThresholdYears"
                  ]
                },
                {
                  "label": "Zákonník práce 311/2001 Z. z. § 101 and § 105 — slov-lex.sk (the 60-day gate, and the twelfth per 21 worked days that applies below it)",
                  "url": "https://www.slov-lex.sk/static/SK/ZZ/2001/311/20260901.html",
                  "date": "2026-10-11",
                  "covers": [
                    "qualifyingDaysForYearLeave",
                    "daysPerTwelfth"
                  ]
                }
              ]
            }
          ]
        }
      ]
    },
    "tests": [
      {
        "description": "N1 the basic four weeks on a five-day week is 20 days",
        "given": {
          "$.daysPerWeek": 5,
          "$.ageAtYearEnd": 30,
          "$.caresForChild": false,
          "$.educationOrResearchRole": false,
          "$.monthsWorked": 12,
          "$.daysWorkedInYear": 250,
          "$.daysTaken": 0
        },
        "expect": {
          "$.weeksEntitled": 4,
          "$.fullYearDays": 20,
          "$.daysEntitled": 20
        }
      },
      {
        "description": "N2 reaching 33 by the year end is five weeks, so 25",
        "given": {
          "$.daysPerWeek": 5,
          "$.ageAtYearEnd": 33,
          "$.caresForChild": false,
          "$.educationOrResearchRole": false,
          "$.monthsWorked": 12,
          "$.daysWorkedInYear": 250,
          "$.daysTaken": 0
        },
        "expect": {
          "$.weeksEntitled": 5,
          "$.daysEntitled": 25
        }
      },
      {
        "description": "N3 the band is AT 33, so 32 is still on four weeks",
        "given": {
          "$.daysPerWeek": 5,
          "$.ageAtYearEnd": 32,
          "$.caresForChild": false,
          "$.educationOrResearchRole": false,
          "$.monthsWorked": 12,
          "$.daysWorkedInYear": 250,
          "$.daysTaken": 0
        },
        "expect": {
          "$.weeksEntitled": 4,
          "$.daysEntitled": 20
        }
      },
      {
        "description": "N4 caring for a child gives the same five weeks at any age",
        "given": {
          "$.daysPerWeek": 5,
          "$.ageAtYearEnd": 24,
          "$.caresForChild": true,
          "$.educationOrResearchRole": false,
          "$.monthsWorked": 12,
          "$.daysWorkedInYear": 250,
          "$.daysTaken": 0
        },
        "expect": {
          "$.weeksEntitled": 5,
          "$.daysEntitled": 25
        }
      },
      {
        "description": "N5 a teacher gets eight weeks, which beats the age band rather than adding to it",
        "given": {
          "$.daysPerWeek": 5,
          "$.ageAtYearEnd": 40,
          "$.caresForChild": false,
          "$.educationOrResearchRole": true,
          "$.monthsWorked": 12,
          "$.daysWorkedInYear": 250,
          "$.daysTaken": 0
        },
        "expect": {
          "$.weeksEntitled": 8,
          "$.daysEntitled": 40
        }
      },
      {
        "description": "N6 half a year of employment is six twelfths under § 102",
        "given": {
          "$.daysPerWeek": 5,
          "$.ageAtYearEnd": 30,
          "$.caresForChild": false,
          "$.educationOrResearchRole": false,
          "$.monthsWorked": 6,
          "$.daysWorkedInYear": 125,
          "$.daysTaken": 0
        },
        "expect": {
          "$.daysEntitled": 10
        }
      },
      {
        "description": "N7 below § 101's 60 days, § 105 pays per 21 worked days, not per month",
        "given": {
          "$.daysPerWeek": 5,
          "$.ageAtYearEnd": 30,
          "$.caresForChild": false,
          "$.educationOrResearchRole": false,
          "$.monthsWorked": 5,
          "$.daysWorkedInYear": 50,
          "$.daysTaken": 0
        },
        "expect": {
          "$.daysEntitled": 3.3
        }
      },
      {
        "description": "N8 at exactly 60 worked days the month rule takes over",
        "given": {
          "$.daysPerWeek": 5,
          "$.ageAtYearEnd": 30,
          "$.caresForChild": false,
          "$.educationOrResearchRole": false,
          "$.monthsWorked": 3,
          "$.daysWorkedInYear": 60,
          "$.daysTaken": 0
        },
        "expect": {
          "$.daysEntitled": 5
        }
      },
      {
        "description": "N9 fewer than 21 worked days earns nothing under § 105",
        "given": {
          "$.daysPerWeek": 5,
          "$.ageAtYearEnd": 30,
          "$.caresForChild": false,
          "$.educationOrResearchRole": false,
          "$.monthsWorked": 0,
          "$.daysWorkedInYear": 20,
          "$.daysTaken": 0
        },
        "expect": {
          "$.daysEntitled": 0
        }
      },
      {
        "description": "N10 a six-day week gets more days out of the same four weeks",
        "given": {
          "$.daysPerWeek": 6,
          "$.ageAtYearEnd": 30,
          "$.caresForChild": false,
          "$.educationOrResearchRole": false,
          "$.monthsWorked": 12,
          "$.daysWorkedInYear": 300,
          "$.daysTaken": 0
        },
        "expect": {
          "$.daysEntitled": 24
        }
      },
      {
        "description": "N11 days already taken come off the remainder",
        "given": {
          "$.daysPerWeek": 5,
          "$.ageAtYearEnd": 33,
          "$.caresForChild": false,
          "$.educationOrResearchRole": false,
          "$.monthsWorked": 12,
          "$.daysWorkedInYear": 250,
          "$.daysTaken": 10
        },
        "expect": {
          "$.daysRemaining": 15
        }
      },
      {
        "description": "N12 taking more than the entitlement never goes negative",
        "given": {
          "$.daysPerWeek": 5,
          "$.ageAtYearEnd": 30,
          "$.caresForChild": false,
          "$.educationOrResearchRole": false,
          "$.monthsWorked": 12,
          "$.daysWorkedInYear": 250,
          "$.daysTaken": 40
        },
        "expect": {
          "$.daysRemaining": 0
        }
      }
    ]
  }
}
