我想在GMT时区中指定一个时间,然后将其转换为本地时区,即EST。
这似乎是我想要的,但似乎还有很长的路要走!
有没有一种更简单的方法可以实现这一点:
public static TimeZoneInfo edtZone = TimeZoneInfo.FindSystemTimeZoneById("Eastern Standard Time");
public static TimeZoneInfo gmtZone = TimeZoneInfo.FindSystemTimeZoneById("GMT Standard Time");
public static CultureInfo ci = CultureInfo.InvariantCulture;
DateTime edtStartDT = TimeZoneInfo.ConvertTime(DateTime.SpecifyKind(DateTime.Now.Date.Add(new TimeSpan(18, 00, 00)), DateTimeKind.Unspecified), gmtZone, edtZone);
这可能是您正在寻找的:
// A timespan isn't really a time-of-day, but we'll let that slide for now.
TimeSpan time = new TimeSpan(18, 00, 00);
// Use the current utc date, at that time.
DateTime utcDateTime = DateTime.UtcNow.Date.Add(time);
// Convert to the US Eastern time zone.
TimeZoneInfo tz = TimeZoneInfo.FindSystemTimeZoneById("Eastern Standard Time");
DateTime easternDateTime = TimeZoneInfo.ConvertTimeFromUtc(utcDateTime, tz);
请注意,我们将当前UTC日期与您提供的时间配对。由于美国东部时间比UTC晚5或4小时,18:00后您将始终获得相同的日期。但是,如果您使用不同的时间,例如00:00,您会发现由此产生的东部时间在前天。这很正常。
关于你以前的代码的几个注意事项:
Windows时区ID
"Eastern Standard Time"
表示EST和EDT。它真的应该被称为"东部时间"。不要让这个名字混淆问题。GMT和UTC在所有现代用法中基本相同。除非你指的是伦敦使用的时区,否则你应该更喜欢UTC这个词。
Windows时区ID
"GMT Standard Time"
实际上不适用于GMT/UTC。它是伦敦使用的时区,在格林尼治标准时间(UTC+00:00)和英国夏令时(UTC+01:00)之间交替。如果您想要一个代表UTC的TimeZoneInfo
,则ID仅为"UTC"。(然而,在这种情况下,您并不真正需要它。)假设您的原始代码使用
DateTime.Now.Date
,它将假设计算机本地时区中的日期,可能不是UTC或Eastern。如果你发现自己在使用
DateTime.SpecifyKind
,在大多数情况下,你可能做错了什么。(加载或反序列化时会出现异常。)
关于我关于TimeSpan
不是一天中的真实时间的注释,以下是.NET让您处理的方式:
DateTime time = DateTime.Parse("18:00:00", CultureInfo.InvariantCulture);
DateTime utcDateTime = DateTime.UtcNow.Date.Add(time.TimeOfDay);
甚至更丑陋的一行:
DateTime utcDateTime = DateTime.Parse("18:00:00", CultureInfo.InvariantCulture,
DateTimeStyles.AssumeUniversal | DateTimeStyles.AdjustToUniversal);
就我个人而言,我更喜欢使用Noda Time,它有一个单独的LocalTime
类型,明确表示一天中不与特定日期绑定的时间。我还在努力将System.TimeOfDate
和System.Date
类型添加到CoreCLR中。