Get offset from Utc on any system/time zone

StewartBW 1,830 Reputation points
2024-08-03T07:42:23.7333333+00:00

Hello experts,

Need to get the current system's time zone offset from UTC:

tz

This:

TimeZone.CurrentTimeZone.GetUtcOffset(Now.Date).TotalHours.ToString

Will not show the correct value when in the daylight saving period.

This one seems to work correctly:

TimeZoneInfo.Local.BaseUtcOffset.ToString

So 2 questions, is TimeZoneInfo.Local.BaseUtcOffset.ToString always working as expected on all time zones and both in standard / daylight time?

Second, this returns "-05:00:00", is there a formatter to get it as "-05:00" ?

And show positive offset "14:00:00" as "+14:00".

Thanks in advance :)

Developer technologies | VB
Developer technologies | C#
{count} votes

1 answer

Sort by: Most helpful
  1. Karen Payne MVP 35,586 Reputation points Volunteer Moderator
    2024-08-03T11:02:53.2033333+00:00

    Check out NodaTime NuGet package.

    using NodaTime;
    
    namespace TODO;
    /// <summary>
    ///
    /// Patterns for Offset values
    /// https://nodatime.org/3.1.x/userguide/offset-patterns
    ///
    /// Time zone list
    /// https://nodatime.org/TimeZones
    /// https://gist.github.com/jrolstad/5ca7d78dbfe182d7c1be
    /// </summary>
    internal static class TimeOperations
    {
        private static string TimeZoneOffset(string timeZoneId, DateTime dateTimeUtc)
        {
            
            Instant instant = Instant.FromDateTimeUtc(dateTimeUtc);
            DateTimeZone zone = DateTimeZoneProviders.Tzdb[timeZoneId];
    
            ZonedDateTime dateTime = new ZonedDateTime(instant, zone);
            var daylightSavings = dateTime.IsDaylightSavingsTime();
            Offset offset = daylightSavings? zone.MinOffset : zone.MaxOffset;
            return offset.ToString("m", null);
        }
    
        private static bool IsDaylightSavingsTime(this ZonedDateTime zonedDateTime)
        {
            var instant = zonedDateTime.ToInstant();
            var zoneInterval = zonedDateTime.Zone.GetZoneInterval(instant);
            return zoneInterval.Savings != Offset.Zero;
        }
    
        public static DateTime GetSysDateTimeNow(string zone = "US/Pacific")
        {
            Instant now = SystemClock.Instance.GetCurrentInstant();
            return now.InZone(DateTimeZoneProviders.Tzdb[zone]).ToDateTimeUnspecified();
        }
        public static string Cancun()
        {
            const string timeZoneId = "America/Cancun";
            var offset = TimeZoneOffset(timeZoneId, DateTime.SpecifyKind(GetSysDateTimeNow(timeZoneId), DateTimeKind.Utc));
            return offset;
        }
    
        public static string Local()
        {
            const string timeZoneId = "US/Pacific";
            var offset = TimeZoneOffset(timeZoneId, DateTime.SpecifyKind(GetSysDateTimeNow(), DateTimeKind.Utc));
            return offset;
        }
    
        public static string USEastern()
        {
            const string timeZoneId = "US/Eastern";
            var offset = TimeZoneOffset(timeZoneId, DateTime.SpecifyKind(GetSysDateTimeNow(timeZoneId), DateTimeKind.Utc));
            return offset;
        }
    }
    
    
    0 comments No comments

Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.