DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
Refcards Trend Reports Events Over 2 million developers have joined DZone. Join Today! Thanks for visiting DZone today,
Edit Profile Manage Email Subscriptions Moderation Admin Console How to Post to DZone Article Submission Guidelines
View Profile
Sign Out
Refcards
Trend Reports
Events
Zones
Culture and Methodologies Agile Career Development Methodologies Team Management
Data Engineering AI/ML Big Data Data Databases IoT
Software Design and Architecture Cloud Architecture Containers Integration Microservices Performance Security
Coding Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Culture and Methodologies
Agile Career Development Methodologies Team Management
Data Engineering
AI/ML Big Data Data Databases IoT
Software Design and Architecture
Cloud Architecture Containers Integration Microservices Performance Security
Coding
Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance
Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
What's in store for DevOps in 2023? Hear from the experts in our "DZone 2023 Preview: DevOps Edition" on Fri, Jan 27!
Save your seat
  1. DZone
  2. Coding
  3. Languages
  4. A Day is Not 60*60*24 Seconds Long

A Day is Not 60*60*24 Seconds Long

A review of how to express dates in JavaScript, using a junior programmer's code as an example.

Swizec Teller user avatar by
Swizec Teller
·
Nov. 20, 15 · Opinion
Like (10)
Save
Tweet
Share
55.08K Views

Join the DZone community and get the full member experience.

Join For Free

I was fixing some code written by an intrepid junior the other day and came upon this beauty:

var day = 1000*60*60*24;
var week = day*7;

var yesterday = new Date(today.getTime() - day);
var lastWeek = new Date(today.getTime() - week);

Looks pretty good, right? It calculates the timestamp for yesterday and a timestamp for last week by deducting the amount of milliseconds in a day and a week from the current time. Clever.

But wait… does it smell bad to you? I’ll give you a minute.

…

How about now? Are your nose hairs sizzling yet?

Maybe not. I mean, we’ve all written code like this. Maybe not recently, but for sure when we were starting out. Even the internet didn’t smell anything.

Pop quiz: Why is this code wrong?var day = 1000*60*60*24

— Swizec (@Swizec) November 3, 2015


There’s less context, but the smelliest line of code is still there.

Answers ranged from the slightly missing the point:

@Swizecbecause there aren't 60,000 seconds in a minute. context would be helpful

— Aron (@MrAronD) November 3, 2015

To the snarky:

@swizec You should use ES6's const instead of var…

— Anže Pečar (@Smotko) November 3, 2015

And even the “I am a linter”:

@swizec Probably not, but… mising semicolon?

— Blaž Maležič (@BlazMalezic) November 3, 2015

They all have a point, but none of them got the point.

Days aren’t 60*60*24 seconds long. They are 1 day long, which on most days maps to 60*60*24 = 86400 seconds. But not on all days.

Thanks to the wonder that is daylight savings time (DST), we have a day that’s only 23 hours long. We also have a day that’s 25 hours long. Then, every few years, we have a day that’s 86,401 seconds long. In theory, we could even have a day that’s 86,399 seconds long. It’s unlikely, but it’s possible.

But, I mean, who cares, right? It’s just an hour here, an hour there, and maybe a second when no one’s paying attention. Nobody’s going to notice. 24 hours ago should still mean yesterday.

Here’s the thing, though. Just because it’s yesterday doesn’t mean it’s also 1 day ago.

Let’s say this code runs between 2 am and 3 am on the days when daylight savings time goes away. First of all, not all countries do the change; not even all US states do. Second of all, there are two instances of the hour between 2 am and 3 am.

Let me show you some examples:

new Date((new Date("<a href="tel:2015110102">2015-11-01 02</a>:59 pst").getTime()-1000*60*60*24))
// Sat Oct 31 2015 03:59:00 GMT-0700 (PDT)
new Date((new Date("<a href="tel:2015110102">2015-11-01 02</a>:59 pdt").getTime()-1000*60*60*24))
// Sat Oct 31 2015 02:59:00 GMT-0700 (PDT)

Subtracting 24 hours from PST (Pacific Standard Time) gives you the day before, but an hour later. Subtracting 24 hours from PDT (Pacific Daylight Time) gives you the day before at the same time. This timezone name-change is how you know which side of DST you’re on.

The same example without specifying a timezone chooses your local timezone (which for me is PST):

new Date((new Date("2015-11-01 02:59").getTime()-1000*60*60*24))
// Sat Oct 31 2015 03:59:00 GMT-0700 (PDT)

Now let’s see what happens in March, when daylight savings time goes back into effect:

new Date((new Date("2015-03-08 02:30 pdt").getTime()-1000*60*60*24))
// Sat Mar 07 2015 01:30:00 GMT-0800 (PST)
new Date((new Date("2015-03-08 02:30 pst").getTime()-1000*60*60*24))
// Sat Mar 07 2015 02:30:00 GMT-0800 (PST)

We didn’t get the wrong date because JavaScript is awesome and automatically covers up the mess with timezone changes. It knows that on these key days, PST becomes PDT and vice-versa.

At least, this is what happened when I ran the code in San Francisco. When I tried in Denver, a few days later, it looked like this:

new Date((new Date("2015-11-01 02:59 pst").getTime()-1000*60*60*24))
// Sat Oct 31 2015 04:59:00 GMT-0600 (MDT)
new Date((new Date("2015-11-01 02:59 pdt").getTime()-1000*60*60*24))
// Sat Oct 31 2015 03:59:00 GMT-0600 (MDT)
new Date((new Date("2015-11-01 01:59 pdt").getTime()-1000*60*60*24))
// Sat Oct 31 2015 02:59:00 GMT-0600 (MDT)
new Date((new Date("2015-11-01 01:59 pst").getTime()-1000*60*60*24))
// Sat Oct 31 2015 03:59:00 GMT-0600 (MDT)

Notice the funny part? At 2:59, we’re hit by San Francisco’s DST change. At 1:59, we’re hit with Denver’s DST change. That’s because Denver is on Mountain Time, which is an hour ahead of Pacific Time. So Denver goes through the DST change an hour before San Francisco does. Mind = blown.

Now, this wasn’t too bad because JavaScript is amazing and knows when to automatically switch timezones. But what if you’re in Arizona? That state’s on Eastern Time, and most of it doesn’t observe daylight savings. Now JavaScript needs to know a whole lot about your user. Let’s hope it does.

You might not care about any of this, but if your job is to capture all of X from yesterday, then you’re in for a ride when your boss or client says, “Errrr, there seems to be a whole hour of events missing. That’s 10,000 datapoints. Where did they go?”

Then there are leap seconds.

In a way, leap seconds are less of a problem because you can only get it wrong by a second; but, when you’re calculating with Unix epoch times (which is what getTime() does, by the way), you don’t have the luxury of timezones. Not that timezones would help for leap seconds.

You’d think a system that counts seconds since January 1st, 1970, wouldn’t have this problem. Unfortunately, you’d be wrong.

Observe that when a positive leap second occurs (i.e., when a leap second is inserted), the Unix time numbers repeat themselves. The Unix time number 915148800.50 is ambiguous. It can refer either to the instant in the middle of the leap second, or to the instant one second later, half a second after midnight UTC.

&embdash; Wikipedia (https://en.wikipedia.org/wiki/Unix_time)

Let’s see what JavaScript will do in this situation:

new Date(new Date("1999-01-01T00:00:00.00").getTime()-1000*60*60*24)
// Wed Dec 30 1998 16:00:00 GMT-0800 (PST)

Ok. That’s bad. We’ve lost an entire day. I’m pretty sure that’s going to be a problem. If your boss or client was unhappy about the 10,000 datapoints you missed when you got it wrong by an hour, how will they feel about losing 240,000 datapoints?

Oh, and by the way, stop using Unix timestamps as unique identifiers because they’re not unique.

All that said, there were two or three people that put garlic around their necks, tossed salt over their shoulders, and ran as fast as their legs would carry them.

@Swizec because it doesn&#39;t account for leap seconds? something to do with floating point rounding since that appears to be javascript? idk

&mdash; Aron (@MrAronD) November 3, 2015

@Swizec This is a minefield, especially for distributed systems. See falsehoods programmers believe about time: https://t.co/C3CCMMhIib

&mdash; galar (@galar) November 4, 2015

You should read the falsehoods article. Dealing with time is a minefield.

Oh, one more thing. Relativistic effects come into play for rocket guidance systems, things running on space stations, and anything moving quickly. That’s when a second is no longer a second.

Let’s hope neither the military nor any astronauts ever use your real-time smartphone app or website.

P.S.: There’s internet on the International Space Station. 

LEAP (programming language) IT JavaScript Space (architecture) PHP Development Tools Internet (web browser) app career

Published at DZone with permission of Swizec Teller, DZone MVB. See the original article here.

Opinions expressed by DZone contributors are their own.

Popular on DZone

  • 5 Factors When Selecting a Database
  • Simulate Network Latency and Packet Drop In Linux
  • Type Variance in Java and Kotlin
  • Spring Cloud: How To Deal With Microservice Configuration (Part 1)

Comments

Partner Resources

X

ABOUT US

  • About DZone
  • Send feedback
  • Careers
  • Sitemap

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 600 Park Offices Drive
  • Suite 300
  • Durham, NC 27709
  • support@dzone.com
  • +1 (919) 678-0300

Let's be friends: