简体   繁体   English

在C#中,将Sql Server 2005 datetime值转换为另一个时区

[英]In C#, convert Sql Server 2005 datetime value to another timezone

UPDATE UPDATE

I am dealing with a legacy database where the datetime values have been stored in a specific timezone (not UTC). 我正在处理遗留数据库,其中日期时间值已存储在特定时区(不是UTC)。 Assume it is not possible to change how we are storing these values. 假设无法更改存储这些值的方式。

END UPDATE 结束更新

Say I have a SQL Server 2005 database with a table as follows: 假设我有一个带有表的SQL Server 2005数据库,如下所示:

[id] (int) not null   
[create_date] (datetime) not null

Suppose my [create_date] has been stored, by convention, as timezone TZ-A. 假设我的[create_date]按照惯例存储为时区TZ-A。

Suppose I want to retrieve this value (using SqlClient) from the database and display it in another timezone, TZ-B. 假设我想从数据库中检索此值(使用SqlClient)并将其显示在另一个时区TZ-B中。

How do I do this? 我该怎么做呢?

DateTime from_db = // retrieve datetime from database, in timezone TZ-A
DateTime to_display = //convert from_db to another timezone, TZ-B

Use TimeZoneInfo 使用TimeZoneInfo

TimeZoneInfo timeZone1 = TimeZoneInfo.FindSystemTimeZoneById("Central Standard Time");
TimeZoneInfo timeZone2 = TimeZoneInfo.FindSystemTimeZoneById("Eastern Standard Time");
DateTime to_display= TimeZoneInfo.ConvertTime(from_db, timeZone1, timeZone2);

I also agree that storing in UTC is the way to go. 我也同意以UTC格式存储是要走的路。 The only downside is trying to explain UTC to users who want to write their own reports. 唯一的缺点是试图向想要编写自己的报告的用户解释UTC。

Everyone has C# ways, I give you TSQL (sadly only 2008): 每个人都有C#方式,我给你TSQL(遗憾的是只有2008年):

See below for doc, you probably want something like: 请参阅下面的doc,您可能需要以下内容:

-- up here set the @time_zone variable.

 SELECT 
    COl0, TODATETIMEOFFSET(COLDATE, @time_zone),.... ColN, from 
Table_Original;

From MSDN 来自MSDN

The SWITCHOFFSET function adjusts an input DATETIMEOFFSET value to a specified time zone, while preserving the UTC value. SWITCHOFFSET函数将输入DATETIMEOFFSET值调整为指定的时区,同时保留UTC值。 The syntax is SWITCHOFFSET(datetimeoffset_value, time_zone). 语法是SWITCHOFFSET(datetimeoffset_value,time_zone)。 For example, the following code adjusts the current system datetimeoffset value to time zone GMT +05:00: 例如,以下代码将当前系统datetimeoffset值调整为时区GMT +05:00:

SELECT SWITCHOFFSET(SYSDATETIMEOFFSET(), '-05:00'); SELECT SWITCHOFFSET(SYSDATETIMEOFFSET(),' - 05:00');

So if the current system datetimeoffset value is February 12, 2009 10:00:00.0000000 -08:00, this code returns the value February 12, 2009 13:00:00.0000000 -05:00. 因此,如果当前系统datetimeoffset值是2009年2月12日10:00:00.0000000 -08:00,则此代码返回值2009年2月12日13:00:00.0000000 -05:00。

The TODATETIMEOFFSET function sets the time zone offset of an input date and time value. TODATETIMEOFFSET函数设置输入日期和时间值的时区偏移量。 Its syntax is TODATETIMEOFFSET(date_and_time_value, time_zone). 其语法为TODATETIMEOFFSET(date_and_time_value,time_zone)。

This function is different from SWITCHOFFSET in several ways. 此功能在几个方面与SWITCHOFFSET不同。 First, it is not restricted to a datetimeoffset value as input; 首先,它不限于datetimeoffset值作为输入; rather it accepts any date and time data type. 而是它接受任何日期和时间数据类型。 Second, it does not try to adjust the time based on the time zone difference between the source value and the specified time zone but instead simply returns the input date and time value with the specified time zone as a datetimeoffset value. 其次,它不会尝试根据源值和指定时区之间的时区差异来调整时间,而只是返回带有指定时区的输入日期和时间值作为datetimeoffset值。

The main purpose of the TODATETIMEOFFSET function is to convert types that are not time zone aware to DATETIMEOFFSET by the given time zone offset. TODATETIMEOFFSET函数的主要目的是通过给定的时区偏移将不是时区感知的类型转换为DATETIMEOFFSET。 If the given date and time value is a DATETIMEOFFSET, the TODATETIMEOFFSET function changes the DATETIMEOFFSET value based on the same original local date and time value plus the new given time zone offset. 如果给定的日期和时间值是DATETIMEOFFSET,则TODATETIMEOFFSET函数会根据相同的原始本地日期和时间值加上新的给定时区偏移量更改DATETIMEOFFSET值。

For example, the current system datetimeoffset value is February 12, 2009 10:00:00.0000000 -08:00, and you run the following code: 例如,当前系统datetimeoffset值是2009年2月12日10:00:00.0000000 -08:00,并运行以下代码:

SELECT TODATETIMEOFFSET(SYSDATETIMEOFFSET(), '-05:00'); SELECT TODATETIMEOFFSET(SYSDATETIMEOFFSET(),' - 05:00');

The value February 12, 2009 10:00:00.0000000 -05:00 is returned. 返回值2009年2月12日10:00:00.0000000 -05:00。 Remember that the SWITCHOFFSET function returned February 12, 2009 13:00:00.0000000 -05:00 because it adjusted the time based on the time zone differences between the input (-08:00) and the specified time zone (-05:00). 请记住,SWITCHOFFSET函数在2009年2月12日13:00:00.0000000 -05:00返回,因为它根据输入(-08:00)和指定时区(-05:00)之间的时区差异调整时间。

As mentioned earlier, you can use the TODATETIMEOFFSET function with any date and time data type as input. 如前所述,您可以将TODATETIMEOFFSET函数与任何日期和时间数据类型一起用作输入。 For example, the following code takes the current system date and time value and returns it as a datetimeoffset value with a time zone -00:05: 例如,以下代码获取当前系统日期和时间值,并将其作为datetimeoffset值返回,时区为-00:05:

SELECT TODATETIMEOFFSET(SYSDATETIME(), '-05:00'); SELECT TODATETIMEOFFSET(SYSDATETIME(),' - 05:00');

我不打算给出答案,而是建议:无论如何, 始终以UTC 格式存储绝对日期。

use the TimeZoneInfo class, it gives you built in time zone conversion functions using the Windows API. 使用TimeZoneInfo类,它使用Windows API为您提供内置的时区转换功能。

http://msdn.microsoft.com/en-us/library/system.timezoneinfo.aspx http://msdn.microsoft.com/en-us/library/system.timezoneinfo.aspx

Always store the data in the database as UTC. 始终将数据作为UTC存储在数据库中。 Then convert it in the client for display purposes from UTC to the local time using DateTime.ToLocalTime(); 然后使用DateTime.ToLocalTime()在客户端中将其转换为从UTC到本地时间的显示目的;

检查方法TimeZoneInfo.ConvertTime

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM