Calendar event in MS Graph API can't set timezone Mountain Standard Time - timezone

I am trying to build a select element and add several timezones in United States.
Able to find EST, CST, PST timezones in us & canada, but was not able to find MST(Mountain Standard Time, UTC-7).
Regarding the official document, it says that the timeZone property can be set to any of the time zones currently supported by Windows.
If I have a look at the date/time setting on windows 10, I can see the MST timezone option.
And also if I check this document, it has not MST timezone as well.
Should I just use Mountain Standard Time although it is not in the documents?

Generally speaking, most operations in the Microsoft Graph API that work with time zones will accept any valid Windows or IANA time zone identifier.
If you like, you can call the supportedTimeZones API, to get a complete list of those that are available on the server at any time. This might be useful in such cases where a new time zone is established but not yet installed, but in most cases you can just use any of the standard lists.
A list of Windows time zone identifiers and their display names can be obtained by calling tzutil /l from a Windows command prompt. You can also do this from .NET using TimeZoneInfo.GetSystemTimeZones (using the Id and DisplayName properties).
A list of IANA time zone identifiers can be found on Wikipedia, or from a variety of other sources.
Assuming you want to build a list of time zones for the United States only (not including US Territories), you will need at minimum the following:
Using Windows IDs:
Id Windows Display Name (English)
----------------------------------------------------------------------------
"Eastern Standard Time" "(UTC-05:00) Eastern Time (US & Canada)"
"Central Standard Time" "(UTC-06:00) Central Time (US & Canada)"
"Mountain Standard Time" "(UTC-07:00) Mountain Time (US & Canada)"
"US Mountain Standard Time" "(UTC-07:00) Arizona"
"Pacific Standard Time" "(UTC-08:00) Pacific Time (US & Canada)"
"Alaskan Standard Time" "(UTC-09:00) Alaska"
"Aleutian Standard Time" "(UTC-10:00) Aleutian Islands"
"Hawaiian Standard Time" "(UTC-10:00) Hawaii"
Using IANA IDs:
"America/New_York"
"America/Chicago"
"America/Denver"
"America/Phoenix"
"America/Los_Angeles"
"America/Anchorage"
"America/Adak"
"Pacific/Honolulu"
With regard to the documentation you referred to in your question:
The list of IANA identifiers in the Graph API doc is incomplete, and IMHO that doc needs to be re-written.
The list of Windows identifiers in this doc is intentionally incomplete, as it isn't a list of every supported time zone but rather a list of the default time zone by region on a new Windows installation.

Related

EWS TimeZone not found error - localization issue?

We have the following situation with a client when synchronizing Exchange calendar with EWS:
On the Win 10 client computer, calling GetTimeZoneInformation returns TIME_ZONE_ID_DAYLIGHT, i.e. 'The system is operating in the range covered by the DaylightDate member of the TIME_ZONE_INFORMATION structure.'
The StandardName is: W. Europe Standard Time
The DaylightName is: W. Europe Daylight Time
IIRC correctly, I now need to search through the Dlt entries of HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Time Zones\ to determine the root key name for the time zone.
But 'W. Europe Daylight Time' is not present: There are 139 entries but none of them has a Dlt entry named 'W. Europe Daylight Time'
So my code can't convert to the proper root key name and puts 'W. Europe Daylight Time' in EWS SOAP calls like this:
<soapenv:Envelope
xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:typ="http://schemas.microsoft.com/exchange/services/2006/types"
xmlns:mes="http://schemas.microsoft.com/exchange/services/2006/messages">
<soapenv:Header>
<typ:RequestServerVersion Version="Exchange2013"/>
<typ:MailboxCulture>en-US</typ:MailboxCulture>
<typ:TimeZoneContext>
<typ:TimeZoneDefinition Id="W. Europe Daylight Time"/>
</typ:TimeZoneContext>
</soapenv:Header>
<soapenv:Body>
<mes:ResolveNames ReturnFullContactData="1" SearchScope="ActiveDirectory">
<mes:UnresolvedEntry>someone#somewhere.com</mes:UnresolvedEntry>
</mes:ResolveNames>
</soapenv:Body>
</soapenv:Envelope>
... and these fail with errors like:
GetCalendarFolder (calendar): FaultInBody: A time zone with the specified ID could not be found.
Details: ErrorTimeZone Id: W. Europe Daylight Time
On the client machine, searching the registry for 'W. Europe', I find one entry that says:
RootKeyName: W. Europe Standard Time
DisplayName: (UTC+01:00) Amsterdam, Berlijn, Bern, Rome, Stockholm, Wenen
StandardName: West-Europa (standaardtijd)
DaylightName: West-Europa (zomertijd)
This machine has the following language settings:
Default system UI language : en-US
System locale : nl-NL
Default time zone : W. Europe Standard Time
Installed language(s): en-US
Type : Fully localized language.
Installed language(s): nl-NL
Type : Partially localized language, MUI type.
Fallback Languages en-US
My suspicion is that these 'localized'(?) StandardName/DaylightName registry values prevent me from properly looking up the 'W. Europe Standard Time' time zone ID.
FWIW, the Exchange server has:
TIME_ZONE_ID_DAYLIGHT
StandardName: W. Europe Standard Time
DaylightName: W. Europe Daylight Time
and does have a registry entry
RootKeyName: W. Europe Standard Time
DisplayName: (UTC+01:00) Amsterdam, Berlin, Bern, Rome, Stockholm, Vienna
StandardName: W. Europe Standard Time
DaylightName: W. Europe Daylight Time
How can I resolve this?
You've got two separate concepts mixed together.
The ID of the time zone is "W. Europe Standard Time". It isn't localized for other languages, and it does not change for daylight saving time. The same string is used to cover both standard time and daylight time, despite the word Standard being in it. (This is a common source of confusion, and is also covered in the timezone tag wiki.)
The StandardName, DaylightName, and DisplayName are localized by the OS language, and are not identifiers. They are meant for human display only. For example, the DisplayName is generally paired with the ID in drop-down lists to pick a time zone. The display name would be shown to the user, and the corresponding ID would be saved in the application. The StandardName and DaylightName are used for human display in conjunction with a specific date and time, depending on which is in effect.
That GetTimeZoneInformation returns TIME_ZONE_ID_DAYLIGHT is irrelevant. You should not be using it to mutate the name of the ID (i.e., don't replace "standard" with "daylight").
Ultimately it sounds like you just need the user's time zone id. There are lots of ways to get that. Any of the following would work:
Using the Win32 API, you can call GetDynamicTimeZoneInformation, which returns a DYNAMIC_TIME_ZONE_INFORMATION structure. The TimeZoneKeyName is the ID you should use.
You can get this directly from the registry at HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\TimeZoneInformation in the TimeZoneKeyName value
If you are writing .NET code, you can get it from TimeZoneInfo.Local.Id
From the command line, you can call tzutil /g

Where does Rails store start and end dates of daylight savings period?

I am using Rails 5 and my app's timezone is set to Brasilia.
Right now it's winter (no daylight saving) in Brazil so
Time.current.dst? returns false
But in Brazil daylight savings starts at 21/10/2018, so when I do
(Time.current + 10.days).dst? I expect it ti return true, but it returns false.
Is there a table where I can check what dates Rails considers for start end and of daylight savings in each timezone?
Or as another example. I understand that UTC does not have daylight savings. So
Time.current.strftime(%Z) return -3 which is the correct diference between UTC and current Brazil time.
But when I do
(Time.current+10.days).strftime(%Z) is still returns -3 but that date is after Brazil has changed time, so it should be -2. Something seems to be wrong.
Per the Rails documentation:
The TimeZone class serves as a wrapper around TZInfo::Timezone instances.
TZInfo::Timezone instances are provided via the Ruby TZInfo gem. The data for TZInfo is provided in a separate TZInfo-Data package. Staying current with that will keep your time zone data accurate. This data is sourced from the IANA time zone database (TZDB), as it is with most other programming languages.
Note that it is generally preferable to use the IANA time zone identifiers with tzinfo gem directly, as Rails time zones are limited to "a meaningful subset of 134 zones" (per the same docs), but contain many duplications and omissions, and provide no criteria as to what "meaningful" means. More on this in the timezone tag wiki (near the end).
Also, Brazil starts DST on November 4th in 2018, not on October 21st. See here and here. This change was reflected in IANA TZDB 2018a, which was reflected in TZInfo-Data v1.2018.1. If you have that version or newer, then you have the newer, correct Brazil DST date, and thus explains your results.
There was recently a plan to push Brazil's DST date out even further to November 18th, but the government retracted that plan before it ever became official, and thus was never represented in the time zone data.

How would I add support for timezone in my application?

We're currently storing local datetime of Pacific/Hawaii in the database. Assuming that I cannot change these dates to UTC, what information do I need to add to support timezone?
My thoughts are:
First, add a timezone field to indicate which timezone the user is viewing from. (The user will select this from a dropdown)
Second, add timezone field to indicate the timezone (Pacific/Hawaii) of the current datetimes values in the database.
Third, add offset to cover DST hours
So say a user from America/Los_Angeles views the site, it would pull the datetime from the database, append the offset and apply the timezone of Hawaii before converting it to Los Angeles time. For any calculation or comparison I would convert the Hawaii time to UTC first, then convert the UTC result to Los Angeles. Am I missing anything?
Your question is very broad, and without knowing more about your application, the platform, how you use collect dates and times, what they represent, etc., I can only speak in generalities.
Storing in UTC is recommended, but that is just by convention. The main necessities are that the time zone you are storing data in does not have DST (which Hawaii hasn't since 1947), and that you do not rely on your computer's operating system or environment settings to determine what time zone to use. You can use the Hawaiian time zone if you must. Be sure you document it somewhere though! It will surely be a surprise to anyone else that comes along in the lifecycle of the application.
While it would wolk, there is absolutely no advantage to doing this. You could just as easily convert your data to UTC when you roll out these changes and use UTC going forward. (That would be the preferred approach.)
The IANA time zone ID for Hawaii is "Pacific/Honolulu". If you're on Windows/.Net, the TimeZoneInfo ID is "Hawaiian Standard Time". Either way, they must be spelled, cased, and punctuated in exactly that manner.
Make sure you understand that a Time Zone Offset and a Time Zone are two different concepts. While Hawaii may use a fixed offset of -10:00, that's not guaranteed for most time zones. Please read the timezone tag wiki for further details.
You should probably not attempt to implement your own time zone logic. There are libraries for this in almost every language. Look to see what is appropriate for your platform. (If you provide details, I can offer suggestions.)
It would be a more robust solution to store the times as UTC time as time zone is local to the specific PC that is displaying the data. In your case if you store time plus offset how can you decide which offset to store? Not a workable solution if multiple time zones are involved.

How to specify EDT (daylight saving time) to Exchange Web Services (XML not managed)?

The article here:
http://msdn.microsoft.com/en-us/library/exchange/bb738399(v=exchg.80).aspx
in the section "Use Registry Key Names for TimeZoneNames", tells me that when I can create a calendar item in Exchange, I can pass it the name of a timezone. This is sort-of working, but how do I name "Eastern Daylight Time"?
Only 'US Eastern Standard Time' is accepted as valid. In works in that I schedule something for say 14:00, when it displays in my Google calendar I see it is displaying at 15:00 EDT, so it used the EST timezone I passed in. Problem is that it sends out reminder emails with the time displayed in "US Eastern Standard Time".
When: Friday, August 30, 2013 2:00 PM-3:00 PM. US Eastern Standard Time
... rest of email ...
I don't want that text like that. It should say "US Eastern Daylight Time" or something like that.
The soap request contains XML like:
<t:CalendarItem xmlns="http://schemas.microsoft.com/exchange/services/2006/types">
...
<Start>2013-08-30T14:00:00</Start>
<t:MeetingTimeZone TimeZoneName="US Eastern Standard Time"></t:MeetingTimeZone>
<t:CalendarItem>
This is Exchange Server 2007, SP1.
Here is an image of what the email looks like, in Gmail. (The times are bit different from my above example, sorry). The appointment time is correct, but it in the email body it calls it "Eastern Standard Time", which is not right -- it should be "Eastern Daylight Time" or something like that. (Note that line is part of the email body generated by the Exchange Server, it is not something made up by Gmail.)
The Windows Time Zone key you're looking for is exactly: "Eastern Standard Time". This covers the US Eastern time zone, inclusive of both Eastern Standard Time and Eastern Daylight Time. It has a display name of "(UTC-05:00) Eastern Time (US & Canada)".
This is actually one of the examples I call out in the timezone tag wiki - which you should read if you haven't already.
The other key you found "US Eastern Standard Time" is actually for the zone with the display name of "(UTC-05:00) Indiana (East)" - which is segregated for historical reasons and is now obsolete. (See the Wikipedia entry on Time in Indiana, and Microsoft's KB article on this if you are interested in why.)
If you look in the Windows Registry at HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Time Zones, you will see the valid keys. In each key, you will see the Display name that corresponds to each. This explains how they appear when you change your time zone in Windows.
With regards to Exchange Web Services, in the article you mentioned, it does talk about how you can use the key name. But it also talks about how you can pass much more information in the MeetingTimeZone element and use a display name instead.
If interoperability with Google Calendar (and others) is important, you might consider passing the IANA time zone name in the TimeZoneName attribute - in this case it would be America/New_York. You would still need to provide the <BaseOffset>, <Standard>, and <Daylight> elements, so that it will work right on Windows. See the MeetingTimeZone section in that article.
I should state that I haven't tried this approach myself, but it appears from the documentation that if you provide those elements that the TimeZoneName becomes less important to Windows but would still get passed along.
You should certainly be able to pass it using Microsoft's approach:
<MeetingTimeZone TimeZoneName="(GMT-05:00) Eastern Time (US & Canada)">
<BaseOffset>P0DT5H0M0.0S</BaseOffset>
<Standard>
<Offset>P0DT0H0M0.0S</Offset>
<RelativeYearlyRecurrence>
<DaysOfWeek>Sunday</DaysOfWeek>
<DayOfWeekIndex>First</DayOfWeekIndex>
<Month>November</Month>
</RelativeYearlyRecurrence>
<Time>02:00:00.0000000</Time>
</Standard>
<Daylight>
<Offset>-P0DT1H0M0.0S</Offset>
<RelativeYearlyRecurrence>
<DaysOfWeek>Sunday</DaysOfWeek>
<DayOfWeekIndex>Second</DayOfWeekIndex>
<Month>March</Month>
</RelativeYearlyRecurrence>
<Time>02:00:00.0000000</Time>
</Daylight>
</MeetingTimeZone>
What I'm suggesting is that you tweak it slightly by passing the IANA zone name instead and see if it behaves properly with Gmail and Google Calendar:
<MeetingTimeZone TimeZoneName="America/New_York">
<BaseOffset>P0DT5H0M0.0S</BaseOffset>
<Standard>
<Offset>P0DT0H0M0.0S</Offset>
<RelativeYearlyRecurrence>
<DaysOfWeek>Sunday</DaysOfWeek>
<DayOfWeekIndex>First</DayOfWeekIndex>
<Month>November</Month>
</RelativeYearlyRecurrence>
<Time>02:00:00.0000000</Time>
</Standard>
<Daylight>
<Offset>-P0DT1H0M0.0S</Offset>
<RelativeYearlyRecurrence>
<DaysOfWeek>Sunday</DaysOfWeek>
<DayOfWeekIndex>Second</DayOfWeekIndex>
<Month>March</Month>
</RelativeYearlyRecurrence>
<Time>02:00:00.0000000</Time>
</Daylight>
</MeetingTimeZone>

UTC Time, Timezones, Daylight Savings, and Daylight Savings switchover dates

I'm building an application which will be able to send emails at any specific local time to any place in the world.
For example, my daily schedule (localtime):
8:00 AM - Send email to John in Toronto, Canada
9:15 AM Western Standard Time (Australia) - Send email to Bob in Perth, Australia
10:12 PM - Send email to Anas in Rabat, Morocco
I want to be able to execute this code on and Amazon EC2 server in a single location (e.g. São Paulo, Brasil).
I also know that Toronto is in Eastern Standard Time, (UTC - 5h) , but from March 11, 2012 to November 4, 2012, it is in Eastern Daylight Time (UTC - 4h).
I also know that Perth is in Western Standard Time (UTC + 8h), with no daylight savings.
I also know that Rabat is in Western European Time (UTC), but from April 29,2012 to July 20,2012, and August 19,2012 to Sept 30, 2012 it is in in West European Summer Time (UTC + 1h)
To keep track of these combinations of time zone, daylight savings, et cetera, I will, of course insist that all internal server times be in UTC. However, I need some way to keep track of when and how each time-zone jurisdiction switches time zones because of Daylight Savings or (in the case of Rabat) Ramadan, and then adjust my crontabs to accommodate these changes.
Is there an authoritative web service or set of tables somewhere which would help me keep these timezone changes in sync with my desire to deliver emails at the same local time every day to users in different time zones with different switchover dates for daylight savings?
Most programming languages give you access to timezone conversion functions. The most rudimentary ones only work between UTC and the "local" timezone of the server, so you will need a full-featured one, such as pytz for Python that will let you specify a local time with a timezone name (e.g. "America/Toronto") and convert it to UTC for you. Given that, you don't need to worry about the UTC offsets of different timezones (including historical offsets if they've changed) nor DST start end end times: the library will take care of it for you. Just make sure you have the latest database, which comes in the tzdata package.
As for your crontab, you're probably best off if the local timezone on the server that runs cron is UTC, that way you can put UTC times directly in the crontab. On the other hand, depending on the volume of events that you have, I would advice just having cron run your code at regular schedules intervals (such as every 5 minutes) and then your code figures out what events need to be triggered based on the current UTC time and the contents of your database. Then it doesn't matter what the timezone of the server is.
Is there an authoritative web service or set of tables somewhere ...
No, there is nothing "authoritative", but there is something close. It's called the TZ database, and it is currently under the oversight of IANA. Its home page is here.
It is also known as tzdata, zoneinfo, timezonedb, tzdb, the Olson Database, or the IANA Time Zone Database.
There are implementations for just about every language and platform you can imagine. You can read more in the tz-link file from the tzdb, and in the timezone tag wiki, here on StackOverflow.

Resources