Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Getting the Arizona Standard Time in .net

Tags:

timezone

c#

.net

I have an application in which time zones are treated as string, by using the system name so we can make an actual System.TimeZoneInfo object by doing:

var tz = TimeZoneInfo.FindSystemTimeZoneById(timeZone);

Such values are persisted to DB, now we are facing an issue where one such object is requested to be on Arizona Time which is not a standard timezone. From what I have investigated the Arizona Time changes Time Zones due to the fact that it doesn't observes "Day Light Savings".

I am looking for a way to set one value in DB so that there is no need to change it according to day light savings changes.

Is there a way to do this?

Even if I have to change a bit the code to get the TimeZoneInfo object. What really matters to me is a way to determine the actual timezone corresponding to Arizona Time

like image 318
Luiso Avatar asked Feb 23 '17 19:02

Luiso


People also ask

Is Arizona on MST or PST right now?

Time Zone. Arizona is on Mountain Standard Time .

Is AZ the same time as PST?

When daylight saving is not active, the time in Phoenix and Albuquerque, New Mexico is the same (Mountain Standard Time), and both are one hour ahead of Los Angeles, California (Pacific Standard Time).

Is AZ time the same as CA right now?

The time zone for the capital Phoenix is used here. California has the same time as Arizona.


2 Answers

About Arizona time zones

From timeanddate.com:

There is a common misconception that Arizona is on Pacific Daylight Time (PDT) during the summer and on Mountain Standard Time (MST) during the winter. Because MST and PDT have the same UTC offset of minus 7 hours (UTC-7), Arizona has the same local time as neighboring states California and Nevada during the summer season. Although the time is the same, Arizona uses standard time (MST) all year. “Daylight” time zones, such as MDT, are mostly used for areas that switch to DST every year

IANA (tz database) time zone database contains two time zones for Arizona:

  • America/Phoenix (Mountain Standard Time - Arizona, except Navajo), which does not observe daylight saving changes (DST), and
  • America/Shiprock, which observes DST.

Arizona time zones in .NET

Depending on your users' exact location in Arizona, you should use either America/Phoenix or America/Shiprock time zone, so you will need two values in the database. However, if you try to get time zones with TimeZoneInfo.FindSystemTimeZoneById using tz database names, you will get System.TimeZoneNotFoundException.

In order to get Arizona time zone that does not observe DST (America/Phoenix), you can use:

TimeZoneInfo.FindSystemTimeZoneById("US Mountain Standard Time")

In order to get Arizona time zone that does observe DST (America/Shiprock), you can use:

TimeZoneInfo.FindSystemTimeZoneById("Mountain Standard Time")

So, you would have both ids in your database, US Mountain Standard Time and Mountain Standard Time, or alternatively some other strings that you would later map to these .NET time zone ids.

Check out NodaTime, it can help you a lot when it comes to dealing with date, time and time zones.

And finally, here is a sample program (with NodaTime) that demonstrates the difference between .NET US Mountain Standard Time (America/Phoenix, Arizona without DST) and Mountain Standard Time (America/Shiprock, Arizona with DST).

using System;

using NodaTime;
using NodaTime.TimeZones;

namespace TimeZoneExample
{
    class Program
    {
        static void Main(string[] args)
        {
            // Arizona without daylight saving time (TZ: America/Phoenix)
            var mstWithoutDstTz = TimeZoneInfo.FindSystemTimeZoneById("US Mountain Standard Time");

            // Arizona with daylight saving time (TZ: America/Shiprock)
            var mstWithDstTz = TimeZoneInfo.FindSystemTimeZoneById("Mountain Standard Time");

            // NodaTime BclDateTimeZone for Arizona without daylight saving time
            var mstWithoutDstNodaTz = BclDateTimeZone.FromTimeZoneInfo(mstWithoutDstTz);

            // NodaTime BclDateTimeZone for Arizona with daylight saving time
            var mstWithDstNodaTz = BclDateTimeZone.FromTimeZoneInfo(mstWithDstTz);

            // January 1, 2017, 15:00, local winter date
            var localWinterDate = new LocalDateTime(2017, 01, 01, 15, 00);

            // NodaTime ZonedDateTime for Arizona without daylight saving time: January 1, 2017, 15:00
            var winterTimeWithoutDst = mstWithoutDstNodaTz.AtStrictly(localWinterDate);

            // NodaTime ZonedDateTime for Arizona with daylight saving time: January 1, 2017, 15:00
            var winterTimeWithDst = mstWithDstNodaTz.AtStrictly(localWinterDate);

            // Both time zones have the same time during winter
            Console.WriteLine($"Winter w/o DST: {winterTimeWithoutDst}"); // 2017-01-01T15:00:00 US Mountain Standard Time (-07)
            Console.WriteLine($"Winter w/ DST: {winterTimeWithDst}"); // 2017-01-01T15:00:00 Mountain Standard Time (-07)

            // add 180 days to get June 30, 2017
            var sixMonthsToSummer = Duration.FromTimeSpan(new TimeSpan(180, 0, 0, 0));

            // During summer, e.g. on June 30, Arizona without daylight saving time is 1 hour behind.
            Console.WriteLine($"Summer w/o DST: {winterTimeWithoutDst + sixMonthsToSummer}"); // 2017-06-30T15:00:00 US Mountain Standard Time (-07)
            Console.WriteLine($"Summer w/ DST: {winterTimeWithDst + sixMonthsToSummer}"); // 2017-06-30T16:00:00 Mountain Standard Time (-06)
        }
    }
}
like image 107
Nikola Prokopić Avatar answered Oct 20 '22 03:10

Nikola Prokopić


If I understand your problem correctly, you want to create a custom time zone representing "Arizona Time" which has a constant offset from UTC regardless the date of the year.

If so, you should be able to use the static method

TimeZoneInfo.CreateCustomTimeZone

Just set the TimeSpan to the number of hours from UTC that you need it to be (-7 hours from what I can tell).

https://msdn.microsoft.com/en-us/library/bb309898(v=vs.110).aspx

EDIT: You might also have some success by simply using the named timezone

"US Mountain Standard Time" 

which should represent the same.

like image 3
wiesener Avatar answered Oct 20 '22 01:10

wiesener