0

I have an application where some operations are only allowed at certain time of period to every user no matter from which country he accessing Application just like stock exchange has fixed time window.

Suppose I set operational time to 01:00 AM to 11:00 PM Eastern Time (ET) and I am storing time to UTC format in DB. and this is From time 6:00:00 to time 4:00:00.

Below is how I handled it

const nowGetTime = nowDateTime.getTime();

  const availableLocaleFrom = new Date(this.setDateTime(new Date(), this.availableFrom)); // Here Adding current date to existing time as without it we can't convert date 
  const availableLocaleTo = new Date(this.setDateTime(new Date(), this.availableTo));
  const start = this.convertUTCDateToLocalDate(availableLocaleFrom);
  const end = this.convertUTCDateToLocalDate(availableLocaleTo);
  // console.log('start', availableLocaleFrom, 'end', availableLocaleTo);
  // same day but ahead of start

  if (start.getDate() > new Date().getDate()) {
    start.setDate(start.getDate() - 1 );
 }
 if (start.getTime() > end.getTime()) {
    end.setDate(end.getDate() + 1 );
 }

 if (end.getTime() - start.getTime() > (1000 * 60 * 60 * 24)) {
    end.setDate(end.getDate() - 1 );
}
 
this.isMarginAvailable = ( nowGetTime > start.getTime() && nowGetTime < end.getTime());

Helping functions

 setDateTime(date: Date, str: string) {
  var sp = str.split(':');
  date.setHours(parseInt(sp[0],10));
  date.setMinutes(parseInt(sp[1],10));
  date.setSeconds(parseInt(sp[2],10));
  return date;
}

convertUTCDateToLocalDate(onlyLocaleDate) {
 return new Date(Date.UTC(onlyLocaleDate.getFullYear(), onlyLocaleDate.getMonth(),   onlyLocaleDate.getDate(),  onlyLocaleDate.getHours(), onlyLocaleDate.getMinutes(), onlyLocaleDate.getSeconds()));

}

And this function is not working well. Like in Tokyo when Tokyo's local time is 2:30 pm condition is not satisfying Happening same for Australia at certain period.

I am struggling since 2 days, trying many if else conditions and still trying some reliable solution. This conditions not satisfying when time frame is beyond 12 hours.

Thanks

  • 2
    "I am storing time to UTC format in DB" - how are you doing that, when "1am Eastern Time" can be 6am UTC or 5am UTC depending on the time of year? What do you expect to happen during daylight saving time? (If your real business rule is a check between 1am and 11pm Eastern time, that's what I'd suggest you store in the database. The mantra of "always store UTC" is dangerously over-stated IMO. See https://codeblog.jonskeet.uk/2022/10/30/handling-times-for-an-ev-charger/ for a related blog post.) – Jon Skeet Mar 10 '23 at 09:35
  • I am converting selected time to UTC format using let from = this.datepipe.transform(element.from, 'HH:mm:ss', '+0000'); let to = this.datepipe.transform(element.to, 'HH:mm:ss', '+0000'); – Rajnesh Rathor Mar 10 '23 at 10:05
  • Firstly, let's clarify terminology: UTC isn't a "format". It's worth separating in your mind the difference between time zone handling and formatting values as text. But fundamentally, it feels to me like you've got a problem in terms of DST (and any other reason why "Eastern time to UTC" doesn't have the same mapping for every day). – Jon Skeet Mar 10 '23 at 10:23
  • Time can be set from any country. It can be set from Tokyo, Mumbai or Melborne – Rajnesh Rathor Mar 10 '23 at 11:20
  • I think you're missing the point. You've said: "Suppose I set operational time to 01:00 AM to 11:00 PM Eastern Time (ET) and I am storing time to UTC format in DB" - but you've missed the point that there is no consistent mapping from Eastern Time to UTC. It depends on the time of year, because the UTC offset in Eastern Time depends on the time of year. I'm afraid until you've understood that fundamental issue, I won't be able to help you further. – Jon Skeet Mar 10 '23 at 11:29

1 Answers1

1

I second Jon Skeet's comment and recommend that you store the points in time as a pair of

  • a time (HH:mm:ss, as defined in XML Schema), in your case 01:00:00 and 23:00:00 and
  • a time zone (a string from the IANA database), in your case America/New_York.

Actually, beginning and end of your operational hours are two points in time with the same time zone.

In order to perform computations with these, you can use a Javascript date/time library which is able to translate the point in time on any given date into UTC, taking account of daylight saving time as well as of other changes to the time zone's legal definition (if the library is regularly updated).

The Javascript Intl.DateTimeFormat function is able to convert from UTC to date and time for a given time zone:

> Intl.DateTimeFormat("en-US", {timeZone: "America/New_York",
  day: "numeric", month: "numeric", year: "numeric",
  hour: "numeric", minute: "numeric"})
  .format(new Date("2023-03-10T06:00:00Z"))
'3/10/2023, 1:00 AM'

but not vice versa: it cannot convert a date/time/time zone combination into UTC.

See also java Calendar, Date, and Time management for a multi-timezone application.

Heiko Theißen
  • 12,807
  • 2
  • 7
  • 31
  • I have converted local time to UTC and then started comparing. Thus I concluded – Rajnesh Rathor Mar 13 '23 at 10:51
  • If you _store_ the time as local time (`01:00:00`, say), you can always convert it to UTC on a _given date_. But the result will vary between winter and summer because of daylight saving time. – Heiko Theißen Mar 13 '23 at 11:40