javascriptangulartypescriptangular8angular9

Angular: Date Timezone Global parameter setting


I am searching for a way to

How can this be done? Is there a global parameter in Angular to set this, maybe in the config files?

*We have 500 lines of date codes in the code base, which require this global conversion. Sometimes when people are working in different timezones, the application will render different timezone dates. Need to correct previous people's code.

Currently cannot convert these lines to Moment, working with Date in the current codebase.

Also, would this be a proper solution? tzutil /s "Pacific Standard Time" , just learned about this in google

https://learn.microsoft.com/en-us/previous-versions/windows/it-pro/windows-server-2012-r2-and-2012/hh875624(v=ws.11)


Solution

  • I totally agree with @Adrian Brand. Also, it is not an Angular problem. It is more like how you handle your date time on your application.

    From my experience. It is always tricky to do this date-time stuff with build-in JavaScript Date.

    Also, for handling the Pacific Time, you might need to handle the daylight saving. Which is another problem on its own.

    The Pacific Time Zone (PT) is a time zone encompassing parts of western Canada, the western United States, and western Mexico. Places in this zone observe standard time by subtracting eight hours from Coordinated Universal Time (UTC−08:00). During daylight saving time, a time offset of UTC−07:00 is used.

    I assume you still send the data as the ISO format to the server.


    So I am in Singapore, see the below result for a normal Date constructor.

    1. var date = new Date(2019, 3, 5). //Fri Apr 05 2019 00:00:00 GMT+0800 (Singapore Standard Time)
    2. date.toISOString() //2019-04-04T16:00:00.000Z. Because Singapore is in +08:00 which is 8 hours ahead of UTC.

    So if you want always do new Date to result in PST time, which mean

    1. var date = new Date(2019, 3, 5) // Fri Apr 05 2019 00:00:00 GMT-0700 (Pacific Standard Time)
    2. date.toISOString() //2019-04-05T08:00:00.000Z. Because PST is at -08:00, 8 hours behind the UTC. The daylight saving topic of -07:00, I leave it for you.

    You will either need to

    1. Override the Date constructor, which is not recommended at all.
    2. Add a new method to the Date construction for displaying or give you a correct ISO format but consider the PST Time zone. Which is involving some string replacement and some math for offset calculation.

    Add a method to display string in PST

    If you do the constructor with an exact date as var date = new Date(2019, 3, 5). You can just add a new method call toPSTString() and use regex to replace the text inside () to Pacific Standard Time and the GMT+xxx to GMT-08:00 Because the value of the date is absolute.

    Date.prototype.toPSTString = function () {
      let date = this.toString();
      //date.replace.... easy part, you could use Regex to do it
      return date;
    };
    

    But if you passed in the constructor the date in the ISO String format or a number of milliseconds. It will be very tricky to handle. For instance, if you do new Date("2019-04-05T07:00:00.000Z"), what do you want to see?

    See below for how I output the ISO String based on the offset difference. It might give you some idea/

    Add a method to get the string in ISO format that consider the PST -08:00 time zone

    new Date will always work in your local machine timezone. So If I am in Singapore, I do new Date(2019, 3, 5).toISOString(), it will always give me 2019-04-04T16:00:00.000Z, not the 2019-04-05T08:00:00.000Z as you expected.

    You could also overwrite the JS function to output the UTC date but with consideration of PST time.

    Date.prototype.toPSTString = function () {
      function convertMinuteToMillisecond(mins) {
        return mins * 60 * 1000;
      }
      let localDateOffsetToUtc = this.getTimezoneOffset(); //the offset between the user local timezone with UTC. In my use case of Singapore, it give me -480.
      const offSetBetweenPSTAndUTC = 480;
      let offsetBetweenPSTAndLocal = offSetBetweenPSTAndUTC - localDateOffsetToUtc;
      let newDate = new Date(
        this.getTime() + convertMinuteToMillisecond(offsetBetweenPSTAndLocal)
      );
      return newDate.toISOString();
    };
    
    var date = new Date(2019, 3, 5);
    date.toISOString(); //"2019-04-04T16:00:00.000Z" Singapore
    date.toPSTString(); //"2019-04-05T08:00:00.000Z" PST
    

    The output looks correct. I haven't really tested it but hope you can get the idea.


    But usually, if you are in Singapore, you wanted to see the date in Singapore timezone. Nobody cares about PST timezone. Same if you are in London, you don't want to see the time in Singapore or PST timezone. I think you might want to think about that. Because If your application is growing up, it is getting more difficult to fix this kind of problem.

    I wrote about how I handle the timezone and locale in my blog. In my use case, I use moment.js and also, the server side need to support me on that. If you want to have more idea, you can take a look too.