normalizeDateFromController function
Normalizes the given date from the controller into the user's local time,
based on the difference between the controllerTime and the currentTime.
The resulting date will be based on the user's timezone, instead of the controller's timezone. This must only be used for dates that are generated by the controller (and not by the server, for example). Normally this means dates coming from parameters such as the last ran date.
Implementation
DateTime? normalizeDateFromController(
DateTime? date,
DateTime? controllerTime,
DateTime currentTime,
) {
if (date == null || controllerTime == null) {
return date;
}
// Backend currently stores dates based on the controller's time, but then
// sends back the dates using the server's timezone.
//
// For example, an event that happens 5PM ET from the controller is stored
// in the backend as 5PM (with no timezone value). Then, the backend service
// sends the time as 5PM CT. See below table.
//
// 5PM EST 5PM 5PM CST / 6PM EST 3 PM PST
// Event time Time stored in Time sent by Time displayed
// from controller database backend to user
//
// The frontend can correctly convert the time to the user's local
// timezone, but we still need to correct for the difference between the
// controller's time and the server's time.
// First, get the current server time. Per Ashok, backend servers use
// US / Central Time.
final serverTzOffset = Duration(
milliseconds: tz
.getLocation('US/Central')
.timeZone(currentTime.millisecondsSinceEpoch)
.offset,
);
final tzDifference = serverTzOffset - currentTime.timeZoneOffset;
final serverTime = currentTime.add(tzDifference);
// Then get the difference between the controller time and the server.
var difference = serverTime.difference(controllerTime);
final inMinutes = difference.inMinutes;
final inHours = (inMinutes / 60.0).round();
final minutesRemainder = (inMinutes - (inHours * 60)).abs();
if (minutesRemainder <= 5) {
// If the difference is close to a multiple of an hour, round to the
// nearest hour. This means the controller time is up-to-date, but
// potentially in a different timezone.
difference = Duration(hours: inHours);
}
// Add the difference to the event date
return date.add(difference);
}