我有一个asp.net应用程序,必须每天在东部时区(DST感知)的特定时间运行一些代码。所以我的第一个想法是,获取东部时间值并将其转换为本地服务器时间。
所以我需要这样的东西:
var eastern = DateTime.Today.AddHours(17); // run at 5pm eastern
var timeZoneInfo = TimeZoneInfo.FindSystemTimeZoneById("Eastern Standard Time");
var utc = TimeZoneInfo.ConvertTimeToUtc(eastern, timeZoneInfo);
var local = TimeZoneInfo.ConvertTimeFromUtc(utc, TimeZoneInfo.Local);
但是如何指定东部DateTime对象应该在EST时区中。
我接近这个错误的方式吗?
答案 0 :(得分:8)
首先,您需要考虑几件事情。你必须处理夏令时,它有时会发生变化(过去10年的开始和结束日期已经改变了两次)。所以在北半球冬季,东部时间是-5 GMT(或UTC)。但是,在夏季它是格林尼治标准时间-6,或者是格林尼治标准时间-4,我永远不能保持直线(我也不应该)。
有一些DNF库函数可以处理时区信息,但是你真的需要.net 3.5来获得最有用的东西。 .net 3.5中有TimeZoneInfo类。
TimeZoneInfo tzi = TimeZoneInfo.FindSystemTimeZoneById("Eastern Standard Time");
DateTime dt = TimeZoneInfo.ConvertTimeBySystemTimeZoneId(DateTime.Now,
TimeZoneInfo.IsDaylightSavingsTime(tzi) ?
tzi.DaylightName : tzi.StandardName);
if (dt.Hour == 17)
....
此外,请记住,每年两次丢失或获得一小时,所以如果您有一个倒计时器显示“下次处理的时间”或类似的东西,您还必须考虑到这一点。事实上,时间处理并不像最初想象的那么容易,并且存在很多边缘情况。
答案 1 :(得分:4)
DateTime
不了解时区。即使DateTimeOffset
并不真正了解某个时区 - 它知道UTC时刻和它的偏移量。
您可以编写自己的 <{1}}和TimeZoneInfo
的结构,但在这种情况下我不确定是否需要它。你是只是试图在东部时间下午5点安排,或者这实际上是否更为一般?之后你用DateTime
(或其他什么)做什么?使用DateTime
和DateTimeOffset
您绝对可以获得您感兴趣的UTC时刻;如果你只需要知道“现在”之间的时间,那就相当容易了。
我觉得有责任指出,当Noda Time准备就绪时,它几乎肯定是正确答案:)
答案 2 :(得分:3)
似乎我能够回答我自己的问题。这是我用来获取下一个DateTime
对象的代码。
private DateTime GetNextRun()
{
var today = DateTime.Today;
var runTime = new DateTime(today.Year, today.Month, today.Day, 17, 0, 0);
var timeZoneInfo = TimeZoneInfo.FindSystemTimeZoneById("Eastern Standard Time");
var offset = timeZoneInfo.GetUtcOffset(runTime);
var dto = new DateTimeOffset(runTime, offset);
if (DateTime.Now > dto.LocalDateTime)
dto = dto.AddDays(1);
return dto.LocalDateTime;
}
使用DateTimeOffset
代替DateTime
进行所有转换证明有效。它甚至似乎正确处理了夏令时。
答案 3 :(得分:1)
您可以使用DateTime.UtcNow来获取UTC中心时间(我认为是GMT 0),然后从htere获取您想要的时区数量,并为每个区域删除/添加一小时。< / p>