使用GMT将字符串中的DateTime转换为C#中的本地时间

时间:2018-10-30 14:55:14

标签: c# sql-server ssis

我在CSV文件中有一个日期,它是SSIS脚本任务的字符串。

我需要根据字符串中存在的GMT偏移量将日期转换为本地时间-我想将其转换为datetime并将其保存在数据库中。

我得到的日期时间是

2018-06-21 08:55 GMT-0400

我需要将其存储为

2018-06-21 08:55

假设我的当地时间是美国东部时间。

为此,我使用以下代码:

 DateTime dt;        // datetime variable
 string str;                // string variable
 string format = "yyyy-MM-dd HH:mm:ss";
 str = Row.Dateused;

 if (Row.Dateused_IsNull == false)
 {
     // convert datetime format to standard one
     DateTime.TryParseExact(str, format, CultureInfo.InvariantCulture,DateTimeStyles.AssumeUniversal |DateTimeStyles.AdjustToUniversal,out dt);
     Row.Dateused = dt.ToString();
 }

但是当我执行它时,这就是我得到的输出:

1/1/0001 12:00:00

有人可以告诉我我要去哪里错吗?

1 个答案:

答案 0 :(得分:0)

简短版本

ParseExact的正确模式是"yyyy-MM-dd HH:mm 'GMT'zzzzz"。最好使用的类型是DateTimeOffset

如果使用DateTime,则它应具有DateTimeStyles.AdjustToUniversal才能获得UTC时间。

在任何情况下,都应将强类型值而不是字符串传递给数据库,以避免转换错误。

长版

处理时区时,正确的类型是DateTimeOffset,而不是DateTime。 DateTime无法理解时区,因此它假定时间是UTC或运行此代码的计算机的 local 时区。它不了解local的实际含义。

DateTime和DateTimeOffset都可以使用正确的模式来解析此字符串:

"yyyy-MM-dd HH:mm 'GMT'zzzzz"

例如:

var pattern="yyyy-MM-dd HH:mm 'GMT'zzzzz";
var dt=DateTimeOffset.ParseExact("2018-06-21 08:55 GMT-0400",pattern,CultureInfo.InvariantCulture);
Console.WriteLine("{0:O}",dt);

将打印:

2018-06-21T08:55:00.0000000-04:00

DateTime属性可以使用DateTimeKind.Unspecified返回不带偏移量的日期和时间。以下代码:

 DateTime dtOnly=dt.DateTime;
 Console.WriteLine("{0:O}",dtOnly);

将打印:

2018-06-21T08:55:00.0000000

在数据库中使用datetimeoffset还是更好,并避免例如由于夏令时转换而引起的错误。如果类型必须datetime(为什么?),则应首先使用UtcDateTime将其转换为UTC。但是,这将丢失偏移信息。

Console.WriteLine("{0:O}",dt.UtcDateTime);

将打印:

2018-06-21T12:55:00.0000000Z

使用DateTimeKind.Utc

DateTime怎么样?

DateTime.ParseExact也可以使用,但是结果取决于 local 时区。这是因为ParseExact将看到偏移量,并返回调整为 local 时区(无论是什么时间)或UTC的DateTime。返回08:55的唯一方法是,如果这是当前计算机的时区偏移量。

在我的机器上,偏移量是+3:00。所以

DateTime.ParseExact("2018-06-21 08:55 GMT-0400",pattern,CultureInfo.InvariantCulture,DateTimeStyles.AssumeLocal);

将使用种类=本地返回2018-06-21T15:55:00。与AssumeUniversal相同,因为字符串不是UTC,它具有偏移量。

DateTimeStyles.AdjustToUniversal将导致2018-06-21T12:55:00带有Kind Utc。可以正确地将相应的UTC值存储在数据库中,而不会引起太多混乱,