2017-03-22 2 views
1

Je suis un problème avec Azure serveur SQL, sur ma machine locale, je peux enregistrer un datetimeoffset dans la db et le décalage horaire est correctement enregistré comme ci-dessousSaving Datetimeoffset sur SQL Azure ne fonctionne pas

2017-03-31 00:00:00.0000000 -05:00 

mais sur azur perd le décalage horaire, mes colonnes sont datetimeoffset type et que je reçois mon datetimeoffset en utilisant ce DateTimeOffset.UtcNow.UtcDateTime ou DateTimeOffset.Now mais ni moyen semble fonctionner, est toujours d'être sauvé comme ci-dessous

2017-03-31 00:00:00.0000000 +00:00 

comment puis-je enregistrer le DateTimeOffset correct sur le serveur SQL Azure. J'utilise Entity Framework Code First Migration, je viens de créer l'entité et d'assigner le DateTimeOffset en utilisant l'une des lignes ci-dessus, puis context.SaveChanges().

var entity = Mapper.Map<CarSearchForm, CarSearches>(model); 
ctx.CarSearches.Add(entity); 
ctx.SaveChanges(); 

et automapper profil est comme ce

CreateMap<CarSearchForm, CarSearches>() 
      .ForMember(dest => dest.RequestedDate, opts => opts.MapFrom(src => DateTimeOffset.UtcNow.UtcDateTime)) 
      .ForMember(dest => dest.PickupTime, opts => opts.MapFrom(src => src.TimePickup)) 
      .ForMember(dest => dest.DropoffTime, opts => opts.MapFrom(src => src.TimePickup));  

Voici le modèle

namespace Data.Entities 
{ 
    public class CarSearches 
    { 
     public int CarSearchesId { get; set; } 
     [Required] 
     public string PickupPlace { get; set; } 
     [Required] 
     public DateTimeOffset PickupDate { get; set; } 
     [Required] 
     public DateTimeOffset PickupTime { get; set; } 
     [Required] 
     public DateTimeOffset DropoffDate { get; set; } 
     [Required] 
     public DateTimeOffset DropoffTime { get; set; }  
     [Required] 
     public CarTransmission Transmission { get; set; } 
     [Required] 
     public DateTimeOffset RequestedDate { get; set; }   
    } 

} 

enter image description here Je suis seulement intéressé par la propriété RequestedDate ci-dessus, je ne peux pas Pourquoi ne sauvegarde-t-il pas le décalage de fuseau horaire sur Azure mais fonctionne localement?

Merci

+0

Comment ne pas utiliser l'enregistrer dans la base de données? EF? ado.net? – RAS

+0

Afficher le code comment vous l'enregistrez – Lanorkin

+0

J'ai fait un montage, j'utilise le code EF premières migrations, rien de spécial à ce sujet, il suffit de –

Répondre

3

... Je reçois mon datetimeoffset en utilisant ce DateTimeOffset.UtcNow.UtcDateTime ou DateTimeOffset.Now

  • Le premier va toujours de vous donner une valeur UTC DateTime (offset +00:00). C'est équivalent à DateTime.UtcNow. Le second vous donnera une valeur DateTimeOffset, dont l'heure locale et l'offset correspondent à l'ordinateur sur lequel il est en cours d'exécution.

    • Sur votre ordinateur local, vous voyez -05:00 car il utilise réglage de fuseau horaire de votre ordinateur. Dans Azure, vous voyez +00:00. En effet, la plupart des serveurs et services Azure sont définis avec leur fuseau horaire pour s'exécuter en UTC.

      En général, il s'agit du best practice pour les serveurs, en particulier ceux du cloud. Les serveurs ont souvent besoin de se connecter avec des clients partout dans le monde et d'échanger des données entre eux. UTC est le seul fuseau horaire qui soit raisonnable.

Une autre façon de penser est que si un fuseau horaire de la machine est réglée sur UTC, DateTime.Now et DateTime.UtcNow donnera les mêmes valeurs de date et l'heure, mais on aura sa propriété .Kind définie sur DateTimeKind.Local et l'autre l'aura mis à DateTimeKind.Utc. Puisque DateTimeOffset n'a pas de Kind (heureusement), on ne peut pas faire la distinction entre DateTimeOffset.Now et DateTimeOffset.UtcNow sur une machine dont le fuseau horaire est réglé sur UTC. En ce qui concerne ce qu'il faut faire - si vous souhaitez qu'un autre fuseau horaire soit pris en compte, vous devez d'abord connaître le fuseau horaire. Ensuite, vous pouvez utiliser la classe TimeZoneInfo (si vous utilisez des fuseaux horaires Windows) ou la bibliothèque Noda Time (si vous utilisez des fuseaux horaires IANA) pour convertir l'heure UTC en DateTimeOffset dans ce fuseau horaire.

En utilisant TimeZoneInfo:

DateTime utcNow = DateTime.UtcNow; 
TimeZoneInfo tz = TimeZoneInfo.FindSystemTimeZoneById("Eastern Standard Time"); 
DateTimeOffset easternNow = TimeZoneInfo.ConvertTimeFromUtc(utcNow, tz); 

En utilisant Noda Time:

Instant now = SystemClock.Instance.Now; 
DateTimeZone tz = DateTimeZoneProviders.Tzdb["America/New_York"]; 
DateTimeOffset easternNow = now.InZone(tz).ToDateTimeOffset(); 
+1

Explication très détaillée sur azure timezone et comment cela fonctionne, basé sur ce que je reçois le suivant, toujours stocker datetime sur UTC et convertir en datetime local en spécifiant le fuseau horaire sur mon code de l'application. –

+1

Oui, précisément. Considérez que votre code doit présenter le même comportement et enregistrer les mêmes données, quel que soit l'endroit où il est hébergé ou quel paramètre de fuseau horaire le serveur est activé. –