{
  "schemaVersion": 1,
  "slug": "epoch-converter",
  "category": "date-time",
  "kind": "implementation",
  "independentValidation": false,
  "implementationHash": "b850a6f788878a30063d5a9316502628cb3e37c0efef1b887d93896f9f9db438",
  "provenance": "Generated from the calculation contract used by the published page. Publication is not external validation.",
  "sourceFiles": [
    "data/calculators/epoch-converter.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": "t_s = ⌊t_ms ÷ 1000⌋; t_ms = 1000 × t_s",
    "vars": [
      [
        "t_ms",
        "Epoch milliseconds"
      ],
      [
        "t_s",
        "Unix time (seconds)"
      ]
    ],
    "note": "Second inputs are multiplied by 1000. Relative time is rule-based: <60 s seconds, <60 min minutes, <24 h hours, <30 days days, <12 months months, else years; day of year counted from Jan 1."
  },
  "externalEvidence": null,
  "contract": {
    "compute": "const mergedResult=(()=>{if((true&&![\"timestamp\", \"date\", \"calendar\"].includes(String(mode)))||([\"timestamp\"].includes(String(mode))&&![\"no\", \"yes\"].includes(String(milliseconds))))return{__error:'inputError'};\nif(([\"timestamp\"].includes(String(mode))&&(!Number.isFinite(timestamp)||timestamp<-8640000000000000||timestamp>8640000000000000))||(true&&(!Number.isFinite(timezoneOffset)||timezoneOffset<-14||timezoneOffset>14))||([\"calendar\"].includes(String(mode))&&(!Number.isFinite(hour)||hour<0||hour>23))||([\"calendar\"].includes(String(mode))&&(!Number.isFinite(minute)||minute<0||minute>59)))return{__error:'inputError'};\nconst wd=['Sunday','Monday','Tuesday','Wednesday','Thursday','Friday','Saturday'];const bad={unixSeconds:null,unixMilliseconds:null,utcDate:null,localDate:null,weekday:null,relative:null,dayOfYear:null,year:null,daysSinceEpoch:null,__error:'inputError'};\nlet ms;if(mode==='timestamp'){if(!['yes','no'].includes(milliseconds)||!Number.isSafeInteger(timestamp))return bad;ms=milliseconds==='yes'?timestamp:timestamp*1000;}else if(mode==='date'){if(!/(?:Z|[+-]\\d{2}:?\\d{2})$/i.test(String(date)))return bad;const day=String(date).slice(0,10),check=new Date(day+'T00:00:00Z');if(!Number.isFinite(check.getTime())||check.toISOString().slice(0,10)!==day)return bad;ms=Date.parse(date);}else if(mode==='calendar'){const d=new Date(calendarDate+'T00:00:00Z');if(!/^\\d{4}-\\d{2}-\\d{2}$/.test(calendarDate)||!Number.isFinite(d.getTime())||d.toISOString().slice(0,10)!==calendarDate||!Number.isInteger(hour)||hour<0||hour>23||!Number.isInteger(minute)||minute<0||minute>59)return bad;ms=d.getTime()+(hour*60+minute)*60000;}else return bad;\nif(!Number.isFinite(ms)||Math.abs(ms)>8640000000000000-14*3600000||!Number.isFinite(timezoneOffset)||timezoneOffset<-14||timezoneOffset>14)return bad;const d=new Date(ms),local=new Date(ms+timezoneOffset*3600000);\nconst diff = (ms - Date.now())/1000; const abs = Math.abs(diff); const unit = abs < 60 ? Math.round(abs) + ' seconds' : abs < 3600 ? Math.round(abs/60) + ' minutes' : abs < 86400 ? Math.round(abs/3600) + ' hours' : abs < 2592000 ? Math.round(abs/86400) + ' days' : abs < 31536000 ? Math.round(abs/2592000) + ' months' : Math.round(abs/31536000) + ' years'; const start=new Date(0);start.setUTCFullYear(d.getUTCFullYear(),0,1);start.setUTCHours(0,0,0,0);return{unixSeconds:Math.floor(ms/1000),unixMilliseconds:ms,utcDate:d.toISOString().replace('.000Z','Z'),localDate:local.toISOString().slice(0,19).replace('T',' '),weekday:wd[d.getUTCDay()],relative:diff>=0?'In '+unit:unit+' ago',dayOfYear:Math.floor((ms-start)/86400000)+1,year:d.getUTCFullYear(),daysSinceEpoch:Math.floor(ms/86400000)};\n})();return mergedResult.__error?{\"unixSeconds\":null,\"unixMilliseconds\":null,\"utcDate\":null,\"localDate\":null,\"weekday\":null,\"relative\":null,\"dayOfYear\":null,\"year\":null,\"daysSinceEpoch\":null,...mergedResult}:mergedResult;",
    "inputs": [
      {
        "name": "mode",
        "type": "select",
        "default": "timestamp",
        "options": [
          {
            "value": "timestamp"
          },
          {
            "value": "date"
          },
          {
            "value": "calendar"
          }
        ]
      },
      {
        "name": "timestamp",
        "type": "number",
        "default": 1789000000,
        "min": -8640000000000000,
        "max": 8640000000000000,
        "step": 1,
        "showWhen": {
          "mode": [
            "timestamp"
          ]
        },
        "requiredValue": true,
        "strictRange": true
      },
      {
        "name": "date",
        "type": "text",
        "default": "2026-09-12T12:00:00Z",
        "step": 1,
        "showWhen": {
          "mode": [
            "date"
          ]
        },
        "preserveEmpty": true
      },
      {
        "name": "milliseconds",
        "type": "select",
        "default": "no",
        "options": [
          {
            "value": "no"
          },
          {
            "value": "yes"
          }
        ],
        "showWhen": {
          "mode": [
            "timestamp"
          ]
        }
      },
      {
        "name": "timezoneOffset",
        "type": "number",
        "default": 8,
        "min": -14,
        "max": 14,
        "step": 0.25,
        "slider": true,
        "advanced": true,
        "strictRange": true,
        "requiredValue": true
      },
      {
        "name": "calendarDate",
        "type": "date",
        "default": "@today+4m",
        "step": 1,
        "showWhen": {
          "mode": [
            "calendar"
          ]
        },
        "requiredValue": true,
        "strictRange": true
      },
      {
        "name": "hour",
        "type": "number",
        "default": 0,
        "min": 0,
        "max": 23,
        "step": 1,
        "slider": true,
        "showWhen": {
          "mode": [
            "calendar"
          ]
        },
        "requiredValue": true,
        "strictRange": true
      },
      {
        "name": "minute",
        "type": "number",
        "default": 0,
        "min": 0,
        "max": 59,
        "step": 1,
        "slider": true,
        "showWhen": {
          "mode": [
            "calendar"
          ]
        },
        "requiredValue": true,
        "strictRange": true
      }
    ],
    "outputs": [
      {
        "name": "unixSeconds",
        "precision": 0,
        "unit": "seconds"
      },
      {
        "name": "unixMilliseconds",
        "precision": 0,
        "unit": "milliseconds"
      },
      {
        "name": "utcDate",
        "precision": 0,
        "unit": "",
        "type": "text"
      },
      {
        "name": "localDate",
        "precision": 0,
        "unit": "",
        "type": "text"
      },
      {
        "name": "weekday",
        "precision": 0,
        "unit": "",
        "type": "text"
      },
      {
        "name": "relative",
        "precision": 0,
        "unit": "",
        "type": "text"
      },
      {
        "name": "dayOfYear",
        "precision": 0,
        "unit": ""
      },
      {
        "name": "year",
        "precision": 0,
        "unit": ""
      },
      {
        "name": "daysSinceEpoch",
        "precision": 0,
        "unit": ""
      }
    ],
    "interpret": null
  }
}
