2016-05-16 3 views
1
 DateTimeOffset testDateAndTime = new DateTimeOffset(2008, 5, 1, 8, 6, 32, new TimeSpan(1, 0, 0)); 

     //CLEAN TIME AND DATE 
     testDateAndTime = testDateAndTime.DateTime.Date; 

     var datesTableEntry = db.DatesTable.First(dt => dt.Id == someTestId); 
     datesTableEntry.test= testDateAndTime; 

     db.SaveChangesAsync(); 

RÉSULTAT DE LA BASE DE DONNÉES: 2008-05-01 00:00:00.0000000 -04:00Suppression Time Zone décalée par rapport DateTimeOffset

Comment puis-je tourner -4:00 en +00:00 (à partir du code, avant d'enregistrer)?

J'ai essayé:

public Task<DateTimeOffset> SetTimeZoneOffsetToZero(DateTimeOffset dateTimeOffSetObj) 
    { 
     TimeSpan zeroOffsetTimeSpan = new TimeSpan(0, 0, 0, 0, 0); 
     return dateTimeOffSetObj.ToOffset(zeroOffsetTimeSpan); 
    } 

Il ne fait rien.

L'objectif final est simplement d'avoir une date sans décalage de fuseau horaire ou de fuseau horaire. Je ne veux pas convertir le temps en un autre fuseau horaire (je ne veux pas qu'il soustrait 4 heures de l'heure 00:00:00.0000000 et supprime le décalage horaire à +00:00, je veux juste qu'il règle l'offset sur +00:00). Je veux la date actuelle, avec un décalage de zéro.

Edit:

Voici quelque chose suggéré ailleurs:

DateTimeOffset testDateAndTime = new DateTimeOffset(2008, 5, 1, 8, 6, 32, new TimeSpan(1, 0, 0)); 
    testDateAndTime = testDateAndTime.DateTime.Date; //Zero out time portion 
    testDateAndTime = DateTime.SpecifyKind(testDateAndTime.Date, DateTimeKind.Utc); //"Zero out" offset portion 

J'étais sûr que SpecifyKind convertirait mon Datetimeoffset, par exemple changer à la fois l'heure et le décalage de la fuseau horaire, mais lors du test, il semble juste changer le décalage de fuseau horaire, ce qui est ce que je veux. Y a-t-il un problème à le faire de cette façon?

+0

Vous devez penser à ceci un peu différent. Vous avez toujours un fuseau horaire et un composant temporel. Vous pouvez régler l'heure sur 0 (minuit). Mais vous devez le faire pour un fuseau horaire spécifié. Ce que vous voulez probablement, c'est date.Utc.Date pour obtenir le fuseau horaire UTC, puis la date à zéro sur la partie heure. –

+0

@DavidThielen Si je date.Utc.Date, retournera-t-il une date DIFFERENTE alors celle que j'ai si elle est sur le bord? – VSO

+0

Bon point. Peut-être Date.Utc.Date? –

Répondre

7

Le problème n'a rien à voir avec la base de données. Si vous définissez un point d'arrêt ou connectez la sortie quelque part, vous devriez être en mesure de voir le décalage additionnelle ajoutée peu après ce code:

testDateAndTime = testDateAndTime.DateTime.Date; 

Brisons cette baisse:

  • Vous avez commencé avec un DateTimeOffset valeur de 2008-05-01T08:06:32+01:00
  • Vous avez ensuite appelé .DateTime, ce qui a donné lieu à une valeur DateTime de 2008-05-01T08:06:32 avec DateTimeKind.Unspecified.
  • Vous avez ensuite appelé .Date, ce qui a abouti à une valeur DateTime de 2008-05-01T00:00:00 avec DateTimeKind.Unspecified.
  • Vous affectez le résultat à testDateAndTime, qui est de type DateTimeOffset. Cela appelle une distribution implicite de DateTime à DateTimeOffset - qui applique le local fuseau horaire. Dans votre cas, il semblerait que le décalage pour cette valeur dans votre fuseau horaire local est -04:00, donc la valeur résultante est DateTimeOffset de 2008-05-01T00:00:00-04:00, comme vous l'avez décrit.

Vous avez dit:

objectif final est juste d'avoir une date sans heure ou le fuseau horaire de décalage.

Eh bien, il n'y a actuellement aucun type de données natif C# qui est juste une date sans temps.Il y a un type Date pur dans le System.Time package dans corefxlab, mais ce n'est pas tout à fait prêt pour l'application de production typique. Il y a LocalDate dans la bibliothèque Noda Time que vous pouvez utiliser aujourd'hui, mais vous devrez toujours revenir à un type natif avant d'enregistrer dans la base de données. Donc, en attendant, le mieux que vous pouvez faire est:

  • Modifiez votre SQL Server pour utiliser un type date dans le champ.
  • Dans votre code .NET, utilisez un DateTime avec un temps de 00:00:00 et DateTimeKind.Unspecified. Vous devrez vous rappeler d'ignorer la partie heure (car il y a en effet des dates sans minuit local dans certains fuseaux horaires).
  • Modifiez votre prop test pour qu'il soit un DateTime, et non un DateTimeOffset.

En général, alors que DateTimeOffset correspond à un grand nombre de scénarios (tels que timestamping événements), il ne correspond pas bien pour les valeurs de date uniquement.

Je veux la date du jour, avec un décalage d'origine.

Si vous vraiment souhaite comme DateTimeOffset, vous feriez:

testDateAndTime = new DateTimeOffset(testDateAndTime.Date, TimeSpan.Zero); 

Cependant, je vous conseille contre cela. Ce faisant, vous prenez la locale date de la valeur d'origine et affirmant qu'elle est en UTC. Si le décalage d'origine est autre que zéro, ce serait une fausse assertion. Il est lié à conduire à d'autres erreurs plus tard, car vous parlez en fait d'un moment différent (avec potentiellement une date différente) que celui que vous avez créé.

En ce qui concerne la question supplémentaire posée lors de votre modification - La spécification de DateTimeKind.Utc modifie le comportement de la distribution implicite. Au lieu d'utiliser le fuseau horaire local, il utilise l'heure UTC, qui a toujours un décalage de zéro. Le résultat est le même que la forme plus explicite que j'ai donnée plus haut. Je recommande toujours contre cela, pour les mêmes raisons.

Considérons un exemple de début avec 2016-12-31T22:00:00-04:00. Par votre approche, vous économisez dans la base de données 2016-12-31T00:00:00+00:00. Cependant, ce sont deux points très différents dans le temps. Le premier normalisé à UTC serait 2017-01-01T02:00:00+00:00, et le deuxième converti à l'autre fuseau horaire serait 2016-12-30T20:00:00-04:00. Notez le changement de dates dans la conversion. Ce n'est probablement pas le comportement que vous voudriez glisser dans votre application.