ASP.NET Time Conversion on server (Daylight Savings)
让我首先简要介绍一下我们的应用程序! (请不要立即关闭我的大帖子,它非常简单的场景,我只是描述性的!)我们有一个ASP.NET网站,主要是C#,作为我们所有商店的商店前端。特许经营权。
每个商店可能位于不同的时区,但我们需要在我们的网站上指明商店是开放还是关闭。
服务器有一个DB,其中包含指示不同商店的不同时间表的行,这些行可以在我们的asp.net网站上显示。
在我的数据库中,我有列和行,它们保存位置偏移量,并以UTC格式存储小时数。例;
- 位置ID:21
- TimeZoneOffSet:-5:00
- 星期日开放时间:15:45
- 星期日关闭:16:20
我想出了一种在服务器上确定位置是否打开的方法。我很难确定它是否适用于夏令时。我的问题是,这是否解释了夏令时,我是否正确地了解了这种情况,因为我没有像这样对时间有所了解?
这是我在服务器端代码中所做的事情;
//这是我用来保存数据库中商店计划的班级的重要部分
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 | public class TimeSchedule { public TimeSpan locationOffset { get; set; } public TimeSpan sundayOpen { get; set; } public TimeSpan sundayClose { get; set; } public TimeSchedule() { locationOffset = new TimeSpan(); sundayOpen = new TimeSpan(); sundayClose = new TimeSpan(); } } //I have loaded a TimeSchedule object by id TimeSchedule schedule = location.getTimeScheduleByLocationID(21); // Get the UTC time DateTime utcNow = new DateTime(); utcNow = DateTime.UtcNow; //Get the offset value that we stored in our schedule object TimeSpan locationOffSetHour = schedule.locationOffset; //I then apply the location offset hour to the server utc time. DateTime locationTime = new DateTime(); locationTime = utcNow.Add(locationOffSetHour); // Get the day of the week from our locationTime that we off setted from UTC string LocationWeekDay = locationTime.DayOfWeek.ToString(); // Now for each case of week day, I check to see if the difference in time is >= 0 // If so I assume the store is open TimeSpan zeroDifference = new TimeSpan(0, 0, 0); // This switch case just gets the difference in time according to LocationTime (that we offset'd from UTC) and stored time for the location on the server. // Then verifies that the location is open for that day switch (LocationWeekDay) { case"Sunday": // Verify that location is open, turn on open sign TimeSpan differenceOpenTimeSun = new TimeSpan(); differenceOpenTimeSun = locationTime.TimeOfDay - schedule.sundayOpen; TimeSpan differenceCloseTimeSun = new TimeSpan(); differenceCloseTimeSun = schedule.sundayClose - locationTime.TimeOfDay; if (differenceOpenTimeSun >= zeroDifference && differenceCloseTimeSun > zeroDifference) { imgSign.ImageUrl ="~/SiteImages/open.jpg"; } else { imgSign.ImageUrl ="~/SiteImages/closed.jpg"; } break; } |
感谢您抽出宝贵时间查看我的解决方案!任何"单挑"或"禁忌"都会受到高度赞赏!
采取自由重构。不是说我会做这样的事情,因为我可能会对数据库中的打开和关闭值进行非规范化,但是......这里......
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 | //I have loaded a TimeSchedule object by id TimeZoneInfo tzi = TimeZoneInfo.FindSystemTimeZoneById(schedule.LocationId); // Get the UTC time DateTime utcNow = DateTime.UtcNow; //I then apply the location offset hour to the server utc time. DateTime currentUtcTime = DateTime.UtcNow; DateTime locationTime = TimeZoneInfo.ConvertTimeFromUtc(currentUtcTime, tzi); // Get the day of the week from our locationTime that we off setted from UTC string locationWeekDay = locationTime.DayOfWeek.ToString(); // Now for each case of week day, I check to see if the difference in time is >= 0 // If so I assume the store is open TimeSpan zeroDifference = new TimeSpan(0, 0, 0); // This switch case just gets the difference in time according to LocationTime (that we offset'd from UTC) and stored time for the location on the server. // Then verifies that the location is open for that day switch (locationWeekDay) { case"Sunday": // Verify that location is open, turn on open sign TimeSpan differenceOpenTimeSun = currentUtcTime.TimeOfDay - schedule.sundayOpen; TimeSpan differenceCloseTimeSun = schedule.sundayClose - currentUtcTime.TimeOfDay; if (differenceOpenTimeSun >= zeroDifference && differenceCloseTimeSun > zeroDifference) { imgSign.ImageUrl ="~/SiteImages/open.jpg"; } else { imgSign.ImageUrl ="~/SiteImages/closed.jpg"; } break; |
}
程序中的以下代码行是处理时区并获取当地时间:
1 2 3 4 5 6 7 8 9 10 | // Get the UTC time DateTime utcNow = new DateTime(); utcNow = DateTime.UtcNow; //Get the offset value that we stored in our schedule object TimeSpan locationOffSetHour = schedule.locationOffset; //I then apply the location offset hour to the server utc time. DateTime locationTime = new DateTime(); locationTime = utcNow.Add(locationOffSetHour); |
但是,此代码仅处理添加时区偏移值而不处理DST的处理。
因此,如果您想获得DST,还有两种选择:
如果您使用的是.NET 3.5及更高版本,则可以使用此选项:
DateTime east = TimeZoneInfo.ConvertTimeBySystemTimeZoneId(DateTime.UtcNow,"Eastern Standard Time");
TimeZoneInfo类仅在.NET 3.5及更高版本中可用。
一些建议和意见......
查看C#TimeZoneInfo类。 http://msdn.microsoft.com/en-us/library/system.timezoneinfo.aspx
它包含一些方法,可以使您的时区转换准确。例如,您可以存储TimeZoneId,而不是将TimeZoneOffset存储在数据库中。然后使用......
1 | TimeZoneInfo tzi = TimeZoneInfo.FindSystemTimeZoneById(string id); |
然后而不是..
1 | locationTime = utcNow.Add(locationOffSetHour); |
你可以做...
1 | DateTime locationTime = ConvertTimeFromUtc(utcNow, tzi) ; |
得到当地时间。这将为您提供更准确的偏移,因为它支持夏令时。
查看所有其他代码,看看TimeZoneInfo类是否包含您可以使用的属性和方法,而不是滚动自己的属性和方法。
您也不需要初始化值,然后立即覆盖它......
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | // Change this... DateTime utcNow = new DateTime(); utcNow = DateTime.UtcNow; // to this... DateTime utcNow = DateTime.UtcNow; // and this... TimeSpan differenceOpenTimeSun = new TimeSpan(); differenceOpenTimeSun = locationTime.TimeOfDay - schedule.sundayOpen; // to this... TimeSpan differenceOpenTimeSun = locationTime.TimeOfDay - schedule.sundayOpen; // etc... |
您说您将数据库中的时间存储在UTC中。我假设你正在将此转换为本代码之外的某个地方,因为你这样做...
1 | differenceCloseTimeSun = schedule.sundayClose - locationTime.TimeOfDay |
您可以考虑对两个值使用UTC时间,这样您就不必在计算差异之前进行转换。
您可能仍需要进行时区转换以确定星期几,但您不必进行转换以确定商店是打开还是关闭。
您并没有真正使用标准命名约定。不是必需的,但我会建议使用Microsoft标准作为起点。在StackOverflow上提问时,人们更容易阅读代码:)
http://msdn.microsoft.com/en-us/library/ff926074.aspx
希望这对你有所帮助。