通过 UTC 转换获取时区
Get time zone with UTC conversion
我有 BST 中的系统日期。我想将其转换为 UTC。以下也是如此:
string utcDate= TimeZoneInfo.ConvertTimeToUtc(dt).ToString("dd/MM/yyyy HH:mm:ss");
我想要的是获取区域以及 UTC 日期。请考虑夏令时。
示例:2019-07-08T23:59:00+01:00.
我想你可以这样做:
var dt = DateTime.Now;
string utcDate = dt.ToUniversalTime().ToString("dd/MM/yyyy HH:mm:ss") +
dt.ToString(" zzz");
输出:(我在 EET)
14/07/2019 20:02:17 +02:00
但请注意,这可能会让人们感到困惑。标准方法是时区遵循本地日期,而不是通用日期。
几件事:
你给出的字符串格式,2019-07-08T23:59:00+01:00
是ISO 8601 specification. To be precise, it is the "complete date and time of day representation" of the "ISO 8601 Extended Format". It also the format defined by RFC 3339的一部分。
在这种格式中,日期和时间部分表示本地时间,如时区偏移部分所示。换句话说,这些值不是 UTC,而是已经调整过。在您的示例中,2019-07-08T23:59:00
是当地时间,UTC+01:00
是当时有效的时间。因此相应的 UTC 时间将提前一个小时,2019-07-08T22:59:00Z
.
您似乎在要求 UTC 日期,但偏移量包括夏令时。这是不可能的,因为 UTC 不遵守夏令时。与 UTC 的偏移量始终为零。 You can read more about UTC here.
UTC本身的偏移量用Z
表示,但也可以用+00:00
表示,可以认为是“与UTC的零偏移量”。换句话说,如果您指的是 UTC 时间,请使用 Z
,如果您指的是与 UTC 对齐的本地时间(例如冬季伦敦的格林威治标准时间,或冰岛等),请使用+00:00
.
在你的问题中,你说你想要 UTC 的系统时间和偏移量。我假设“系统时间”是指系统时钟的当前时间。这是由 DateTime.UtcNow
或 DateTimeOffset.UtcNow
提供的。这些 return 要么是 DateTime
要么是 DateTimeOffset
结构——不是字符串。既然你想要一个特定格式的字符串,那么你应该首先询问当前时间,然后将其格式化为带有 ToString
:
的字符串
using System.Globalization;
...
string a = DateTime.UtcNow.ToString("yyyy-MM-dd'T'HH:mm:ssK", CultureInfo.InvariantCulture);
// output example: "2019-07-08T22:59:00Z"
string b = DateTimeOffset.UtcNow.ToString("yyyy-MM-dd'T'HH:mm:sszzz", CultureInfo.InvariantCulture);
// output example: "2019-07-08T22:59:00+00:00"
如果您真正想要的是 local 时间,那么冬天的偏移量是 +00:00
,而冬天的偏移量是 +01:00
在夏天(在英国),然后使用 Now
而不是 UtcNow
。这给出代码为 运行ning.
的计算机时区的本地时间
string c = DateTime.Now.ToString("yyyy-MM-dd'T'HH:mm:ssK", CultureInfo.InvariantCulture);
// output example: "2019-07-08T23:59:00+01:00"
string d = DateTimeOffset.Now.ToString("yyyy-MM-dd'T'HH:mm:sszzz", CultureInfo.InvariantCulture);
// output example: "2019-07-08T23:59:00+01:00"
如果你真的想要英国时间而不考虑本地计算机的时区,那么你必须先获取UTC时间然后将其转换为英国时间在创建字符串之前。
TimeZoneInfo tzi = TimeZoneInfo.FindSystemTimeZoneById("GMT Standard Time");
string e = TimeZoneInfo.ConvertTime(DateTime.UtcNow, tzi).ToString("yyyy-MM-dd'T'HH:mm:ssK", CultureInfo.InvariantCulture);
// output example: "2019-07-08T23:59:00"
string f = TimeZoneInfo.ConvertTime(DateTimeOffset.UtcNow, tzi).ToString("yyyy-MM-dd'T'HH:mm:sszzz", CultureInfo.InvariantCulture);
// output example: "2019-07-08T23:59:00+01:00"
在示例 e
中,请注意 DateTime
无法存储时区转换结果的任意偏移量,因此您将 DateTimeKind.Unspecified
分配给 Kind
属性,这导致字符串表示中没有偏移量。因此,大多数时候您应该使用 DateTimeOffset
(例如 f
)。
另外,请注意 "GMT Standard Time"
的时区 ID 是在 Windows 平台上用于英国的正确 ID。它会在适当的时候在 GMT 和 BST 之间正确切换。如果您在 non-Windows 平台(Linux、OSX 等)上 运行ning .NET Core,那么您应该改用 "Europe/London"
。或者,如果您想编写 platform-neutral 的代码,那么您可以使用我的 TimeZoneConverter 库,它允许您在任何平台上提供任何一种形式和 运行。
在您的代码示例中,您没有调用任何“now”函数,但提供了一个 dt
变量。假设这是一个 DateTime
,调用 TimeZoneInfo.ConvertTimeToUtc
的结果将取决于该变量的 Kind
属性。如果是 DateTimeKind.Utc
,则不执行任何转换。如果是 DateTimeKind.Local
或 DateTimeKind.Unspecified
,则该值将从计算机的本地时区转换为 UTC。
最后,请记住,在与国际观众交谈时,时区缩写可能会产生歧义。我可以通过“BST”推断出您的意思是英国夏令时,但这只是因为您在问题中显示了 +01:00
偏移量。 “BST”也可以代表“孟加拉国标准时间”(+06:00
),或“布干维尔标准时间”(+11:00
)。
我有 BST 中的系统日期。我想将其转换为 UTC。以下也是如此:
string utcDate= TimeZoneInfo.ConvertTimeToUtc(dt).ToString("dd/MM/yyyy HH:mm:ss");
我想要的是获取区域以及 UTC 日期。请考虑夏令时。
示例:2019-07-08T23:59:00+01:00.
我想你可以这样做:
var dt = DateTime.Now;
string utcDate = dt.ToUniversalTime().ToString("dd/MM/yyyy HH:mm:ss") +
dt.ToString(" zzz");
输出:(我在 EET)
14/07/2019 20:02:17 +02:00
但请注意,这可能会让人们感到困惑。标准方法是时区遵循本地日期,而不是通用日期。
几件事:
你给出的字符串格式,
2019-07-08T23:59:00+01:00
是ISO 8601 specification. To be precise, it is the "complete date and time of day representation" of the "ISO 8601 Extended Format". It also the format defined by RFC 3339的一部分。在这种格式中,日期和时间部分表示本地时间,如时区偏移部分所示。换句话说,这些值不是 UTC,而是已经调整过。在您的示例中,
2019-07-08T23:59:00
是当地时间,UTC+01:00
是当时有效的时间。因此相应的 UTC 时间将提前一个小时,2019-07-08T22:59:00Z
.您似乎在要求 UTC 日期,但偏移量包括夏令时。这是不可能的,因为 UTC 不遵守夏令时。与 UTC 的偏移量始终为零。 You can read more about UTC here.
UTC本身的偏移量用
Z
表示,但也可以用+00:00
表示,可以认为是“与UTC的零偏移量”。换句话说,如果您指的是 UTC 时间,请使用Z
,如果您指的是与 UTC 对齐的本地时间(例如冬季伦敦的格林威治标准时间,或冰岛等),请使用+00:00
.在你的问题中,你说你想要 UTC 的系统时间和偏移量。我假设“系统时间”是指系统时钟的当前时间。这是由
的字符串DateTime.UtcNow
或DateTimeOffset.UtcNow
提供的。这些 return 要么是DateTime
要么是DateTimeOffset
结构——不是字符串。既然你想要一个特定格式的字符串,那么你应该首先询问当前时间,然后将其格式化为带有ToString
:using System.Globalization;
...
string a = DateTime.UtcNow.ToString("yyyy-MM-dd'T'HH:mm:ssK", CultureInfo.InvariantCulture); // output example: "2019-07-08T22:59:00Z" string b = DateTimeOffset.UtcNow.ToString("yyyy-MM-dd'T'HH:mm:sszzz", CultureInfo.InvariantCulture); // output example: "2019-07-08T22:59:00+00:00"
如果您真正想要的是 local 时间,那么冬天的偏移量是
的计算机时区的本地时间+00:00
,而冬天的偏移量是+01:00
在夏天(在英国),然后使用Now
而不是UtcNow
。这给出代码为 运行ning.string c = DateTime.Now.ToString("yyyy-MM-dd'T'HH:mm:ssK", CultureInfo.InvariantCulture); // output example: "2019-07-08T23:59:00+01:00" string d = DateTimeOffset.Now.ToString("yyyy-MM-dd'T'HH:mm:sszzz", CultureInfo.InvariantCulture); // output example: "2019-07-08T23:59:00+01:00"
如果你真的想要英国时间而不考虑本地计算机的时区,那么你必须先获取UTC时间然后将其转换为英国时间在创建字符串之前。
TimeZoneInfo tzi = TimeZoneInfo.FindSystemTimeZoneById("GMT Standard Time"); string e = TimeZoneInfo.ConvertTime(DateTime.UtcNow, tzi).ToString("yyyy-MM-dd'T'HH:mm:ssK", CultureInfo.InvariantCulture); // output example: "2019-07-08T23:59:00" string f = TimeZoneInfo.ConvertTime(DateTimeOffset.UtcNow, tzi).ToString("yyyy-MM-dd'T'HH:mm:sszzz", CultureInfo.InvariantCulture); // output example: "2019-07-08T23:59:00+01:00"
在示例
e
中,请注意DateTime
无法存储时区转换结果的任意偏移量,因此您将DateTimeKind.Unspecified
分配给Kind
属性,这导致字符串表示中没有偏移量。因此,大多数时候您应该使用DateTimeOffset
(例如f
)。另外,请注意
"GMT Standard Time"
的时区 ID 是在 Windows 平台上用于英国的正确 ID。它会在适当的时候在 GMT 和 BST 之间正确切换。如果您在 non-Windows 平台(Linux、OSX 等)上 运行ning .NET Core,那么您应该改用"Europe/London"
。或者,如果您想编写 platform-neutral 的代码,那么您可以使用我的 TimeZoneConverter 库,它允许您在任何平台上提供任何一种形式和 运行。在您的代码示例中,您没有调用任何“now”函数,但提供了一个
dt
变量。假设这是一个DateTime
,调用TimeZoneInfo.ConvertTimeToUtc
的结果将取决于该变量的Kind
属性。如果是DateTimeKind.Utc
,则不执行任何转换。如果是DateTimeKind.Local
或DateTimeKind.Unspecified
,则该值将从计算机的本地时区转换为 UTC。最后,请记住,在与国际观众交谈时,时区缩写可能会产生歧义。我可以通过“BST”推断出您的意思是英国夏令时,但这只是因为您在问题中显示了
+01:00
偏移量。 “BST”也可以代表“孟加拉国标准时间”(+06:00
),或“布干维尔标准时间”(+11:00
)。