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.
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; } }