Convertir en datetimeoffset de la requête SQL en heure locale en fonction de TimeZoneInfo

Pour une raison stupide, je rest confus quand je fais affaire avec Timezones.

Lorsqu'un logging est créé, j'utilise:

getutcdate() 

Par exemple, il est stocké dans une colonne datetimeoffset et ressemble à ceci:

 2015-07-03 20:44:21.0300000 +00:00 

Donc pas de décalage, juste UTC brut.

Maintenant, dans le code du server, je veux faire quelques choses … J'ai une requête qui m'obtient juste le CreatedDate pour les articles postés pour un user particulier. Je stocke ceci dans un datatable:

 Dim tz as TimeZoneInfo = GetUserTZInfo(User) Dim dt as DataTable = GetArticleDates(User) Dim MaxArticles As Integer = 5 Dim PostedThisMonth As Integer Dim Remaining As Integer 

Je suis limité à 5 articles publiés par mois, donc vous pouvez voir où le time peut devenir instable vers le début ou la fin du mois en fonction du timezone de l'user. C'est demain quelque part, pourtant le même moment dans le time partout.

Mais je veux que ce soit convivial et basez-le sur l'user, pas sur le time du server.

J'ai des difficultés à utiliser certains des exemples de conversion en heure locale à cause de mon type de datetimeoffset

Quelqu'un pourrait-il suggérer une meilleure pratique / méthode sur la façon de réaliser ce qui suit:

  1. Rechercher le dt pour toutes les dates créées qui sont égales au mois de l'user.
  2. Générer count pour PostThisMonth basé sur ce qui est trouvé.

La seule zone collante comme je l'ai dit est au début ou à la fin du mois … en gros, cette window de 12 heures, et bien sûr DST, mais je m'en soucie less.

L'aide est très appréciée!

Félicitations, vous êtes en avance sur la plupart des gens. Vous le faites correctement en stockant les heures UTC dans votre database et en suivant le timezone de l'user avec TimeZoneInfo .

Si vous ne dévier jamais de +00: 00, vous pouvez stocker juse a datetime ou datetime2 au lieu d'un datetimeoffset , mais cela ne fait rien et cela a l'avantage supplémentaire d'être sans ambiguïté UTC.

Tout ce que vous devez vraiment faire est:

  • Utilisez le timezone de l'user pour convertir le début et la fin du mois local de l'user en points de time UTC équivalents.

  • Interrogez votre database en utilisant cette plage de valeurs.

     // compute the start of this month and the next month, by the user's time zone Dim today As DateTime = TimeZoneInfo.ConvertTime(DateTime.UtcNow, tz).Date Dim startDateOfThisMonth As DateTime = New DateTime(today.Year, today.Month, 1) Dim startDateOfNextMonth As DateTime = startDateOfThisMonth.AddMonths(1) // convert those to UTC Dim startUtc As DateTime = TimeZoneInfo.ConvertTimeToUtc(startDateOfThisMonth, tz) Dim endUtc As DateTime = TimeZoneInfo.ConvertTimeToUtc(startDateOfNextMonth, tz) 

    Ou, puisque vous utilisez datetimeoffset dans votre database, vous pouvez simplement créer un DateTimeOffset à la dernière étape. SQL utilisera l'offset pour convertir en UTC en interne lors de l'parsing de l'index.

     Dim start As DateTimeOffset = New DateTimeOffset(startDateOfThisMonth, tz.GetUtcOffset(startDateOfThisMonth)) Dim end As DateTimeOffset = New DateTimeOffset(startDateOfNextMonth, tz.GetUtcOffset(startDateOfNextMonth)) 

Lorsque vous interrogez votre database, utilisez table.dto >= @start AND table.dto < @end (intervalle semi-ouvert).