我只是尝试以UTC等效时间格式打印DateTime。我做错了什么?
var utcEpoch = DateTime.Parse("1970-01-01", CultureInfo.InvariantCulture, DateTimeStyles.AssumeUniversal); //This specifies the time I provided is in UTC
Console.WriteLine(utcEpoch.ToString("yyyy-MM-dd HH:mm:ss zzz")); //This properly shows my UTC offset of -6, so it's not wrong
Console.WriteLine(utcEpoch.ToString("u")); //This just flat out seems wrong because it doesn't specify a timezone or offset in its output
> 1969-12-31 18:00:00 -06:00
> 1969-12-31 18:00:00Z
我希望最后一个看到1970-01-01 00:00:00Z
。
答案 0 :(得分:1)
来自The Universal Sortable ("u"
) Format Specifier:
虽然结果字符串应将时间表示为Coordinated 世界时(UTC),原始DateTime值没有转换 在格式化操作期间执行。 因此,您必须转换 通过调用
DateTime.ToUniversalTime
方法将DateTime值设置为UTC 格式化之前。相反,DateTimeOffset值执行此操作 自动转换;没有必要打电话给 格式化操作之前的DateTimeOffset.ToUniversalTime方法。
您的utcEpoch.Kind
不 UTC
,它是Local
。 DateTime's are triciker than you might think。您希望它会将UTC
作为Kind
属性返回,但它不是。它返回Local
。
此问题已在Phil Haack blog post上讨论过,Matt Johnson对此有一个非常好的评论;
AssumeLocal
和AssumeUniversal
都与输入方式有关 字符串被解释。 他们自己也不会改变输出 样。强>默认输出类型为
Local
。要使它成为Utc
,您可以使用AdjustToUniversal
风格。
DateTimeStyles
枚举是基于标志的,因此您可以将它们组合在一起 一些有意义的方法。实现您最初设定的目标 do(将输入解析为UTC
并将其输出为UTC
),然后您将使用:DateTime utcDate = DateTime.Parse(" 10/01/2006 19:30",culture,DateTimeStyles.AssumeUniversal | DateTimeStyles.AdjustToUniversal);
正如其他人指出的那样,单独调用
ToUniversalTime()
也可以,但这在技术上更正确。
您也可以在referance source上看到它;
case 'u': // Universal time in sortable format.
if (offset != NullOffset)
{
// Convert to UTC invariants mean this will be in range
dateTime = dateTime - offset;
}
else if (dateTime.Kind == DateTimeKind.Local)
{
InvalidFormatForLocal(format, dateTime);
}
答案 1 :(得分:1)
我认为你很难理解API正在做什么。
首先要注意的是,DateTimeStyles.AssumeUniversal
和DateTimeStyles.AssumeLocal
仍会返回DateTime,其中Kind = Local
> DateTime.Parse("1970-01-01 00:00:00", CultureInfo.InvariantCulture, DateTimeStyles.AssumeUniversal).Kind
=> Local
> DateTime.Parse("1970-01-01 00:00:00", CultureInfo.InvariantCulture, DateTimeStyles.AssumeLocal).Kind
=> Local
所以无论我们将获得本地日期。这意味着API很可能是为了从UTC日期获得本地时间。如果这是正确的,我们试试。
我在瑞典,所以我们在标准时间内是UTC + 1。因此,如果我使用DateTimeStyles.AssumeUniversal
并输入今天的日期,我的当地日期应该是今天的01:00。
在C#Interactive中运行它:
> DateTime.Parse("2018-03-03", .CultureInfo.InvariantCulture, .DateTimeStyles.AssumeUniversal)
=> [2018-03-03 01:00:00]
含义C#假设我输入的字符串是UTC格式,我希望它在本地,所以它“固定”了它。
对AssumeLocal
执行相同操作。
DateTime.Parse("2018-03-03", .CultureInfo.InvariantCulture, .DateTimeStyles.AssumeLocal)
=> [2018-03-03 00:00:00]
正如所料,我们现在将输入视为本地字符串并获得相同的值。
要获取UTC日期,您可以指定类型
DateTime.SpecifyKind(DateTime.Parse("2018-03-03", CultureInfo.InvariantCulture), DateTimeKind.Utc).ToString("o")
=> "2018-03-03T00:00:00.0000000Z"