简体   繁体   English

如何将日期时间转换为 c# 中的特定时区?

[英]How to convert a datetime to specific timezone in c#?

I need help converting a DateTime to a specific time zone.我需要帮助将DateTime转换为特定时区。 What I have below is not working correctly.我下面的内容无法正常工作。

gmTime = 03/02/2013 1:00:00 AM gmTime = 03/02/2013 1:00:00 AM

 TimeZoneInfo timeZone = TimeZoneInfo.FindSystemTimeZoneById("Eastern Standard Time");
 var time = timeZoneInfo.ConvertTime(gmTime, timeZone);

When I debug the value of time , which should be 03/01/2013 8:00:00 PM when the zone is applied, it comes back as 03/02/2013 1:00:00 AM .当我调试 time 的值time ,应用区域时应该是03/01/2013 8:00:00 PM ,它返回为03/02/2013 1:00:00 AM

If I do time.ToLocalTime() then I get the correct value.如果我做time.ToLocalTime()那么我得到正确的值。 However, I need to convert time to different time zones.但是,我需要将time转换为不同的时区。

DateTime objects have a "Kind" variable which helps TimeZoneInfo know how to treat it. DateTime对象有一个“Kind”变量,可以帮助TimeZoneInfo知道如何处理它。 In the MSDN documentation for TimeZone.ConvertTime it has the following: 在TimeZone.ConvertTime的MSDN文档中 ,它具有以下内容:

DateTimeKind.Local, Converts the local time to the time in destinationTimeZone. DateTimeKind.Local,将本地时间转换为destinationTimeZone中的时间。

DateTimeKind.Utc, Converts Coordinated Universal Time (UTC) to the time in destinationTimeZone. DateTimeKind.Utc,将协调世界时(UTC)转换为destinationTimeZone中的时间。

DateTimeKind.Unspecified, Assumed to be Local. DateTimeKind.Unspecified,假设是本地的。

For example: 例如:

  Console.WriteLine("Local time zone is '{0}'.", TimeZoneInfo.Local.Id);

  var gmTime          = new DateTime(2013, 03, 02, 01, 00, 00, DateTimeKind.Utc);
  var localTime       = new DateTime(2013, 03, 02, 01, 00, 00, DateTimeKind.Local);
  var unspecifiedTime = new DateTime(2013, 03, 02, 01, 00, 00);

  var timeZone = TimeZoneInfo.FindSystemTimeZoneById("Eastern Standard Time");

  var gmTimeConverted           = TimeZoneInfo.ConvertTime(gmTime,          timeZone); // 03/02/2013 8:00:00AM
  var localTimeConverted        = TimeZoneInfo.ConvertTime(localTime,       timeZone); // 03/02/2013 
  var unspecifiedTimeConverted  = TimeZoneInfo.ConvertTime(unspecifiedTime, timeZone);

  Console.WriteLine("Converting GMT         to EST: {0}", gmTimeConverted);
  Console.WriteLine("Converting Local       to EST: {0}", localTimeConverted);
  Console.WriteLine("Converting Unspecified to EST: {0}", unspecifiedTimeConverted);

Results in: 结果是:

Local time zone is 'Pacific Standard Time'.
Converting GMT         to EST: 3/1/2013 8:00:00 PM
Converting Local       to EST: 3/2/2013 4:00:00 AM
Converting Unspecified to EST: 3/2/2013 4:00:00 AM

Or if your local timezone is 'Eastern Standard Time' you get these results 或者,如果您当地的时区是“东部标准时间”,则会获得这些结果

Local time zone is 'Eastern Standard Time'.
Converting GMT         to EST: 3/1/2013 8:00:00 PM
Converting Local       to EST: 3/2/2013 1:00:00 AM
Converting Unspecified to EST: 3/2/2013 1:00:00 AM



If you'd like TimeZoneInfo to treat 'Unspecified' like Utc, you should function like TimeZoneInfo.ConvertTimeFromUtc. 如果您希望TimeZoneInfo像Utc一样处理'Unspecified',那么您应该像TimeZoneInfo.ConvertTimeFromUtc一样运行。 Again from MSDN documentation 再次来自MSDN文档

DateTimeKind.Local, Throws an ArgumentException. DateTimeKind.Local,抛出ArgumentException。

DateTimeKind.Unspecified or DateTimeKind.Utc, Converts from Coordinated Universal Time (UTC). DateTimeKind.Unspecified或DateTimeKind.Utc,从协调世界时(UTC)转换。

Try something like the following Chace 尝试类似下面的Chace

TimeZoneInfo estTimeZone = TimeZoneInfo.FindSystemTimeZoneById("Eastern Standard Time");
DateTime estDateTime = TimeZoneInfo.ConvertTimeFromUtc(timeUtc, estTimeZone);

The following code will let you go from any arbitrary time zone to any other.下面的代码将让你 go 从任何任意时区到任何其他。 We make use of DateTimeOffset which will allow you to pass the UTC Offset in. You may consider whether just using DateTimeOffset instead of DateTime will suit your needs.我们使用DateTimeOffset ,它允许您传入 UTC 偏移量。您可以考虑仅使用DateTimeOffset而不是DateTime是否适合您的需要。 But if you want to use DateTime instead, here is some code that will do the conversion for you:但是如果您想改用DateTime ,这里有一些代码可以为您进行转换:

public DateTime ChangeTimeZone(DateTime dateTimeInput, TimeZoneInfo sourceTimeZone, TimeZoneInfo destTimeZone)
{
    var zonedTime = new DateTimeOffset(DateTime.SpecifyKind(dateTimeInput, DateTimeKind.Unspecified),
                                       sourceTimeZone.GetUtcOffset(dateTimeInput));
    var utcTime = zonedTime.UtcDateTime;
    
    return TimeZoneInfo.ConvertTime(utcTime, destTimeZone);
}

You may notice that we explicitly call SpecifyKind and set it to Unspecified .您可能会注意到我们显式调用SpecifyKind并将其设置为Unspecified The reason for this is because if the Kind is specified on the dateTimeInput then the UtcOffset must match that Kind -- so if it is DateTimeKind.Utc, then that number must be 0. If it is Local, then it must be whatever the local time offset is or you will get an exception.这样做的原因是,如果在dateTimeInput上指定了Kind ,那么 UtcOffset 必须与该Kind匹配——所以如果它是 DateTimeKind.Utc,那么该数字必须是 0。如果它是本地的,那么它必须是本地的任何内容时间偏移量是否则你会得到一个例外。 Of course, if you already know the Kind then you could skip this function and just go straight to TimeZoneInfo.ConvertTime .当然,如果您已经知道Kind ,那么您可以跳过此 function 并直接将 go 直接转到TimeZoneInfo.ConvertTime

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

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