static userTimezoneToSpecifiedTimeZone(date: Date, time: string, timeZone: string): Date {
// Major timeZone's for Australia and their offset values in hours
// NOTE Darwin etc -> I'm not sure 9.5 or 10.5 will work
const DST_OFFSETS = {
'Australia/Sydney': [11, 10],
'Australia/Brisbane': [11, 10],
'Australia/Melbourne': [11, 10],
'Australia/Canberra': [11, 10],
'Australia/Darwin': [10.5, 9.5],
'Australia/Adelaide': [10.5, 9.5],
'Australia/BrokenHill': [10.5, 9.5],
'Australia/Perth': [9, 8]
};
// Calculate the offset depending on if the date is in is DST or not
const [dstStartOffset, dstEndOffset] = DST_OFFSETS[timeZone];
const daylightSavingOffset = this.isDaylightSavingTime(date, timeZone) ? dstStartOffset : dstEndOffset;
const hoursAndMinutes = time.split(':');
// Collect raw values to create date object
let year = date.getFullYear();
let month = date.getMonth();
let day = date.getDate();
let hours = Number(hoursAndMinutes[0]);
const minutes = Number(hoursAndMinutes[1]);
// We then convert these values to the timezone's UTC by adding the offset
// i.e. Sydney is 10/11 hours ahead of GMT, so we need to minus 10/11 hours to get GMT.
// allow for the GMT being the day, month and year before when subtracting the offset.
if ((hours - daylightSavingOffset) < 0) {
hours = 24 + (hours - daylightSavingOffset);
day--;
if ((month - 1) < 0) {
year = year--;
month = 11;
}
} else {
hours = hours - daylightSavingOffset;
}
// Create the date object using the UTC value we created above.
const returnDate = new Date(Date.UTC(year, month, day, hours, minutes, 0));
// console.log(`${timeZone} Timezone from FormHelper-> ` + returnDate.toLocaleString(undefined, {timeZone: timeZone}))
return returnDate;
}
static isDaylightSavingTime(date: Date, timeZone: string): boolean {
// Get the time zone offset for the specified date
const offset = new Date(date.toLocaleString('en-US', { timeZone })).getTimezoneOffset();
// Calculate the daylight saving time start and end dates for the current year
const year = date.getFullYear();
const dstStart = new Date(Date.UTC(year, 9, 1, 16)).toLocaleString('en-US', { timeZone });
const dstEnd = new Date(Date.UTC(year, 3, 1, 16)).toLocaleString('en-US', { timeZone });
// Determine if the specified date falls within the daylight saving time period
return offset < new Date(dstEnd).getTimezoneOffset() && offset >= new Date(dstStart).getTimezoneOffset();
}
Comments