不幸的是,标准的 DateTime.Parse()函数将解析为(2013年11月3日):
时间字符串|解析当地时间|在DST |解析当地时间UTC | 12:45 am | 12:45 am |是| 4:45 am | 12:59:59 am | 12:59:59 am |是| 4:59:59 am | 01:00 am | 1:00 am |不| 6:00 am | 01:15 am |上午1:15 |不| 6:15 am所以它从来没有看到 1:00-1: 59:59 am 范围为DST,我解析的UTC时间戳在一小时内跳转。
有没有一个图书馆或类会让我解析时间戳,并考虑到DST的变化?像一些可实例化的类,将记住已经收到的时间戳流,并相应地调整解析的时间戳?
解析时可以进行的数据的假设:
注意:虽然我的软件在C#中,我没有特别标记C#/ .NET,因为我想我可以使用任何语言的解决方案的实现,如果需要,重新编码。
解决方案在C#中:
//定义输入值。 string [] input = {2013-11-03 00:45:00,2013-11-03 01:00:00,2013-11-03 01:15:00,2013-11-03 01:30:00,2013-11-03 01:45:00,2013-11-03 01:00:00,2013-11-03 01:15:00,2013-11-03 01:30:00 2013-11-03 01:45:00,2013-11-03 02:00:00,}; //获取输入意图被解释的时区。 TimeZoneInfo tz = TimeZoneInfo.FindSystemTimeZoneById(Eastern Standard Time); //为输出值创建一个数组 DateTimeOffset [] output = new DateTimeOffset [input.Length]; //从假设DST处于活动状态开始,当将 //从日光时间移动到标准时间时,会发生歧义。 bool dst = true; //通过输入迭代。 (int i = 0; i< input.Length; i ++) { //将输入字符串解析为具有未指定类型的DateTime DateTime dt = DateTime。 ParseExact(input [i],yyyy-MM-dd HH:mm:ss, CultureInfo.InvariantCulture); //确定偏移量。 TimeSpan offset; if(tz.IsAmbiguousTime(dt)) { //获取可能的偏移量,并使用DST标志和上一个条目 //来确定我们是否过去过渡点。这只能工作 //,因为我们有外界的知识,这些项目是顺序的。 TimeSpan [] offsets = tz.GetAmbiguousTimeOffsets(dt); offset = dst&&& (i == 0 || dt> = output [i - 1] .DateTime)?偏移量[1]:偏移量[0]; } else { //该值是明确的,所以只需获得单个偏移量即可。 offset = tz.GetUtcOffset(dt); } //使用确定的值构造DateTimeOffset DateTimeOffset dto = new DateTimeOffset(dt,offset); //我们可以明确地检查一个DateTimeOffset为夏令时, //设置下一次迭代的DST标志。 dst = tz.IsDaylightSavingTime(dto); //将DateTimeOffset保存到输出数组。 output [i] = dto; } //显示调试输出 foreach(输出中为var dto) { Console.WriteLine({ 0:yyyy-MM-dd HH:mm:ss zzzz} => {1:yyyy-MM-dd HH:mm:ss} UTC, dto,dto.UtcDateTime); }输出:
2013-11-03 00:45:00 -04:00 => 2013-11-03 04:45:00 UTC 2013-11-03 01:00:00 -04:00 => 2013-11-03 05:00:00 UTC 2013-11-03 01:15:00 -04:00 => 2013-11-03 05:15:00 UTC 2013-11-03 01:30:00 -04:00 => 2013-11-03 05:30:00 UTC 2013-11-03 01:45:00 -04:00 => 2013-11-03 05:45:00 UTC 2013-11-03 01:00:00 -05:00 => 2013-11-03 06:00:00 UTC 2013-11-03 01:15:00 -05:00 => 2013-11-03 06:15:00 UTC 2013-11-03 01:30:00 -05:00 => 2013-11-03 06:30:00 UTC 2013-11-03 01:45:00 -05:00 => 2013-11-03 06:45:00 UTC 2013-11-03 02:00:00 -05:00 => 2013-11-03 07:00:00 UTC请注意,这是假设您第一次遇到一个不明确的时间,如1:00,它将在DST。说你的列表被截断到最后的5个条目 - 你不会知道那些在标准的时间。在这种情况下,你可以做的不多。
I have CSV data files with timestamped records that are in local time. Unfortunately the data files cover the period where daylight saving time changes (Nov 3rd 2013) so the time component of the timestamps for the records go: 12:45, 1:00, 1:15, 1:30, 1:45, 1:00, 1:15, 1:30, 1:45, 2:00. I want to be able to convert and store the values in the database as UTC.
Unfortunately the standard DateTime.Parse() function of .NET will parse as this (all November 3rd 2013):
| Time String | Parsed Local Time | In DST | Parsed Local Time to UTC | 12:45 am | 12:45 am | Yes | 4:45 am | 12:59:59 am | 12:59:59 am | Yes | 4:59:59 am | 01:00 am | 1:00 am | No | 6:00 am | 01:15 am | 1:15 am | No | 6:15 amSo it never sees the 1:00-1:59:59 am range as being in DST and my parsed timestamps in UTC jumps an hour.
Is there a library or class out there that will allow me to parse the timestamps and take into account the change in DST? Like some instantiatable class that will remember the stream of timestamps it's already received and adjust the parsed timestamp accordingly?
Assumptions about the data that can be made while parsing:
Note: While my software is in C#, I did not tag C#/.NET specifically as I figured I could use any language's implementation of a solution and recode if necessary.
解决方案In C#:
// Define the input values. string[] input = { "2013-11-03 00:45:00", "2013-11-03 01:00:00", "2013-11-03 01:15:00", "2013-11-03 01:30:00", "2013-11-03 01:45:00", "2013-11-03 01:00:00", "2013-11-03 01:15:00", "2013-11-03 01:30:00", "2013-11-03 01:45:00", "2013-11-03 02:00:00", }; // Get the time zone the input is meant to be interpreted in. TimeZoneInfo tz = TimeZoneInfo.FindSystemTimeZoneById("Eastern Standard Time"); // Create an array for the output values DateTimeOffset[] output = new DateTimeOffset[input.Length]; // Start with the assumption that DST is active, as ambiguities occur when moving // out of daylight time into standard time. bool dst = true; // Iterate through the input. for (int i = 0; i < input.Length; i++) { // Parse the input string as a DateTime with Unspecified kind DateTime dt = DateTime.ParseExact(input[i], "yyyy-MM-dd HH:mm:ss", CultureInfo.InvariantCulture); // Determine the offset. TimeSpan offset; if (tz.IsAmbiguousTime(dt)) { // Get the possible offsets, and use the DST flag and the previous entry // to determine if we are past the transition point. This only works // because we have outside knowledge that the items are in sequence. TimeSpan[] offsets = tz.GetAmbiguousTimeOffsets(dt); offset = dst && (i == 0 || dt >= output[i - 1].DateTime) ? offsets[1] : offsets[0]; } else { // The value is unambiguous, so just get the single offset it can be. offset = tz.GetUtcOffset(dt); } // Use the determined values to construct a DateTimeOffset DateTimeOffset dto = new DateTimeOffset(dt, offset); // We can unambiguously check a DateTimeOffset for daylight saving time, // which sets up the DST flag for the next iteration. dst = tz.IsDaylightSavingTime(dto); // Save the DateTimeOffset to the output array. output[i] = dto; } // Show the output for debugging foreach (var dto in output) { Console.WriteLine("{0:yyyy-MM-dd HH:mm:ss zzzz} => {1:yyyy-MM-dd HH:mm:ss} UTC", dto, dto.UtcDateTime); }Output:
2013-11-03 00:45:00 -04:00 => 2013-11-03 04:45:00 UTC 2013-11-03 01:00:00 -04:00 => 2013-11-03 05:00:00 UTC 2013-11-03 01:15:00 -04:00 => 2013-11-03 05:15:00 UTC 2013-11-03 01:30:00 -04:00 => 2013-11-03 05:30:00 UTC 2013-11-03 01:45:00 -04:00 => 2013-11-03 05:45:00 UTC 2013-11-03 01:00:00 -05:00 => 2013-11-03 06:00:00 UTC 2013-11-03 01:15:00 -05:00 => 2013-11-03 06:15:00 UTC 2013-11-03 01:30:00 -05:00 => 2013-11-03 06:30:00 UTC 2013-11-03 01:45:00 -05:00 => 2013-11-03 06:45:00 UTC 2013-11-03 02:00:00 -05:00 => 2013-11-03 07:00:00 UTCNote that this assumes that the first time you encounter an ambiguous time like 1:00 that it will be in DST. Say your list was truncated to just the last 5 entries - you wouldn't know that those were in standard time. There's not much you could do in that particular case.
更多推荐
在观察夏令时期间,分析当地时间(至UTC)的有序时间戳
发布评论