Parsing of Ordered Timestamps in Local Time (to UTC) While Observing Daylight Saving Time

后端 未结 2 1882
借酒劲吻你
借酒劲吻你 2020-11-27 08:26

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 th

2条回答
  •  感情败类
    2020-11-27 08:55

    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 UTC
    

    Note 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.

提交回复
热议问题