🔧 AI Nachrichten Major AI platforms go down in unprecedented simultaneous outage(03.09.2026 um 17:34 Uhr)
🔧 AI Nachrichten ChatGPT, Claude, and Grok Down? Users Report Widespread Outages(03.09.2026 um 19:14 Uhr)
🔧 AI Nachrichten OpenAI Launches GPT-6 Astra, Says We May Have Entered the AGI Era(03.09.2026 um 22:08 Uhr)
🔧 AI Nachrichten Claude Comes to CarPlay as Fifth Major AI Chatbot App(05.09.2026 um 05:31 Uhr)
🔧 AI Nachrichten OpenAI’s GPT-6 Astra Is AGI, Says NVIDIA CEO Jensen Huang(07.09.2026 um 06:31 Uhr)
🔧 AI Nachrichten Blame AI companies for Mac mini and Mac Studio shortage(31.08.2026 um 10:32 Uhr)
🔧 AI Nachrichten Major AI platforms go down in unprecedented simultaneous outage(03.09.2026 um 17:34 Uhr)
🔧 AI Nachrichten ChatGPT, Claude, and Grok Down? Users Report Widespread Outages(03.09.2026 um 19:14 Uhr)
🔧 AI Nachrichten OpenAI Launches GPT-6 Astra, Says We May Have Entered the AGI Era(03.09.2026 um 22:08 Uhr)
🔧 AI Nachrichten Claude Comes to CarPlay as Fifth Major AI Chatbot App(05.09.2026 um 05:31 Uhr)
🔧 AI Nachrichten OpenAI’s GPT-6 Astra Is AGI, Says NVIDIA CEO Jensen Huang(07.09.2026 um 06:31 Uhr)
🔧 AI Nachrichten Blame AI companies for Mac mini and Mac Studio shortage(31.08.2026 um 10:32 Uhr)

🔧 Programmierung 🕛 kürzlich 6 Min Lesezeit
0

Why `new Date(garbage) === "Invalid Date"` is always false (a timestamp converter taught me this the hard way)

↗ Quelle (dev.to)
🗣️ Stimme:
📑 Inhaltsübersicht

I built a small Unix timestamp converter — paste in seconds or milliseconds, get a date back, or go the other way. Simple enough that I figured the only real work would be the date math. Then I went to add "tell the user when they typed garbage" and ran straight into a JavaScript gotcha that's been quietly living in more codebases than anyone wants to admit.






The unit dropdown is secretly a multiplier, not a branch



The converter has a unit selector next to the input — "Seconds" or "Milliseconds." The tempting way to wire that up is an if/else: if seconds, do this math; if milliseconds, do that math. That's not what's in the actual component. The <a-select> options are bound directly to the numbers 1 and 1000, and those numbers get used as literal arithmetic operands everywhere downstream:




CODE
const unixToNoraml_getOutput = () => {
let unix = data.unixToNoraml.unix;
let unit = data.unixToNoraml.unit; // 1 or 1000
let output = new Date(Math.floor((unix * 1000) / unit));
data.unixToNoraml.output = output;
};






If unit is 1 (seconds), that's unix * 1000 / 1 — converts seconds to the milliseconds Date wants. If unit is 1000 (milliseconds), it's unix * 1000 / 1000, which cancels out and leaves the value untouched, because it was already in milliseconds. Same one-liner handles both cases with no conditional at all.



The reverse direction does the same trick in reverse — compute the answer in seconds, then multiply by the unit to get either seconds or milliseconds back out:




CODE
const normalToUnixOutputFormat = computed(() => {
if (!data.normalToUnix.output) return "";
return data.normalToUnix.output * data.normalToUnix.unit;
});






It's a small thing, but reusing the dropdown's raw value as a multiplier instead of introducing a "seconds" | "milliseconds" enum saved a branch in four separate places in the component.






The validation check that doesn't actually validate anything



Here's the one that got me. When you type a date string into the "normal time" field and hit convert, the code tries to reject bad input before doing math on it:




CODE
if (new Date(normal) === "Invalid Date") {
return Swal.fire({
title: t("timestamp.error"),
icon: "warning",
confirmButtonColor: "#1890ff",
});
}
let output = new Date(normal).getTime() / 1000;






new Date("not a real date") doesn't throw and doesn't return the string "Invalid Date" — it returns an actual Date object whose internal time value is NaN. Calling .toString() on that object prints "Invalid Date", but the object itself is never, ever === to a string, no matter what garbage you feed it. So that guard clause is dead code. It will never fire, for any input, ever.



What actually keeps the tool from displaying literal "NaN" to the user is something else entirely, three lines away in a computed property:




CODE
const normalToUnixOutputFormat = computed(() => {
if (!data.normalToUnix.output) return "";
return data.normalToUnix.output * data.normalToUnix.unit;
});






NaN / 1000 is still NaN, and !NaN evaluates to true in JavaScript — so the falsy check blanks the output field instead of the intended validation ever running. The tool behaves correctly, but by accident: the real safety net is a coincidental side effect of how NaN interacts with !, not the Swal.fire() warning dialog that was written to handle exactly this case. The correct check would be isNaN(new Date(normal).getTime()), but that's not what's in the file.






The live clock ticks in your local time, not UTC



The page also has a running "current timestamp" display that updates once a second, with pause/continue buttons:




CODE
const init_clock = () => {
if (data.timer) return;
data.timer = setInterval(() => {
let now = new Date();
data.currentUnix = Math.round(now.getTime() / 1000);
data.currentLocalString = DateTime.fromSeconds(data.currentUnix).toFormat(
"yyyy/MM/dd HH:mm:ss",
);
}, 1000);
};
const pause_clock = () => {
clearInterval(data.timer);
data.timer = null;
};






Two things worth calling out. First, setInterval(..., 1000) doesn't guarantee a tick every exact second — it just re-reads Date.now() and rounds each time it fires, so under heavy main-thread load a tick can land late; the displayed number just catches up rather than drifting permanently. Second, DateTime.fromSeconds() from Luxon defaults to the local system time zone when you don't pass one — so the human-readable clock next to the raw Unix number is your machine's local time, not UTC, even though a Unix timestamp is by definition timezone-independent. There's no UTC toggle for it. If you're in Tokyo and I'm in Berlin, we see the same integer but a different clock face next to it.






Limitations, honestly





  • No digit-count auto-detection. I assumed a paste-in converter like this would sniff "10 digits, must be seconds" vs "13 digits, must be milliseconds." It doesn't — the unit is a manual dropdown. Paste a 13-digit millisecond value while "Seconds" is still selected and you silently get a date several thousand years in the future. No warning, no clamp.


  • Everything renders in local time. The seconds-since-epoch value is timezone-agnostic by definition, but every human-readable output on the page — the live clock, the converted date — is displayed in whatever timezone the browser is set to, with no UTC option. If you're debugging a server log recorded in UTC, you have to do the offset math yourself.


  • The "type a date manually" field parses whatever new Date(string) accepts, which is a browser-implementation detail, not a fully spec'd format. It works fine for the YYYY/MM/DD HH:MM:SS shape the placeholder suggests, but it's not the same guarantee you'd get from an explicit parser.


  • The Invalid Date check discussed above never runs. It's harmless here because NaN's falsiness happens to save it, but it means the warning dialog telling you "please enter a valid time" is unreachable code.



I turned the cleaned-up version into a small free tool: — 繁體中文


  • — English


  • — 한국어


  • — Русский


  • — Bahasa Indonesia


  • — Tiếng Việt


  • — Polski


  • — Italiano


  • — Nederlands


  • Інструмент конвертації Unix Timestamp — Українська

  • Vollständiger Original-Bericht
    Ausführliche Details, Code-Beispiele & Hersteller-Stellungnahme auf dev.to.
    ↗ Original-Artikel auf dev.to lesen
    Wie bewertest du diesen Beitrag?
    1 Klick Feedback
    Teilen mit Netzwerk & Team:

    Community-Analysen & Experten-Meinungen 0

    Verfasse deine eigene Analyse, teile Workarounds oder diskutiere diesen Vorfall im Blog.
    Noch keine Community-Analyse verfasst. Markiere einen Textabschnitt oder klicke oben auf Eigene Analyse verfassen“!
    Community Pulse: Relevanz-Einschätzung
    1 Klick Experten-Votum
    🔴 Akute Relevanz 0%
    🟡 In Evaluierung 0%
    🟢 Keine Auswirkung 0%
    Spannende Innovation 0%
    Verwandte Story-Cluster & Quellen (Vektor-KI)
    Port 8095 Engine
    3 Quellen
    GPT-6 Astra Release Today? OpenAI’s Next Major AI Model Is Almost Here
    1 Quelle
    Apple accuses OpenAI of destroying evidence as trade-secrets fight intensifies
    1 Quelle
    Major AI platforms go down in unprecedented simultaneous outage