将当前本地时间转换为任何其他时区

本文关键字:任何 其他 时区 转换 时间 | 更新日期: 2023-09-27 18:14:06

我想通过将本地时间与UTC进行比较来测试一些与时区相关的代码。然而,这项测试依赖于当地时间与UTC不同,而我在英国,因此根据DateTime比较测试,一年中有6个月的当地时间是UTC(由于夏季时间(。

我可以对我的测试进行硬编码,将UTCNow转换到像EST这样的某个时区,但我的代码在美国系统中使用的可能性很小,现在我遇到了同样的问题。

那么,有没有一种方法可以让我轻松地将DateTime.UtcNow转换为一个与我当地时区完全不同的时区,而无需对其进行硬编码或假设我所在的时区?

将当前本地时间转换为任何其他时区

好吧,正如我在评论中指导的那样,如果你想获得与你不同的时区,你可以这样做:

var zone = TimeZoneInfo.GetSystemTimeZones()
           .Where(x=>x.BaseUtcOffset != TimeZoneInfo.Local.BaseUtcOffset)
           .First();

要将UTC DateTime转换为另一个时区,您必须使用TimeZoneInfo.ConvertTimeFromUtc,示例:

var datetime = // datetime in UTC, for example, DateTime.UtcNow
var zone = // target zone
return TimeZoneInfo.ConvertTimeFromUtc(datetime, zone);

你可以在这里查看我的宠物项目中的样本

.net中的时区是一个非常令人困惑的问题。DateTime只支持本地和UTC时区。实际上,它没有不同时区的概念,因为它只从机器获得当前偏移量,并将其应用于UTC的刻度计数值。

所以一开始没有办法换到另一个时区,但你可以模拟一些东西。如果你想在每个例子中模拟时区GMT+2,你必须首先检索当前区域偏移量,并将该偏移量和所需偏移量的差值添加到本地日期,类似这样:

TimeSpan targetOffset = new TimeSpan(2, 0, 0) - TimeZoneInfo.Local.BaseUtcOffset; //target to GMT+2
DateTime targetNow = DateTime.Now + targetOffset;

通过这种方式,Date将具有与该时区相同的值,但对于使用datetime对象而不仅仅是年/月/天/小时/分钟/秒的计算,所有这些值都将是错误的,因为对象将被标记为本地,因此将具有错误的值。

要解决此问题,您有两种选择,颠倒逻辑(将非本地时间转换为本地时间(或只使用UTC日期。

第一种方法非常简单:

DateTime nonLocal = new DateTime(2016, 10, 21, 13, 33, 0); //We suppose we want 2016-10-21 13:33:00 at GMT+2
DateTime local = nonLocal + (TimeZoneInfo.Local.BaseUtcOffset - new TimeSpan(2, 0, 0));

这将产生正确的DateTime操作,但是,在这里我们再次遇到问题,如果您使用年/月/天/小时/分钟,它们将在您的本地区域中,而不是在假定的区域中,并且使用这些属性的代码将失败。

最后,最好的方法是第二种方法,你只需忘记时区,每当你得到DateTime时,你就会将其转换为UTC,一切都会完美地工作,当你需要表示数据时,只需将其转换成本地数据,一切都完成了,无需担心DateTime算法或属性会因为它们在另一个时区而不同。

 public static class DateTimeExtensions
    {
        public static DateTime As(this DateTime source, string timeZoneName)
        {
            DateTime utcTime = DateTime.SpecifyKind(source, DateTimeKind.Unspecified);
            TimeZoneInfo newTimeZone = TimeZoneInfo.FindSystemTimeZoneById(timeZoneName);
            return TimeZoneInfo.ConvertTimeFromUtc(utcTime, newTimeZone);
        }
    }

用法:

        DateTime date1 = DateTime.UtcNow;
        DateTime date2 = date1.As("Eastern Standard Time");
相关文章: