3
\$\begingroup\$

I offer same day shipping if the user places an order before 9AM ET. If they place the order after 9AM, same day shipping is unavailable.

My server is using UTC time so I need to check if the time is greater than or less than 9AM ET regardless of the time where the user is located.

Not being an expert with JS, I cobbled together this code.

var d = new Date();
var e = d.getHours().toLocaleString('en-US', { timeZone: 'America/New_York' });
var f = '';

if(e >= 9) {
  f = 'shipping unavailable';
}
else {
  f = 'shipping available';
}

I am getting the correct result after 9AM ET on my computer but I am concerned that same day shipping will be offered after 9AM ET.

\$\endgroup\$
  • \$\begingroup\$ Please say you're checking this on the server, too. \$\endgroup\$ – wizzwizz4 Sep 1 at 22:09
4
\$\begingroup\$

Your code has a bug: d.getHours() will return a plain number. Calling toLocaleString on that number calls Number.prototype.toLocaleString, which:

returns a string with a language-sensitive representation of this number.

It does not do anything with timezones; the second parameter does not recognize a timeZone property. For example, where I am now, .getHours() returns 9, and (9).toLocaleString('en-US', { timeZone: 'America/New_York' }) returns "9".

On your server, to retrieve the hours in a particular timezone, one method would be to call toLocaleString on the date object itself with the appropriate timezone, then extract the number of hours from that string:

const timeString = new Date().toLocaleString('en-US', { timeZone: 'America/New_York' });
const [, hours, ampm] = timeString.match(/ (\d+).* ([AP]M)/);
console.log('In NY, it is:', hours, ampm);

Other issues:

  • Since it's 2020, best to prefer at least 2015+ syntax, which should not be an issue since the code is running on the server. (Among other things, being able to use const is wonderful)
  • You initialize f to the empty string, but then you reassign it immediately; the empty string is not used, so there's no point to assigning it.
  • Or, even better: since you want to conditionally assign a value to f depending on the number of hours, it would be more appropriate (and shorter) to use the conditional operator:
const f = Number(hours) < 9 && ampm === 'AM'
  ? 'shipping available'
  : 'shipping unavailable';
| improve this answer | |
\$\endgroup\$
  • \$\begingroup\$ Thanks a lot for the detailed reply. After applying the code changes it appears to work as desired. There's still a lot to learn. \$\endgroup\$ – Junky Sep 1 at 14:37
  • \$\begingroup\$ I have a question related to javascript dates, for operations like calculus of current date minus one day or some other similar operations there is some specific library usually used (maybe moment.js) ? Thanks for your attention. \$\endgroup\$ – dariosicily Sep 1 at 16:56
  • 1
    \$\begingroup\$ @dariosicily Yes, I believe moment.js is the most popular JS date library used by far. You can also subtract days very easily with the built-in Date too. \$\endgroup\$ – CertainPerformance Sep 1 at 17:25
  • \$\begingroup\$ I got it, thank you for your answer and time. \$\endgroup\$ – dariosicily Sep 1 at 19:57
2
\$\begingroup\$

From a short review;

  • Naming could be better for when you look back at the code;

    • var d could be const now
    • var e could be const hour
    • var f could be let shippingLabel
  • toLocaleString does not do what you want with time zones

  • As a beginner, I would not go for ternary to keep things ultra simple

So my counter proposal would be

const now = new Date();
const hour = now.getHours();
let shippingLabel;

if(hour >= 9) {
  shippingLabel = 'Shipping unavailable';
} else {
  shippingLabel = 'Shipping available';
}
| improve this answer | |
\$\endgroup\$
  • \$\begingroup\$ Thanks for your replay but getHours returns the hour, according to local time. I need the hour to always be compared to ET. \$\endgroup\$ – Junky Sep 1 at 14:35
  • 1
    \$\begingroup\$ For that, I would strongly suggest to use moment.js, momentjs.com/timezone \$\endgroup\$ – konijn Sep 1 at 14:37

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.