Communities

Writing
Writing
Codidact Meta
Codidact Meta
The Great Outdoors
The Great Outdoors
Photography & Video
Photography & Video
Scientific Speculation
Scientific Speculation
Cooking
Cooking
Electrical Engineering
Electrical Engineering
Judaism
Judaism
Languages & Linguistics
Languages & Linguistics
Software Development
Software Development
Mathematics
Mathematics
Christianity
Christianity
Code Golf
Code Golf
Music
Music
Physics
Physics
Linux Systems
Linux Systems
Power Users
Power Users
Tabletop RPGs
Tabletop RPGs
Community Proposals
Community Proposals
tag:snake search within a tag
answers:0 unanswered questions
user:xxxx search by author id
score:0.5 posts with 0.5+ score
"snake oil" exact phrase
votes:4 posts with 4+ votes
created:<1w created < 1 week ago
post_type:xxxx type of post
Search help
Notifications
Mark all as read See all your notifications »
Q&A

Welcome to Software Development on Codidact!

Will you help us build our independent community of developers helping developers? We're small and trying to grow. We welcome questions about all aspects of software development, from design to code to QA and more. Got questions? Got answers? Got code you'd like someone to review? Please join us.

Comments on Why is this client code getting the wrong date for a few hours a day?

Parent

Why is this client code getting the wrong date for a few hours a day?

+7
−0

Our web site has a widget that displays some date-based information that we retrieve from some JSON-formatted data (one object per date). We get the current date from the environment, possibly adjust it (see below), look up the right entry in the JSON, and display it. Most of the time this works right, but at certain times of day we see an off-by-one error.

About that adjustment: For purposes of our widget, the day does not start at midnight but at 8PM local time. (The widget is for an alternate calendar where the day starts at sunset. 8PM is a compromise because we are not going to look up actual sunset times in the client locale.) We therefore get the local date and time, and if it's after 8PM we increment the date before looking up the entry.

The behavior I have been seeing is:

  • From midnight to about 8PM (my time), the information is correct.
  • At 8PM the day rolls over to "tomorrow" as expected.
  • At 9PM the day rolls over again, so it is now really wrong (one full day ahead of where it should be).
  • At midnight it rolls back and is correct.

According to the documentation, the Javascript Date class operates in local time so what we're doing should work fine. The objects in the JSON use YYYY-MM-DD date format and Date doesn't by default, so we use toISOString() to convert the local date into this format:

let now = new Date();
if (now.getHours() > 20) {
   now.setDate(now.getDate() + 1);
}

now = now.toISOString().substr(0, 10);
// use that to look up the value

Why is it incrementing twice, making the value wrong for a few hours a day?

History
Why does this post require attention from curators or moderators?
You might want to add some details to your flag.
Why should this post be closed?

1 comment thread

General comments (2 comments)
Post
+4
−0

There are two issues here. The first is that this code isn't rolling over at 8PM as expected:

if (now.getHours() > 20) {
   now.setDate(now.getDate() + 1);
}

This change happens at 9PM as explained in this answer. The second increment is the one that's coming from this code, not the first one.

This leaves the question of what's going on at 8PM. The answer is that while Date uses local time if you get individual elements like day or hour (or even toString()), the ISO standard isn't just about getting YYYY-MM-DD formatting. ISO 8601 uses the UTC date. It's shortly before 9PM local time as I write this, and this is what we get from various operations:

let now = new Date();
now.getDate();        // returns 2
now.getHours();      // returns 20
now.toISOString();   // returns 2021-06-03T00:50:44.053Z

My time zone is UTC-4. Over in UTC-0, aka "Z" time, it's no longer June 2 but has rolled over to June 3. This happens at 8PM. That's where the first rollover is coming from.

In order to get the local date in the YYYY-MM-DD format, you have to use getFullYear(), getMonth(), and getDate() and assemble the string yourself. If month or date is one digit you have to add the leading 0, and don't forget to increment the month (months are 0-based).

Done in by time zones...

History
Why does this post require attention from curators or moderators?
You might want to add some details to your flag.

1 comment thread

General comments (3 comments)
General comments
manassehkatz‭ wrote over 3 years ago

Actually, 20 is 8:00pm. 12:01am is 00:01 = Hour 0, Minute 1. The problem is that > 20 effectively means > 8:59pm because it is looking at only the hour. So the reason of the problem was incorrect, but the actual problem (and the implemented > 19 fix) were both correct.

Monica Cellio‭ wrote over 3 years ago

Oh I see. So we could have also made it >= 20 to get 8PM. I don't know why I didn't do that instead of changing 20 to 19 there.

manassehkatz‭ wrote over 3 years ago

Fenceposts. Always watch out for the fenceposts.