Skip to main content

How long is a second in JavaScript?

· 7 min read
Iago Lastra
Cofounder | TimeTime.in

When you ask the question "How long is a second in JavaScript?", it seems like a straightforward query. However, the answer reveals layers of complexity intertwined with history, science, and the foundations of modern computing. Let’s dive deep to understand how humanity has measured time and how it connects to JavaScript’s timekeeping.

A little history

The Early Days of Timekeeping

Time measurement began with observing natural periodic phenomena. Early civilizations looked to the moon's phases and the apparent movement of the sun to divide time into manageable units. These observations gave rise to the concepts of days, months, and years.

As human needs evolved, a more granular division of time became necessary. The ancient Egyptians and Babylonians divided the day into 24 hours, likely influenced by their base-12 numbering system. Later, hours were divided into 60 minutes and minutes into 60 seconds, creating the framework we still use today.

Enter the Atomic Clock

While these early methods sufficed for centuries, they lacked precision. By the mid-20th century, advancements in technology demanded a more accurate measurement of time. The invention of the atomic clock in the 1950s marked a revolutionary step. These clocks measure time based on the vibrations of cesium atoms, offering unparalleled precision.

As a result, the definition of a second was updated to:

"The duration of 9,192,631,770 periods of the radiation corresponding to the transition between the two hyperfine levels of the ground state of the cesium-133 atom."

This definition formed the foundation for what we now call international atomic time (TAI)

Time scales

UT

Universal Time is based on the Earth's rotation. It’s intuitive and tied to our everyday experience of day and night. However, the Earth's rotation is not perfectly consistent due to various factors such as gravitational interactions and geophysical processes. As a result, we could say that Universal Time is imprecise and variable.

TAI

Atomic Time, derived from atomic clocks, is based on physical phenomena and is both precise and consistent. It serves as the backbone for modern timekeeping systems.

UTC

In the 1970s, Coordinated Universal Time (UTC) was introduced to reconcile the discrepancies between Universal Time and Atomic Time. UTC aligns with Universal Time but incorporates adjustments, such as the addition or removal of leap seconds, to compensate for the Earth's irregular rotation.

Leap Seconds

Leap seconds are occasional one-second adjustments added to UTC to keep it in sync with Universal Time. These adjustments ensure that UTC remains within 0.9 seconds of Universal Time. However, they introduce complications for systems that rely on precise time calculations.

Here’s the improved article in English, incorporating the original tables:


Second duration in JS

ECMAScript and POSIX Time

The time system in JavaScript, as defined by the ECMAScript standard, is based on POSIX time. This means that dates and times are measured as the number of milliseconds elapsed since the epoch: January 1, 1970, 00:00:00 UTC, excluding leap seconds.

This approach treats every day as having exactly 86,400 seconds (24 hours), ignoring both leap seconds and astronomical variations in the Earth's rotation. While this simplifies calculations and suffices for most applications, it introduces limitations in scenarios where precise timekeeping is critical.

POSIX Time ≠ UTC

Although POSIX and UTC appear similar, POSIX is not UTC. Here are the key differences:

  1. Ignores Leap Seconds:

    • UTC includes leap seconds to adjust official time to the Earth's rotation.
    • POSIX does not count leap seconds, meaning that POSIX days always have 86,400 seconds, even when UTC days have 86,401 or 86,399 seconds due to a leap second.
  2. Simplified Interoperability:

    • POSIX assumes all seconds are of equal duration. This makes calculating time differences straightforward but causes discrepancies when leap seconds occur.
    • For example, during a leap second (e.g., 23:59:60), POSIX simply ignores the additional second, making timestamps near the leap second ambiguous or inaccurate.

Leap seconds

Step Adjustment: The Traditional Solution

Historically, systems that needed to account for leap seconds would use a technique called step adjustment. This method can be described as just ignoring the leap second, causing the clock to jump forward or backward by one second at the exact moment of the leap second.

Lets see a table to understand this:

UTCTAIUTC (s)POSIX (step)
23:59:58......16315619216315619198.00
23:59:59......17315619217315619199.00
23:59:60......18315619218315619199.00
00:00:00......19315619219315619200.00

As you can see from the both TAI and UTC are strictly increasing, but POSIX (step) has a jump in time at the leap second. This means that 2 different UTC seconds are mapped to the same POSIX second. This can cause issues in some applications. The biggest problem is that some apps can go "back in time" when a leap second is added.

Lets say that a payment is requested at 23:59:59.600, and approved during the next second at 23:59:60.200. Our logs will show something like:

315619199.600 - Payment requested
315619199.200 - Payment approved (?)

This is a problem because the payment was approved before it was requested. This is why most system use a different approach to handle leap seconds.

Smearing: The Practical Solution

In many modern systems implementing POSIX time, a technique called smearing is used to handle leap seconds. Instead of adding or removing a whole second, the effects of the leap second are distributed gradually over a longer period (typically 24 hours). This has several implications: First of all during the smear period, seconds are slightly longer or shorter than a standard second (measured in atomic time). This ensures a smooth transition instead of an abrupt jump in time. On the other hand compared to stepping the clock is strictly increasing, which is a requirement for many applications.

Example: Smearing and Step Adjustment Tables

UTCTAIUTC (s)POSIX (step)POSIX (smear)
23:59:58......16315619216315619198.00315619197.75
23:59:59......17315619217315619199.00315619198.50
23:59:60......18315619218315619199.00315619199.25
00:00:00......19315619219315619200.00315619200.00

In this table: POSIX (step) ignores the leap second entirely, treating 23:59:60 as if it doesn't exist while POSIX with (smearing) gradually adjusts the clock, ensuring smoother transitions but at the cost of seconds having slightly different durations.

This is how Google's NTP servers handle leap seconds. They smear the leap second over a 24-hour period, ensuring that the clock is always strictly increasing. More information can be found here.

Implications for Applications

Why It Usually Doesn’t Matter

For tasks like scheduling events, calculating ages, or displaying time in user-facing applications, JavaScript (and POSIX) time is precise enough and 99% of the problem will be derived from timezones.

When It Does Matter

For applications requiring high precision, such as those in scientific research or financial systems, the discrepancies caused by leap seconds and smearing can lead to significant errors. Accurate timekeeping is crucial to ensure the reliability and accuracy of measurements and transactions. During a leap second, a single POSIX timestamp can refer to two different moments in UTC, creating ambiguities and potential errors in systems that demand precise time synchronization.

Takeaways