我试图将日期转换为UTC格式,在那里我可以获得正确的偏移量。我在简单的DateTime.Now
中使用ToString("O")
。
现在,当我将当前时间(EST)转换为CST(中央)或MST(山地)时,我没有得到偏移。我在这里错过了什么?还有其他方法吗?
代码:
var currentTimeToUtc = DateTime.Now.ToString("O");
// Output = "2018-12-27T12:31:21.9946661-05:00" --This is perfect.
var centralTime = TimeZoneInfo.ConvertTimeBySystemTimeZoneId(DateTime.Now, "Central Standard Time");
var centralTimeToUtc = centralTime.ToString("O");
// Output = "2018-12-27T11:31:19.8046052"
// Expected Output = "2018-12-27T11:31:19.8046052-06:00"
var mountainTime = TimeZoneInfo.ConvertTimeBySystemTimeZoneId(DateTime.Now, "Mountain Standard Time");
var mountainTimeToUtc = mountainTime.ToString("O");
// Output = "2018-12-27T10:31:25.2438418"
// Expected Output = "2018-12-27T10:31:25.2438418-07:00"
这是DateTime
的预期行为。如果您需要保留时区信息,请改用DateTimeOffset
。
输出不同的原因是DateTime.Now
和中央时间
/山时间
是不同的类型:转换前的日期时间是本地
,转换后变成未指定
。
运行下面的程序来确认这一点:
var now = DateTime.Now;
Console.WriteLine(now.Kind);
var centralTime = TimeZoneInfo.ConvertTimeBySystemTimeZoneId(now, "Central Standard Time");
Console.WriteLine(centralTime.Kind);
var mountainTime = TimeZoneInfo.ConvertTimeBySystemTimeZoneId(now, "Mountain Standard Time");
Console.WriteLine(mountainTime.Kind);
无法更改行为,因为DateTime
不存储偏移量;它依赖于两个众所周知的偏移量来解释时区-Local
表示您的本地时区,而UTC
表示UTC时区。
第三个选项,未指定
,意味着DateTime
的值本身不能被解释为绝对值,因为时区已经从它中剥离出来了。你的代码知道它是什么时区,因为你做了转换,但是关于时区的信息是你程序设计的一部分,而不是相应的DateTime
对象的一部分。NET添加了DateTimeOffset
对象专门来解决这个问题。