UTC to local time conversion for previously saved datetimes if rules for timezone change
我在数据库中存储一个产品。所有日期(SQL Server日期时间)都是UTC,以及我存储该产品时区ID的日期。用户在列表中输入"从"和"到"产品可用的日期。所以我做了如下的事情:
1 2 3 4 5 6 | // Convert user's datetime to UTC var userEnteredDateTime = DateTime.Parse("11/11/2014 9:00:00"); // TimeZoneInfo id will be stored along with the UTC datetime var tz = TimeZoneInfo.FindSystemTimeZoneById("FLE Standard Time"); // following produces: 9/11/2014 7:00:00 AM (winter time - 1h back) var utcDateTime = TimeZoneInfo.ConvertTimeToUtc(userEnteredDateTime, tz); |
并保存记录。假设用户在8月1日进行了此操作,而他与UTC的时区偏移量仍然是+03:00,但是,由于转换考虑了该时间段的"冬季"时间,因此为将来列表保存的日期具有正确的+02:00值。
问题是,如果我尝试在2014年11月11日将产品的"从"和"直到"日期转换为产品的本地时区,我将得到什么日期时间值?例如,如果由于一些新规则,到冬季的过渡被放弃,那么时区仍然是+03:00而不是+02:00?
1 2 | // Convert back var userLocalTime = TimeZoneInfo.ConvertTimeFromUtc(utcDateTime, tz); |
我会得到上午10点还是上午9点,因为OS/.NET补丁可以处理这个问题?
谢谢您!
p.s.:timezoneinfo有toserializedstring()方法,如果我更愿意存储这个值而不是timezone id,这是否保证通过UTC日期时间+序列化的timezoneinfo,我将始终能够转换为用户的原始日期时间输入?
(P)在你的描述中,你会得到10:00的上午。The time zone conversion function would not have any idea that the value was originally entered as 9:00 am,because you only saved the UTC time of 7:00 am.(p)(P)This illustrates one of the cases where the advice"always store utc"is flawed.当你处理未来事件时,它并不总是工作。The problem is that Governments change their mind about time zones often.Sometimes they give reasonable notice(Ex.United States,2007)but sometimes they don't(Ex.Egypt,2014).(p)(P)当你创造了从当地时间到UTC的最初转变,你试图决定相信时间规则不会改变。In other words,you decided that you would assign the event to the universal timeline based solely on the time zone rules as you knew them at that time.(p)(P)解决这一问题的方法很简单:今后的活动应当在当地时间安排。Now,I don't mean"local to your computer",but rather"local to the user",so you will need to know the user's time zone,and you should also store the ID of the time zone somewhere.(p)(P)You'll also need to decide what you want to do if the event falls into the spring-forward or fall-back transition for daylight saving time.这对于上诉模式特别重要。(p)(P)最后一个想法,你将需要在运行的事件。或者在你的案件中,你需要决定是否发生了这一事件。There are a few different ways you can accomplish this:(p)(P)备选案文1(p)
- (P)你可以计算出当地时间的相应的UTC值,并保持它在一个分离的领域。(p)
- (P)On some cycle(daily,weekly,etc)you can recalculate upcoming UTC values from their local values and your current understanding of the time zone rules.Or,if you apply time zone updates manually,you can choose to recruulate everything at that time.(p)
(P)备选案文2(p)
- (P)You can store the values as a EDOCX1 universal 0-type instead of a EDOCX1.这将包括最初的地方时间,以及你根据时间范围规则计算的时间,因为你知道他们在进入时。(p)
- (P)EDOCX1,O,C,O,O,O,O,OYou can read more in datette vs Datemioffset.(p)
- (P)Just like in option 1,you would review the values periodically or after time zone data updates,and adjust the offsets to align with the new time zone data.(p)
- (P)This is what I usually recommend,especially if you're using a database that has support for EDOCX1 universal 0 types,such as sql server or ravendb.(p)
(P)备选案文3(p)
- (P)你可以像本地的EDOCX1一样创造价值(p)
- (P)当你想的时候,你可以计算当前特定时间范围内的时间,并与这一价值进行比较。(p)字母名称
- (P)The down side of this option is that you may have to make lots want if you have events in lots of different time zones.(p)
- (P)You may also have issues with values close to the fall-back dst transition,so be careful if you use this approach.(p)
(P)i recommend against the idea of serializing the time zone itself.如果时间区域发生了变化,它们就发生了变化。假装这不是一个很好的工作。(p)