我想将日期时间从一个时区转换为另一个时区。为此,我需要将区域 id 传递给方法 FindSystemTimeZoneById。但我没有这些信息,需要通过使用 switch-case 来确定。
在这里我还需要考虑夏令时。但为了确定某个时间是否处于夏令时,我需要事先获得该区域 ID。
有没有办法在没有区域 ID 的情况下确定时间是否处于夏令时。我的服务器位于区域 1,我想将时间转换到区域 2。
这是片段:
public DateTime ConvertToDestTime(DateTime currentTime, string sourceTimeZoneUtc, string serverTimeZoneUtc)
{
TimeZoneInfo sourceTimeZone = TimeZoneInfo.FindSystemTimeZoneById(ReturnTimeZoneString(sourceTimeZoneUtc));
TimeZoneInfo serverTimeZone = TimeZoneInfo.FindSystemTimeZoneById(ReturnTimeZoneString(serverTimeZoneUtc));
DateTime serverTime = TimeZoneInfo.ConvertTime(currentTime, sourceTimeZone, serverTimeZone);
return serverTime;
}
private string ReturnTimeZone(string utcOffset)
{
string timezone = string.Empty;
string isDaylight = //need to determine whether time is in DST here
if (isDaylight == "N")
{
switch (utcOffset)
{
case "-04:00":
timezone = "Atlantic Standard Time";
break;
case "-05:00":
timezone = "Eastern Standard Time";
break;
}
}
else
{
switch (utcOffset)
{
case "-04:00":
timezone = "Eastern Standard Time";
break;
case "-05:00":
timezone = "Central America Standard Time";
break;
}
}
return timezone;
将源时间转换为 UTC 时间。
string sourceTimeZone="Atlantic Standard Time;
TimeZoneInfo timeZoneInfo = TimeZoneInfo.FindSystemTimeZoneById(sourceTimeZone);
DateTime sourceUTCTime = TimeZoneInfo.ConvertTimeToUtc(currentTime, timeZoneInfo);
然后使用转换后的 UTC 时间获取目的地时间,如下所示,
string destinationTimeZone="India Standard Time";
TimeZoneInfo destTimeZoneInfo = TimeZoneInfo.FindSystemTimeZoneById(destinationTimeZone);
DateTime destinationUTCTime = TimeZoneInfo.ConvertTimeFromUtc(sourceUTCTime, destTimeZoneInfo);
希望这有帮助!!!
查看 Microsoft 的“永恒”文章 在 .NET Framework 中使用 DateTime 进行编码最佳实践。
这篇文章可能已经有几年了,但原理和问题场景仍然是今天的主题。
有专门的章节介绍处理夏令时。
通过在之前将您的本地时间视图转换为通用时间 进行计算,您就可以克服时间问题 准确度。
因此,请先将本地时间转换为 UTC 格式,然后再转换为目标时间格式。
public static class DateTimeExtension
{
public static DateTime ConvertBetweenTimeZones(this DateTime d, string sourceTimeZone, string destinationTimeZone)
{
var tziSource = TimeZoneInfo.FindSystemTimeZoneById(sourceTimeZone);
var tziDestination = TimeZoneInfo.FindSystemTimeZoneById(destinationTimeZone);
var utcDate = TimeZoneInfo.ConvertTimeToUtc(d, tziSource);
return TimeZoneInfo.ConvertTimeFromUtc(utcDate, tziDestination);
}
}
还有一些单元测试:
[TestClass]
public class DateTimeTests
{
[TestMethod]
public void ConvertBetweenTimeZonesTest()
{
var dateTime = new DateTime(2023, 1, 27, 21, 0, 0);
var sourceTimeZone = "Central European Standard Time";
var destTimeZone = "UTC-02";
var dateResult = dateTime.ConvertBetweenTimeZones(sourceTimeZone, destTimeZone);
var expectedDate = new DateTime(2023, 1, 27, 18, 0, 0);
Assert.AreEqual(expectedDate, dateResult);
}
}
[TestClass]
public class TimeZoneInfoTests
{
[TestMethod]
public void ConvertBetweenTimeZonesTest()
{
var timeZone = "Central European Standard Time";
var tzi = TimeZoneInfo.FindSystemTimeZoneById(timeZone);
Assert.AreEqual("UTC+01:00", tzi.GetShortName());
}
}
public static String GetShortName(this TimeZoneInfo info)
{
return info.DisplayName.Split('(')[1].Split(')')[0];
}