1

I'm working on code to determine if the current local datetime falls within a datetime range, a start and end datetime.

I start by getting the start and end datetime values as a serialized GMT string (this is what the source system is returning to me):

let myStartDate = "2020-09-11T14:15:13.000Z";
let myEndDate = "2020-09-15T01:09:34.000Z";

I then convert the datetime to UTC format:

let startDate = new Date(myStartDate).toUTCString();
let endDate = new Date(myEndDate).toUTCString();
let now = new Date().toUTCString();

Then I check to see if now is between the startDate and endDate:

if (now > startDate && now < endDate) {
  console.log("You're INSIDE the datetime window!");
} else {
  console.log("You're OUTSIDE the datetime window!");
}

console.log("Now:   " + new Date(now));
console.log("Start: " + new Date(startDate));
console.log("End:   " + new Date(endDate));

When I run this, my code is telling me I'm outside the datetime window, even though the start and datetime values are a couple days before and after my current datetime.

An alternative I see is using getTime(), which converts the datetime to a UTC milliseconds number.

let startDate = new Date(myStartDate).getTime();
let endDate = new Date(myEndDate).getTime();
let now = new Date().getTime();

This seems to work, but I'm confused why toUTCString() can't be evaluated the same way.

Matt Smith
  • 1,932
  • 1
  • 21
  • 41
  • 1
    the output of `toUTCString()` should be a string? I'd expect a number or date value not be preferred for range comparisons. – jidexl21 Sep 13 '20 at 20:55
  • @jidexl21 correct, I misspoke, it's not a string, it's number – Matt Smith Sep 13 '20 at 21:02
  • 1
    `typeof ((new Date()).toUTCString())` returns string. – jidexl21 Sep 13 '20 at 21:08
  • If your strings are in ISO 8601 format, you don't need to convert to Date objects, the strings will compare lexically as accurately as if they were Dates. If you used *toISOString* the string comparison would work too, since it would return the same string as you're parsing, i.e. `new Date("2020-09-11T14:15:13.000Z").toISOString() === "2020-09-11T14:15:13.000Z"`. – RobG Sep 13 '20 at 22:34
  • @RobG I was tinkering with `toISOString()` originally but I learned that it's deprecated now, so went with `toUTCString()`. – Matt Smith Sep 13 '20 at 23:43
  • [*toISOString*](https://tc39.es/ecma262/#sec-date.prototype.toisostring) is not deprecated and likely never will be (it's the only Date *toString* method that returns an ISO 8601 compliant string). What makes you think it is? – RobG Sep 14 '20 at 02:07
  • @RobG I mispoke, I was referring to `toGMTString()`. – Matt Smith Sep 14 '20 at 18:13

2 Answers2

4

No need to convert to strings, you can compare Date objects themselves. The Date objects get cast to number (equivalent to getTime()) when doing such comparisons

Since the timezone offset is same for each one and your original strings are already UTC then UTC isn't going to really be relevant in the comparison

Note that for == or != comparisons will need to convert to getTime() due to object equality rules

let myStartDate = new Date("2020-09-11T14:15:13.000Z");
let myEndDate = new Date("2020-09-15T01:09:34.000Z");

let today = new Date();

console.log(today >= myStartDate && today <= myEndDate)
charlietfl
  • 170,828
  • 13
  • 121
  • 150
0

Well,

toUTCString only converts a time to time-string with UTC tz.
most languages, including JavaScript don't know how to translate strings to comparable dates.

Lets do a thinking practice:

What is bigger, "1" or "2"? "2"
What is bigger, "a" or "b"? "b"
What is bigger, "a" or "A"? "a" <-- a==97 and A==65

So the comparison is Ascii based.

So if the numeric value is bigger -> the string is bigger

Itamar
  • 1,601
  • 1
  • 10
  • 23