Unix Timestamp Converter
Convert a Unix timestamp to a readable date, or a date back to a timestamp, kept in sync in both directions.
About the Unix Timestamp Converter
A Unix timestamp counts elapsed time since January 1, 1970 00:00:00 UTC (the "epoch"), either in whole seconds or milliseconds. This tool runs both directions at once: typing a timestamp on top fills in the local time, UTC time and a plain-language relative time below it ("3 days ago", "in 2 hours"), while picking a date and time at the bottom recalculates the equivalent timestamp in both units. Both sides stay synced as you edit either one, and the relative time is computed directly from the millisecond difference against your device's current clock, not fetched from anywhere.
How two-way sync avoids an infinite update loop
Updating the timestamp field re-fills the date field, but the date field also has its own input listener that would normally fire in response and try to update the timestamp field right back, which could ping-pong back and forth indefinitely. This tool prevents that with a simple syncing flag: whenever one field's update function is actively writing a new value into the other field, it sets that flag first, and both update functions check the flag at their very start and bail out immediately if it's already set. That's what lets editing either field cleanly cascade to update everything else exactly once, without triggering an unwanted follow-up update loop.
Why the relative time uses approximate month and year lengths
Converting days into months or years for a "3 months ago" style label uses fixed average divisors, 30.44 days per month and 365.25 days per year, rather than doing exact, calendar-aware math that accounts for which specific months and leap years actually fall between two dates. That's a deliberate simplification: a relative time label is meant to give a quick, approximate human sense of elapsed time, not a precise calendar computation, and 30.44 (365.25 Γ· 12) and 365.25 already correctly account for the average effect of leap years without needing to actually walk through a real calendar day by day.
Why the unit-switching threshold is 45, not 60
The relative time logic switches from seconds to minutes once the value reaches 45 seconds, not 60. That's intentional: if it waited until exactly 60, a value like 59.6 seconds would round up to display as the confusing and technically wrong "60 seconds" instead of correctly bumping over to "1 minute." Cutting over at 45 leaves enough buffer that anything close enough to round into the next unit's first increment gets displayed in that next unit's terms instead, avoiding that awkward boundary case, this same 45-second convention is used by most relative-time libraries for exactly this reason.
Why picking a date always converts correctly without manual time zone math
The <input type="datetime-local"> control deliberately stores no time zone information at all, its value is a plain wall-clock string with no UTC offset attached. When that exact string gets passed to new Date(value), JavaScript's own Date parser automatically interprets a timezone-less date-time string using your browser's local system time zone. Since both halves of this relationship, the input control's assumed meaning and the Date constructor's fallback behavior, consistently agree on "local system time," the conversion works out correctly without this tool needing to do any manual offset math of its own.
Why both seconds and milliseconds are always shown together
The Unit dropdown only controls how a raw number you type into the top timestamp field gets interpreted, as seconds or as milliseconds. The output section at the bottom always displays both units side by side regardless of that setting, since different systems expect different ones, JavaScript's own Date.now() and most web APIs use milliseconds, while Unix itself and many server-side languages and databases traditionally use whole seconds. Showing both simultaneously means you never have to guess which format your specific target system needs before copying.
Frequently Asked Questions
How does editing one field update the other without them fighting each other?
A simple syncing flag is set whenever one field's update function is writing into the other field, and both functions check that flag first and immediately exit if it's already set. This lets an edit cleanly cascade through all the fields exactly once instead of triggering a repeating update loop.
Why does the relative time label use approximate month and year lengths?
It uses fixed averages, 30.44 days per month and 365.25 days per year, which already account for leap years on average, rather than exact calendar math. A relative time label is meant to give a quick approximate sense of elapsed time, not a precise calendar computation.
Why does the relative time switch units at 45 seconds instead of 60?
Waiting until exactly 60 could round a value like 59.6 seconds up to a confusing "60 seconds" instead of correctly showing "1 minute." Switching at 45 leaves a buffer so anything close to the next unit's first increment displays in that unit's terms instead, avoiding that awkward boundary case.
Does the date picker need to know my time zone to convert correctly?
No, the datetime-local input stores no time zone information at all, and JavaScript's Date parser automatically interprets that timezone-less string using your browser's local system time zone. Both sides consistently agree on "local time," so no manual offset math is needed.
Why are both seconds and milliseconds shown even though I only picked one unit?
The Unit dropdown only affects how a number typed into the timestamp field is interpreted. The output always shows both, since JavaScript and web APIs typically use milliseconds while Unix and many databases use seconds, so you don't have to guess which format you need before copying.
Why do the copy buttons strip out the commas from the displayed number?
The displayed timestamp uses comma formatting for readability, but a raw number without commas is what's actually needed when pasting into code, a database, or an API call, so the copy action removes the commas before copying to the clipboard.