Sqlserver
 sql >> Base de données >  >> RDS >> Sqlserver

Conversion de date et heure de fuseau horaire en fuseau horaire dans le serveur sql

Les horodatages Unix sont un nombre entier de secondes depuis le 1er janvier 1970 UTC.

En supposant que vous vouliez dire que vous avez une colonne entière dans votre base de données avec ce numéro, alors le fuseau horaire de votre serveur de base de données n'est pas pertinent.

Convertissez d'abord l'horodatage en datetime saisissez :

SELECT DATEADD(second, yourTimeStamp, '1970-01-01')

Ce sera l'UTC datetime qui correspond à votre horodatage.

Ensuite, vous devez savoir comment ajuster cette valeur à votre fuseau horaire cible. Dans une grande partie du monde, une même zone peut avoir plusieurs décalages, en raison de l'heure d'été.

Malheureusement, SQL Server n'a pas la capacité de travailler directement sur les fuseaux horaires. Donc, si vous utilisiez, par exemple, l'heure du Pacifique américain, vous n'auriez aucun moyen de savoir si vous devez soustraire 7 heures ou 8 heures. D'autres bases de données (Oracle, Postgres, MySql, etc.) ont des moyens intégrés pour gérer cela, mais hélas, SQL Server ne le fait pas. Donc, si vous recherchez une solution à usage général, vous devrez effectuer l'une des opérations suivantes :

  • Importez des données de fuseau horaire dans une table et maintenez cette table à mesure que les règles de fuseau horaire changent. Utilisez cette table avec un tas de logique personnalisée pour résoudre le décalage pour une date particulière.

  • Utilisez xp_regread pour accéder aux clés de registre Windows qui contiennent des données de fuseau horaire, et utilisez à nouveau un tas de logique personnalisée pour résoudre le décalage pour une date particulière. Bien sûr, xp_regread est une mauvaise chose à faire, nécessite certaines autorisations accordées et n'est pas prise en charge ou documentée.

  • Écrivez une fonction SQLCLR qui utilise TimeZoneInfo classe dans .Net. Malheureusement, ce nécessite un assembly SQLCLR "non sécurisé" , et pourrait provoquer de mauvaises choses.

À mon humble avis, aucune de ces approches n'est très bonne, et il n'y a pas de bonne solution pour le faire directement en SQL. La meilleure solution serait de renvoyer la valeur UTC (soit l'entier d'origine, soit le datetime à UTC) vers votre code d'application appelante, et faites la conversion de fuseau horaire à la place (avec, par exemple, TimeZoneInfo dans .Net ou des mécanismes similaires dans d'autres plates-formes).

CEPENDANT - vous avez de la chance car le Koweït est (et a toujours été) dans une zone qui ne change pas pour l'heure d'été. Cela a toujours été UTC+03:00. Vous pouvez donc simplement ajouter trois heures et renvoyer le résultat :

SELECT DATEADD(hour, 3, DATEADD(second, yourTimeStamp, '1970-01-01'))

Mais reconnaissez qu'il ne s'agit pas d'une solution à usage général qui fonctionnera dans n'importe quel fuseau horaire.

Si vous le souhaitez, vous pouvez renvoyer l'un des autres types de données SQL, tels que datetimeoffset , mais cela vous aidera uniquement à comprendre que la valeur est décalée de trois heures par rapport à qui que ce soit. Cela ne rendra pas le processus de conversion différent ou meilleur.

Réponse mise à jour

J'ai créé un projet pour prendre en charge les fuseaux horaires dans SQL Server. Vous pouvez l'installer d'ici . Ensuite, vous pouvez simplement convertir comme ceci :

SELECT Tzdb.UtcToLocal('2015-07-01 00:00:00', 'Asia/Kuwait')

Vous pouvez utiliser n'importe quel fuseau horaire de la base de données IANA tz , y compris ceux qui utilisent l'heure d'été.

Vous pouvez toujours utiliser la méthode que j'ai montrée ci-dessus pour convertir à partir d'un horodatage Unix. En les associant :

SELECT Tzdb.UtcToLocal(DATEADD(second, yourTimeStamp, '1970-01-01'), 'Asia/Kuwait')

Mise à jour à nouveau

Avec SQL Server 2016, il existe désormais une prise en charge intégrée des fuseaux horaires avec AT TIME ZONE déclaration. Ceci est également disponible dans Azure SQL Database (v12).

SELECT DATEADD(second, yourTimeStamp, '1970-01-01') AT TIME ZONE 'Arab Standard Time'

Plus d'exemples dans cette annonce.