Microsoft Dynamics CRM 2011 | Verwendung lokaler Zeitzonencode

In Microsoft Dynamics CRM gibt es zahlreiche Anwendungsbeispiele, in denen auf Basis von DateTime-Attributen verschiedene Berechnungen durchgeführt werden sollen – so z.B. in den Offset-Berechnungen für den Arbeitszeitenkalender. Offset beschreibt die Dauer in Minuten seit Mitternacht.

In Installationsumgebungen, die in mehreren Zeitzonen operieren ergeben sich dadurch für Plug-Ins oder Workflow-Activities spezielle Herausforderungen.

Können wir über eine Abfrage noch sehr einfach an die Zeitzone eines ausgewählten Benutzers herankommen, so stellt sich die Frage, wie dies in der Praxis in eine Berechnung / Konvertierung zur aktuellen Zeit münden kann?

Stellen wir uns also vor, wir haben in einer unserer Entitäten ein Suchfeld zu einem Benutzer integriert. Gleichfalls finden wir ein DateTime-Attribut in unserer Entität. Nun wissen wir bereits, dass CRM die Datum/Zeit-Felder immer in UTC Zeit speichert.

Lesen wir daher einen Feldinhalt z.B. in einem Plug-In mit

var DateField = entity.GetAttributeValue<DateTime>(„prefix_yourfieldname“);

aus, so finden wir anstelle von 02.09.2013 08:00 Uhr lokaler Zeit (deutsche Zeitzone) den Wert 02.09.2012 06:00.

Aus einem Beispielcode im SDK wissen wir aber auch, dass wir den Zeitzonencode eines Benutzers einfach abfragen können.

var currentUserSettings = service.RetrieveMultiple(
                         new QueryExpression(UserSettings.EntityLogicalName)
                         {
                             ColumnSet = new ColumnSet(„localeid“, „timezonecode“),
                             Criteria = new FilterExpression
                             {
                                 Conditions =
                                 {
                                    new ConditionExpression(„systemuserid“, ConditionOperator.Equal, SystemUserId.Id )
                                 }
                             }
                         }).Entities[0].ToEntity<UserSettings>();

                   _timeZoneCode = currentUserSettings.TimeZoneCode;

Wenn wir diese Abfrage starten erhalten wir für o.g. Beispiel die 110 zurück. Was jedoch können wir mit diesem Zeitzonencode anstellen?

In .NET findet sich eine DateTime Konvertierung auf Basis einer TimeZoneInfo.

TimeZoneInfo localZone = TimeZoneInfo.FindSystemTimeZoneById(ID);

Leider entspricht die ID in diesem Fall jedoch nicht der 110, sondern dem String “W. Europe Standard Time”. Wir müssen uns also eine Hilfe schaffen, um von dem ermittelten Code-Wert auf den korrekten String-Wert schließen zu können.

In diesem Fall hilft uns ein Dictionary:

Dictionary<int, string> TimeZoneNames = new Dictionary<int, string>();

                    TimeZoneNames.Add(110, „W. Europe Standard Time“);
                    TimeZoneNames.Add(000, „Dateline Standard Time“);
                    TimeZoneNames.Add(001, „Samoa Standard Time“);
                    TimeZoneNames.Add(002, „Hawaiian Standard Time“);
                    TimeZoneNames.Add(003, „Alaskan Standard Time“);
                    TimeZoneNames.Add(004, „Pacific Standard Time“);
                    TimeZoneNames.Add(010, „Mountain Standard Time“);
                    TimeZoneNames.Add(013, „Mexico Standard Time 2“);
                    TimeZoneNames.Add(015, „U.S. Mountain Standard Time“);
                    TimeZoneNames.Add(020, „Central Standard Time“);
                    TimeZoneNames.Add(025, „Canada Central Standard Time“);
                    TimeZoneNames.Add(030, „Mexico Standard Time“);
                    TimeZoneNames.Add(033, „Central America Standard Time“);
                    TimeZoneNames.Add(035, „Eastern Standard Time“);
                    TimeZoneNames.Add(040, „U.S. Eastern Standard Time“);
                    TimeZoneNames.Add(045, „S.A. Pacific Standard Time“);
                    TimeZoneNames.Add(050, „Atlantic Standard Time“);
                    TimeZoneNames.Add(055, „S.A. Western Standard Time“);
                    TimeZoneNames.Add(056, „Pacific S.A. Standard Time“);
                    TimeZoneNames.Add(060, „Newfoundland and Labrador Standard Time“);
                    TimeZoneNames.Add(065, „E. South America Standard Time“);
                    TimeZoneNames.Add(070, „S.A. Eastern Standard Time“);
                    TimeZoneNames.Add(073, „Greenland Standard Time“);
                    TimeZoneNames.Add(075, „Mid-Atlantic Standard Time“);
                    TimeZoneNames.Add(080, „Azores Standard Time“);
                    TimeZoneNames.Add(083, „Cape Verde Standard Time“);
                    TimeZoneNames.Add(085, „GMT Standard Time“);
                    TimeZoneNames.Add(090, „Greenwich Standard Time“);
                    TimeZoneNames.Add(095, „Central Europe Standard Time“);
                    TimeZoneNames.Add(100, „Central European Standard Time“);
                    TimeZoneNames.Add(105, „Romance Standard Time“);
                    TimeZoneNames.Add(113, „W. Central Africa Standard Time“);
                    TimeZoneNames.Add(115, „E. Europe Standard Time“);
                    TimeZoneNames.Add(120, „Egypt Standard Time“);
                    TimeZoneNames.Add(125, „FLE Standard Time“);
                    TimeZoneNames.Add(130, „GTB Standard Time“);
                    TimeZoneNames.Add(135, „Israel Standard Time“);
                    TimeZoneNames.Add(140, „South Africa Standard Time“);
                    TimeZoneNames.Add(145, „Russian Standard Time“);
                    TimeZoneNames.Add(150, „Arab Standard Time“);
                    TimeZoneNames.Add(155, „E. Africa Standard Time“);
                    TimeZoneNames.Add(158, „Arabic Standard Time“);
                    TimeZoneNames.Add(160, „Iran Standard Time“);
                    TimeZoneNames.Add(165, „Arabian Standard Time“);
                    TimeZoneNames.Add(170, „Caucasus Standard Time“);
                    TimeZoneNames.Add(175, „Transitional Islamic State of Afghanistan Standard Time“);
                    TimeZoneNames.Add(180, „Ekaterinburg Standard Time“);
                    TimeZoneNames.Add(185, „West Asia Standard Time“);
                    TimeZoneNames.Add(190, „India Standard Time“);
                    TimeZoneNames.Add(193, „Nepal Standard Time“);
                    TimeZoneNames.Add(195, „Central Asia Standard Time“);
                    TimeZoneNames.Add(200, „Sri Lanka Standard Time“);
                    TimeZoneNames.Add(201, „N. Central Asia Standard Time“);
                    TimeZoneNames.Add(203, „Myanmar Standard Time“);
                    TimeZoneNames.Add(205, „S.E. Asia Standard Time“);
                    TimeZoneNames.Add(207, „North Asia Standard Time“);
                    TimeZoneNames.Add(210, „China Standard Time“);
                    TimeZoneNames.Add(215, „Singapore Standard Time“);
                    TimeZoneNames.Add(220, „Taipei Standard Time“);
                    TimeZoneNames.Add(225, „W. Australia Standard Time“);
                    TimeZoneNames.Add(227, „North Asia East Standard Time“);
                    TimeZoneNames.Add(230, „Korea Standard Time“);
                    TimeZoneNames.Add(235, „Tokyo Standard Time“);
                    TimeZoneNames.Add(240, „Yakutsk Standard Time“);
                    TimeZoneNames.Add(245, „A.U.S. Central Standard Time“);
                    TimeZoneNames.Add(250, „Cen. Australia Standard Time“);
                    TimeZoneNames.Add(255, „A.U.S. Eastern Standard Time“);
                    TimeZoneNames.Add(260, „E. Australia Standard Time“);
                    TimeZoneNames.Add(265, „Tasmania Standard Time“);
                    TimeZoneNames.Add(270, „Vladivostok Standard Time“);
                    TimeZoneNames.Add(275, „West Pacific Standard Time“);
                    TimeZoneNames.Add(280, „Central Pacific Standard Time“);
                    TimeZoneNames.Add(285, „Fiji Islands Standard Time“);
                    TimeZoneNames.Add(290, „New Zealand Standard Time“);
                    TimeZoneNames.Add(300, „Tonga Standard Time“);

Wenn wir diese Hilfe in unseren Programmcode integriert haben, können wir mit Hilfe von:

int tzc = Convert.ToInt32(_timeZoneCode);

                    if (TimeZoneNames.ContainsKey(tzc))
                    {
                        tzn = TimeZoneNames[tzc];
                    }

auf den korrekten Zeitzonennamen schließen. Dieser befindet sich nunmehr in der tzn-Variablen. Und unsere Konvertierung sieht dann wie folgt aus:

TimeZoneInfo localZone = TimeZoneInfo.FindSystemTimeZoneById(tzn);

DateTime localDateTime = TimeZoneInfo.ConvertTimeFromUtc(DateField, localZone);

Mit dieser einfachen Hilfe können wir fortan zu jedem Feld die gewünschte Uhrzeit in dem Format eines zugehörigen Benutzers ausgeben und damit Berechnungen, wie Beispielsweise eine Offset-Berechnung anstellen.

Wer von Euch nunmehr noch etwas mehr Informationen zu .GetAttributeValue<T> haben möchte, dem sei der Blog Artikel meines MVP Kollegen David Barry empfohlen. In dieser sehr schönen Zusammenfassung bekommt Ihr Wertvolle Hinweise und Tipps zu Integration in Eure Projekte.

Damit wünsche ich Euch viel Spaß in der Verwirklichung / Umsetzung Eurer Projekte und bis zum nächsten Mal.

 

Technorati Tags:

2 Gedanken zu “Microsoft Dynamics CRM 2011 | Verwendung lokaler Zeitzonencode

    • Hallo Armin,

      danke für Dein Feedback. Lass mich versuchen auf Deine Punkte zu antworten.
      Zu 1. bei der von mir verwendeten ID sollte ein Fehler bei der Umrechnung TZ Singapore ausgeschlossen sein.
      Zu 2. Ich behaupte ja nicht, dass es noch andere Möglichkeiten gibt, die Umrechnung zu gestalten. In meiner Methode verzichte ich auf einen zusätzlichen Execute Request an den Server. Aber natürlich funktioniert die von Dir beschriebene Methode ebenfalls.

      Es obliegt natürlich immer den Anforderungen/Spezifikationen, welche Methode zum Einsatz kommen sollte. Nochmals Danke für den Hinweis und bis bald.

Schreibe einen Kommentar

Trage deine Daten unten ein oder klicke ein Icon um dich einzuloggen:

WordPress.com-Logo

Du kommentierst mit Deinem WordPress.com-Konto. Abmelden / Ändern )

Twitter-Bild

Du kommentierst mit Deinem Twitter-Konto. Abmelden / Ändern )

Facebook-Foto

Du kommentierst mit Deinem Facebook-Konto. Abmelden / Ändern )

Google+ Foto

Du kommentierst mit Deinem Google+-Konto. Abmelden / Ändern )

Verbinde mit %s