{
  "schemaVersion": 1,
  "slug": "freezer-storage-time-calculator",
  "category": "cooking",
  "kind": "implementation",
  "independentValidation": false,
  "implementationHash": "40b5c03c5730405bd856769b10f0b637054f9ec46a0fe6513a70d6d277725908",
  "provenance": "Generated from the calculation contract used by the published page. Publication is not external validation.",
  "sourceFiles": [
    "data/calculators/freezer-storage-time-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": "useBy = freezeDate ⊕ m; daysRemaining = (useBy - today) / 86400000; stillGood <=> daysRemaining ≥ 0",
    "vars": [
      [
        "m",
        "storage months (food table)"
      ],
      [
        "freezeDate",
        "freeze date"
      ],
      [
        "useBy",
        "best-quality end date"
      ],
      [
        "daysRemaining",
        "days left (negative = past)"
      ],
      [
        "⊕",
        "calendar-month addition"
      ],
      [
        "today",
        "current date"
      ]
    ],
    "note": "Food windows are approximate quality estimates, not safety limits; assume continuously frozen at 0°F (-18°C) or below. Invalid or future freeze dates are rejected. Calendar-month endpoints are clamped to the last valid day."
  },
  "externalEvidence": null,
  "contract": {
    "compute": "const invalid=()=>({months:null,useByDate:null,daysRemaining:null,stillGood:null,__error:'inputError'}); if(typeof freezeDate!=='string'||!/^\\d{4}-\\d{2}-\\d{2}$/.test(freezeDate))return invalid(); const frozen=new Date(freezeDate+'T00:00:00Z'); if(!Number.isFinite(frozen.getTime())||frozen.toISOString().slice(0,10)!==freezeDate)return invalid(); const localNow=new Date(); const now=new Date(Date.UTC(localNow.getFullYear(),localNow.getMonth(),localNow.getDate())); if(frozen>now)return invalid(); const M={beef:12,ground:4,pork:6,chicken:9,fish:3,leanfish:6,soup:3,casserole:3,bread:3,berries:12,vegetables:12,butter:9}; const months=M[food]||6; const targetMonth=frozen.getUTCMonth()+months; const year=frozen.getUTCFullYear()+Math.floor(targetMonth/12); const month=((targetMonth%12)+12)%12; const day=Math.min(frozen.getUTCDate(),new Date(Date.UTC(year,month+1,0)).getUTCDate()); const useBy=new Date(Date.UTC(year,month,day)); const days=Math.round((useBy-now)/86400000); return {months,useByDate:useBy.toISOString().slice(0,10),daysRemaining:days,stillGood:days>=0?'Yes':'Past best quality'};",
    "inputs": [
      {
        "name": "food",
        "type": "select",
        "default": "beef",
        "options": [
          {
            "value": "beef"
          },
          {
            "value": "ground"
          },
          {
            "value": "pork"
          },
          {
            "value": "chicken"
          },
          {
            "value": "fish"
          },
          {
            "value": "leanfish"
          },
          {
            "value": "soup"
          },
          {
            "value": "casserole"
          },
          {
            "value": "bread"
          },
          {
            "value": "berries"
          },
          {
            "value": "vegetables"
          },
          {
            "value": "butter"
          }
        ]
      },
      {
        "name": "freezeDate",
        "type": "date",
        "default": "@today",
        "step": 1
      }
    ],
    "outputs": [
      {
        "name": "months",
        "precision": 0,
        "unit": "months"
      },
      {
        "name": "useByDate",
        "precision": 0,
        "unit": "",
        "type": "text"
      },
      {
        "name": "daysRemaining",
        "precision": 0,
        "unit": "days"
      },
      {
        "name": "stillGood",
        "precision": 0,
        "unit": "",
        "type": "text"
      }
    ],
    "interpret": null
  }
}
