Déterminer Time Offset donné Olson TZID et DateTime locale?

J'ai besoin de déterminer le décalage temporel donné à Olson TZID d'un événement et un DateTime d'un événement .

Je suppose que je peux le faire avec l'aide de Noda Time, mais je suis nouveau ici et j'ai besoin d'aide – un exemple de séquence d'appel API réelle pour effectuer cette tâche.

Quelques détails supplémentaires sur ce que nous utilisons et faisons.

  1. Nous exécutons ASP.NET + site Web basé sur SQL Server. Les users de notre site entrent et enregistrent les events qui se produisent à divers endroits. Pour chaque événement Lat / Long et DateTime avec décalage temporel (de cet événement) sont parmi les champs obligatoires.
  2. Il existe différents scénarios d'input de données, parfois Lat / Long est entré en premier, parfois DateTime est. Le système permet de déterminer Lat / Long à partir d'une adresse ou d'un sharepoint la carte. Nous souhaitons que le décalage temporel soit cohérent avec Lat / Long dans la plupart des cas car nous nous attendons normalement à ce que DateTime soit entré comme local pour cet événement.
  3. Nous utilisons le champ SQL Server DateTimeOffset pour stocker datatables.
  4. Nous ne voulons pas dépendre de services Web tiers pour déterminer un décalage, mais nous préférons que notre système le fasse.

Je suis libre de download et d'utiliser tous les outils ou données nécessaires. J'ai déjà téléchargé shapefiles de http://efele.net/maps/tz/ et utilisé Shape2SQL http://goo.gl/u7AUy pour les convertir en table SQL Server avec TZIDs et GEOMs.
Je sais comment get TZID de Lat / Long en interrogeant cette table.
Ce dont j'ai besoin, encore une fois, est de déterminer le décalage temporel de TZID et de DateTime .

Merci à Jon Skeet et Matt Johnson d'avoir fourni une réponse sur Noda Time Google Group http://goo.gl/I9unm0 . Jon a expliqué comment get la valeur Microsoft BCL DateTimeOffset en fonction des valeurs Olson TZID et NodaTime LocalDateTime. Matt a pointé un exemple pour déterminer si DST est actif étant donné ZonedDateTime: Quel est l'équivalent de System.TimeZoneInfo.IsDaylightSavingTime dans NodaTime?

Je vais écrire un article de blog résumant mon expérience d'obtention de Olson TZID à partir de Lat / Long, en analysant la string DateTime dans LocalDateTime et en déterminant DateTimeOffset. Je vais montrer comment fonctionnent les methods GetTmzIdByLocation (latitude, longitude) et GetRoughDateTimeOffsetByLocation (latitude, longitude) et pourquoi j'ai eu besoin des deux (la première méthode ne fonctionne pas pour les locations sur l'océan). Une fois que j'écrirai ce post, j'appendai un commentaire ici.

Notez que l'parsing de la string DateTime dans un code ci-dessous n'est pas encore optimale; Comme Matt l'a expliqué dans un post de Google Group (lien ci-dessus), il vaut mieux utiliser les outils de Noda Time que BCL. Voir une question connexe sur http://goo.gl/ZRZ7XP

Mon code actuel:

public object GetDateTimeOffset(ssortingng latitude, ssortingng longitude, ssortingng dateTime) { var tzFound = false; var isDST = false; var tmpDateTime = new DateTimeOffset(DateTime.Now).DateTime; if (!Ssortingng.IsNullOrEmpty(dateTime)) { try { // Note: Looks stupid? I need to throw away TimeZone Offset specified in dateTime ssortingng (if any). // Funny thing is that calling DateTime.Parse(dateTime) would automatically modify DateTime for its value in a system timezone. tmpDateTime = DateTimeOffset.Parse(dateTime).DateTime; } catch (Exception) { } } try { var tmzID = GetTmzIdByLocation(latitude, longitude); DateTimeOffset result; if (Ssortingng.IsNullOrEmpty(tmzID) || tmzID.ToLower() == "uninhabited") // TimeZone is unknown, it's probably an ocean, so we would just return time offest based on Lat/Long. { var offset = GetRoughDateTimeOffsetByLocation(latitude, longitude); result = new DateTimeOffset(tmpDateTime, TimeSpan.FromMinutes(offset * 60)); // This only works correctly if tmpDateTime.Kind = Unspecified, see http://goo.gl/at3Vba } // A known TimeZone is found, we can adjust for DST using Noda Time calls below. else { tzFound = true; // This was provided by Jon Skeet var localDateTime = LocalDateTime.FromDateTime(tmpDateTime); // See Noda Time docs at http://goo.gl/XseiSa var dateTimeZone = DateTimeZoneProviders.Tzdb[tmzID]; var zonedDateTime = localDateTime.InZoneLeniently(dateTimeZone); // See Noda Time docs at http://goo.gl/AqE8Qo result = zonedDateTime.ToDateTimeOffset(); // BCL DateTimeOffset isDST = zonedDateTime.IsDaylightSavingsTime(); } return new { result = result.ToSsortingng(IncidentDateFormat), tzFound, isDST }; } catch (Exception ex) { IMAPLog.LogEvent(System.Reflection.MethodBase.GetCurrentMethod().Name, "", ex); throw new CustomHttpException("Unable to get timezone offset."); } } 

Une méthode d'extension (fournie par Matt Johnson) pour déterminer si l'heure d'été est active Quel est l'équivalent de System.TimeZoneInfo.IsDaylightSavingTime dans NodaTime?

 public static class NodaTimeUtil { // An extension method by Matt Johnson - on Stack Overflow at http://goo.gl/ymy7Wb public static bool IsDaylightSavingsTime(this ZonedDateTime zonedDateTime) { var instant = zonedDateTime.ToInstant(); var zoneInterval = zonedDateTime.Zone.GetZoneInterval(instant); return zoneInterval.Savings != Offset.Zero; } }