La conversion entre les fuseaux horaires avec Noda Temps
Je suis en train d'essayer de s'assurer que notre héritage back-end peut soutenir la résolution date de fois selon le fuseau horaire actuel (ou, plus précisément offset). Nos serveurs sont en heure normale de l'est, et la plupart de nos jour fois provenir de là. Cependant, pour les utilisateurs qui sont dans d'autres fuseaux horaires, une conversion de leur fuseau horaire (ou, dans ce cas, offset) est nécessaire lors de la récupération de ceux-date de fois. Aussi, la date de fois en provenance de l'utilisateur devront être converties à l'heure normale de l'est avant la persistance sur le serveur. Étant donné que le front-end nous sommes en développement est basé sur le web, je suis capable de récupérer de l'utilisateur de décalage en minutes et passer cette valeur dans ma couche de service au sein de l'en-tête. J'ai regardé Noda Temps et pense que c'est un API. Il ne me force à penser à la fois à une plus raffinée, mais je ne suis pas encore sûr à 100% que j'ai correctement utilisé correctement. Voici les méthodes que j'ai écrit pour la conversion décrites ci-dessus. Je l'ai testé et ils semblent fonctionner. Dans le scénario ci-dessus, ce que cela ressemble à une bonne utilisation de la bibliothèque? Suis-je en pensant à la date de fois correctement?
public static DateTime ConvertToUtcFromEasternTimeZone(DateTime easternDateTime)
{
NodaTime.DateTimeZone easternTimeZone = NodaTime.DateTimeZoneProviders.Tzdb.GetZoneOrNull("America/New_York");
ZoneLocalMappingResolver customResolver = Resolvers.CreateMappingResolver(Resolvers.ReturnLater, Resolvers.ReturnStartOfIntervalAfter);
var easternLocalDateTime = LocalDateTime.FromDateTime(easternDateTime);
var easternZonedDateTime = easternTimeZone.ResolveLocal(easternLocalDateTime, customResolver);
return easternZonedDateTime.ToDateTimeUtc();
}
public static DateTime ConvertToEasternTimeZoneFromUtc(DateTime utcDateTime)
{
NodaTime.DateTimeZone easternTimeZone = NodaTime.DateTimeZoneProviders.Tzdb.GetZoneOrNull("America/New_York");
NodaTime.DateTimeZone utcTimeZone = NodaTime.DateTimeZoneProviders.Tzdb.GetZoneOrNull("UTC");
ZoneLocalMappingResolver customResolver = Resolvers.CreateMappingResolver(Resolvers.ReturnLater, Resolvers.ReturnStartOfIntervalAfter);
var utcLocal = LocalDateTime.FromDateTime(utcDateTime);
var utcZonedDateTime = utcTimeZone.ResolveLocal(utcLocal, customResolver);
var easternZonedDateTime = utcZonedDateTime.ToInstant().InZone(easternTimeZone);
return easternZonedDateTime.ToDateTimeUnspecified();
}
public static DateTime ConvertToUtc(DateTime dateTime, int offsetInMinutes)
{
LocalDateTime localDateTime = LocalDateTime.FromDateTime(dateTime);
var convertedDateTime = localDateTime.PlusMinutes(offsetInMinutes).ToDateTimeUnspecified();
return convertedDateTime;
}
public static DateTime ConvertFromUtc(DateTime dateTime, int offsetInMinutes)
{
LocalDateTime localDateTime = LocalDateTime.FromDateTime(dateTime);
var convertedDateTime = localDateTime.PlusMinutes(-offsetInMinutes).ToDateTimeUnspecified();
return convertedDateTime;
}
L'idée ici est que le temps de la zone de questions quand je suis à résoudre entre l'heure UTC et l'heure de la zone dans la base de données. Quand je suis à résoudre entre le client en temps et en heure UTC, puis de compenser les questions.
Dans l'avenir, on peut persister à l'heure UTC, et ce sera plus facile. Actuellement, cette solution est un bouche-trou.
L'idée est que nous allons passer d'...
client -> UTC +/- décalage -> UTC -> Heure de l'est -> base de données
base de données -> Heure de l'est -> UTC -> UTC +/- décalage -> client
pour finalement...
client -> UTC +/- décalage -> UTC -> base de données
base de données -> UTC -> UTC +/- décalage -> client
Oui, Jon. Merci pour la clarification. J'ai besoin de prendre en compte l'heure d'été.
OriginalL'auteur PureCognition | 2013-10-08
Vous devez vous connecter pour publier un commentaire.
Votre première méthode semble correct, bien que nous ne savons pas ce
customResolver
est.Votre deuxième méthode est un peu hors. Je vous suggère de:
Notez que vous n'avez pas besoin de rechercher le fuseau horaire dans chaque appel de méthode - juste:
... ensuite l'utiliser partout.
Votre troisième et quatrième méthodes ne sont pas ce que j'avais penser que idiomatiques - pour la troisième méthode, vous devez utiliser:
La quatrième méthode semble un peu plus compliqué, car nous ne pouvons pas fournir tout ce que nous devrions en termes de conversions avec
OffsetDateTime
. Le code que vous avez utilisé est probablement correct, mais il serait certainement plus propre si vous pouvez utiliserOffsetDateTime
.EDIT: j'ai ajouté une méthode pour
Instant
pour faire de la quatrième méthode plus propre. Il fera partie de la version 1.2.0, et vous pouvez utiliser:En outre, la version de la bibliothèque que j'ai n'a pas de Décalage.FromMinutes(). Donc, j'ai converti pour Compenser.FromHoursAndMinutes(0, offsetInMinutes).
OriginalL'auteur Jon Skeet