I need to make illusion of working in the selected by the user timezone. The problem that server and client code are stick to javascript date. So to achieve the requirement I have made mannualy mapping from utc to the date on the client side:
dateToServer(date) {
const momentDate = moment(date);
let serverDate = null;
if (momentDate.isValid() && date) {
const browserUtcOffset = momentDate.utcOffset();
serverDate = momentDate
.utc()
.subtract(this.clientTimeZoneOffset, 'minutes')
.add(browserUtcOffset, 'minutes')
.toDate();
}
return serverDate;
}
dateToClient(date) {
const momentDate = moment(date);
let uiDate = null;
if (momentDate.isValid() && date) {
const browserUtcOffset = momentDate.utcOffset();
uiDate = momentDate
.utc()
.subtract(browserUtcOffset, 'minutes')
.add(this.clientTimeZoneOffset, 'minutes')
.toDate();
}
return uiDate;
}
I'm adding/subtracting the browserUtcOffset, because it is adding/subtracting automatically by browser when the date is go between server and client.
It was working well, but this solution is missing handling of the DST. I'd like to check is DST active for the date and then add DST offset if need.
Here C# code, that can do this:
string timeZone = "Central Standard Time";
TimeZoneInfo timeZoneInfo = TimeZoneInfo.FindSystemTimeZoneById(timeZone);
DateTime date = new DateTime(2011, 3, 14);
Console.WriteLine(timeZoneInfo.BaseUtcOffset.TotalMinutes); // -360
Console.WriteLine(timeZoneInfo.GetUtcOffset(date).TotalMinutes); // -300
Console.WriteLine(timeZoneInfo.IsDaylightSavingTime(date)); // true
Console.WriteLine(timeZoneInfo.DaylightName);
Console.WriteLine(timeZoneInfo.SupportsDaylightSavingTime);
I have found the isDST
in the momentjs, and when I have my windows local timezone to CST and check moment([2011, 2, 14]).isDST();
in browser console I see the true. How you can see the isDST
is depends on the browser local time.
Next step try to use moment-timezone to do smth like I have done in C#. Unfortunately I don't understand how to achieve this. The first problem that as start point I have: UTC time
, Base offset(-360 in C# sample)
, timezone name: Central Standard Time
, but timezones in the moment-timezone are different.
moment.tz.names().map(name => moment.tz.zone(name)).filter(zone => zone.abbrs.find(abbr => abbr === 'CST') != null)
this code returns 68 timezones.
Why there each of them have many abbrs? What mean untils? All I want to check if UTC time in the selected timezone, which is "Central Standard Time", the daylight saving day active. See C# sample one more time :)
string timeZone = "Central Standard Time";
TimeZoneInfo timeZoneInfo = TimeZoneInfo.FindSystemTimeZoneById(timeZone);
DateTime date = new DateTime(2011, 3, 14);
Console.WriteLine(timeZoneInfo.BaseUtcOffset.TotalMinutes); //-360
Console.WriteLine(timeZoneInfo.GetUtcOffset(date).TotalMinutes); //-300
Console.WriteLine(timeZoneInfo.IsDaylightSavingTime(date)); //true, I have checked is daylightsavingtime for the date
Console.WriteLine(timeZoneInfo.DaylightName);
Console.WriteLine(timeZoneInfo.SupportsDaylightSavingTime);
The application has been written on the angularjs 1.6.3.