{
  "schemaVersion": 1,
  "slug": "work-days-calculator",
  "category": "date-time",
  "kind": "implementation",
  "independentValidation": false,
  "implementationHash": "627f5e1112c05e6b74efe66979ddfa4a557bd49e91a61ad540b03dd00beb7764",
  "provenance": "Generated from the calculation contract used by the published page. Publication is not external validation.",
  "sourceFiles": [
    "data/calculators/work-days-calculator.json",
    "src/engine.js"
  ],
  "runtimeSource": "/sources/engine.txt",
  "runtimeHash": "5c888d8898afbdee36267bb9977829e1e2ac568f6677c8ee87469c139864645c",
  "scope": "The compute function records implemented equations, constants, lookup tables and custom rules. Inputs record defaults and allowed values; outputs record precision and units. Defaults are examples, not recommendations. General background references are not evidence for this specific algorithm.",
  "publishedFormula": {
    "formula": "N = counted weekdays − min(holiday count, counted weekdays); hours = N×hours/day; weeks = N/5",
    "vars": [
      [
        "span",
        "Days between the dates"
      ],
      [
        "workdays",
        "Allowed weekdays"
      ],
      [
        "holidays",
        "Holidays to subtract"
      ],
      [
        "e",
        "End-date flag (0 or 1)"
      ],
      [
        "wd",
        "Working days"
      ],
      [
        "hours",
        "Hours per work day"
      ]
    ],
    "note": "The loop counts weekdays (Monday–Friday) between the dates; the start is included and the end is included only when selected. Enter the number of public holidays that fall on counted weekdays; the value is capped at the weekday count. Hours = working days×hours/day; weeks = working days÷5; weekly average is undefined for a zero-day interval."
  },
  "externalEvidence": {
    "reviewedAt": "2026-10-12",
    "sources": [
      {
        "name": "MDN — Date and UTC calendar operations",
        "url": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date"
      }
    ],
    "referenceRole": "definition",
    "implementationHash": "627f5e1112c05e6b74efe66979ddfa4a557bd49e91a61ad540b03dd00beb7764",
    "basis": "N = counted weekdays − min(holiday count, counted weekdays); hours = N×hours/day; weeks = N/5",
    "limitations": "The references explain definitions and methods; any extra preset must be checked against the assumptions on this page."
  },
  "contract": {
    "compute": "const validDate=s=>{const m=/^(\\d{4})-(\\d{2})-(\\d{2})$/.exec(String(s));if(!m)return false;const d=new Date(s+'T00:00:00Z');return Number.isFinite(d.getTime())&&d.getUTCFullYear()===+m[1]&&d.getUTCMonth()+1===+m[2]&&d.getUTCDate()===+m[3];};if(!validDate(startDate)||!validDate(endDate)) return {calendarDays:null,workingDays:null,excludedDays:null,workingHours:null,workingWeeks:null,endDateResult:null,averagePerWeek:null,__error:'inputError'};const a=new Date(startDate+'T00:00:00Z'),b=new Date(endDate+'T00:00:00Z'),span=Math.abs((b-a)/86400000),dir=b>=a?1:-1,calendarDays=span+(includeEndDate==='yes'?1:0);let weekdays=0;for(let k=0;k<calendarDays;k++){const dow=new Date(a.getTime()+dir*k*86400000).getUTCDay();if(dow!==0&&dow!==6)weekdays++;}const holidayWeekdays=Math.min(weekdays,Math.max(0,Math.floor(holidays))),workingDays=weekdays-holidayWeekdays;return {calendarDays,workingDays,excludedDays:calendarDays-workingDays,workingHours:workingDays*hoursPerDay,workingWeeks:workingDays/5,endDateResult:endDate,averagePerWeek:calendarDays>0?workingDays/(calendarDays/7):null};",
    "inputs": [
      {
        "name": "startDate",
        "type": "date",
        "default": "@today",
        "step": 1
      },
      {
        "name": "endDate",
        "type": "date",
        "default": "@today+3m",
        "step": 1
      },
      {
        "name": "holidays",
        "type": "number",
        "default": 4,
        "min": 0,
        "max": 100,
        "step": 1,
        "slider": true
      },
      {
        "name": "includeEndDate",
        "type": "select",
        "default": "no",
        "options": [
          {
            "value": "no"
          },
          {
            "value": "yes"
          }
        ]
      },
      {
        "name": "hoursPerDay",
        "type": "number",
        "default": 8,
        "min": 0,
        "max": 24,
        "step": 0.5,
        "slider": true
      }
    ],
    "outputs": [
      {
        "name": "workingDays",
        "precision": 0,
        "unit": "days"
      },
      {
        "name": "calendarDays",
        "precision": 0,
        "unit": "days"
      },
      {
        "name": "excludedDays",
        "precision": 0,
        "unit": "days"
      },
      {
        "name": "workingHours",
        "precision": 0,
        "unit": "hours"
      },
      {
        "name": "workingWeeks",
        "precision": 2,
        "unit": "weeks"
      },
      {
        "name": "endDateResult",
        "precision": 0,
        "unit": "",
        "type": "text"
      },
      {
        "name": "averagePerWeek",
        "precision": 2,
        "unit": "days"
      }
    ],
    "interpret": null
  }
}
