Search code examples
c#timezonetimezone-offsetgmt

Difference between Staging and production sent datetime in invoice


We have GMT time zone for staging and production. but when the code execute it shows correct result in staging and incorrect in production.

bool checkTimeBSTorGMT = TimeZoneInfo.Local.IsDaylightSavingTime(records.GetDateTimeOrEmpty("notification_date"));
if (checkTimeBSTorGMT == true)
{
    DateTime dt = new DateTime();
    dt = records.GetDateTimeOrEmpty("notification_date");
    dt = dt.AddHours(1);
    instance.SentDateTime = dt;
}
else
{
    instance.SentDateTime = records.GetDateTimeOrEmpty("notification_date");
}

My code is as above. I want that it should fetch correct date according to the user local machine across the world.


Solution

  • I would not be trying to roll my own times and timezones code. It will end in tears. (Is the daylight savings bias always 60 minutes? Your code assumes so)

    Here is a better way to convert between two timezones. I've included some of the more unusual timezones in there.

    using System;
    
    public class Program
    {
        private static void DisplayTimeInTimeZone(DateTime timeOfInterestUTC, string timezoneId)
        {
            Console.WriteLine($"UTC Time {timeOfInterestUTC} in {timezoneId} is {TimeZoneInfo.ConvertTime(timeOfInterestUTC, TimeZoneInfo.FindSystemTimeZoneById(timezoneId))}");
        }
    
        public static void Main()
        {
            /*
            // In case you were wondering what Timezones are available
            foreach (var tz in TimeZoneInfo.GetSystemTimeZones())
            {
                Console.WriteLine(tz.Id);
            }
            */
            DateTime someArbitraryLocalTime = new DateTime(2018, 2, 15, 9, 30, 0);
            DateTime someArbitraryTimeAsUTC = TimeZoneInfo.ConvertTimeToUtc(someArbitraryLocalTime, TimeZoneInfo.FindSystemTimeZoneById("US Eastern Standard Time"));
            Console.WriteLine($"US Eastern Standard Time {someArbitraryLocalTime} in UTC is {someArbitraryTimeAsUTC}");
            DisplayTimeInTimeZone(someArbitraryTimeAsUTC, "GMT Standard Time");
            DisplayTimeInTimeZone(someArbitraryTimeAsUTC, "Cen. Australia Standard Time");
            DisplayTimeInTimeZone(someArbitraryTimeAsUTC, "Chatham Islands Standard Time");
            DisplayTimeInTimeZone(someArbitraryTimeAsUTC, TimeZoneInfo.Local.Id);
        }
    }
    

    I'm unclear about what notification_date and SentDateTime are with respect to time zones. If they are already UTC, then it is just the ConvertTime method you need to translate it.

    If it is local to a reference timezone, you will need to use ConvertTimeToUtc first. If it comes from user input, be aware that some times don't exist for time zones that have daylight savings (when DST starts, we set our clocks forwards an hour, so any time in that "hour" is undefined). Conversely, the conversion is ambiguous at the end of DST because that "hour" happens twice.