время ноды: как изобразить «стандартное время» - PullRequest
0 голосов
/ 12 октября 2018

Я получаю данные из текстового файла, где даты часто бывают в «стандартном времени» (например, Центральное стандартное время или Восточное стандартное время. Я конкретно имею в виду, что никаких изменений летнего времени не наблюдается ).Используя Noda Time, я пытаюсь найти лучший способ представить это.

Моя первая мысль была, что я должен создать DateTimeZone для этого.Я заметил, что некоторые «стандартные часовые пояса» включены в базу данных tz (например, «America / Cancun» может использоваться для восточного стандартного времени), но другие часовые пояса, кажется, не имеют ничего, чтобы представлять их «стандартное время»"вариант в базе данных.

Тогда я подумал, что должен сделать Offset или сделать DateTimeZone прямо из Offset, но я не могу найти способ получить базовое смещение DateTimeZone.Для часовых поясов в континентальной части США я почти уверен, что смогу просто сделать DateTimeZone.ForOffset(localTimeZone.MinOffset) (где localTimeZone - DateTimeZone), но я очень сомневаюсь, что это сработает в некоторых из более странных часовых поясов.Я также попытался DateTimeZone.ForOffset(localTimeZone.GetZoneInterval(SystemClock.Instance.GetCurrentInstant()).StandardOffset), но это настолько окольным, что я подозреваю, что есть причина, почему это неправильно.

I может просто сохранить необработанное смещение, связанное с каждым провайдером файлов, но настройка приложения будет намного проще, если в конфигурации указано, что это центральное стандартное время, а не если в нем указаносмещение -6.

Мне не хватает способа сделать это?Или что-то не так с моей концептуализацией проблемы, так что это неправильный подход?

1 Ответ

0 голосов
/ 13 октября 2018

Не обязательно есть одно «базовое смещение» для DateTimeZone.Это может измениться со временем.Например, стандартное время на большей части Аляски в 1983 году изменилось с UTC-10 на UTC-9.

Теперь, когда может не быть проблемой для интересующих вас часовых поясов... в этом случае вы можете использовать подход «найти стандартное смещение для местного часового пояса в текущий момент, а затем создать постоянное смещение DateTimeZone из этого».Я бы, вероятно, использовал бы три выражения вместо вашего текущего мега-выражения, но он бы делал то, что вы хотите.

Если вы хотите часовой пояс, который эквивалентен существующему часовому поясу, включая любые изменения в его стандартном смещенииНо без какого-либо перехода на летнее время это сделать довольно сложно.Это можно сделать, но это не будет ужасно просто.Вы, вероятно, захотите свой собственный подкласс DateTimeZone, который принимает существующий DateTimeZone и выполняет итерацию по всем значениям ZoneInterval с начала времени до некоторой подходящей конечной точки (например, 2200, в качестве даты в далеком будущем, которая не будетиметь какие-либо изменения правил, указанные после него в течение достаточно долгого времени) и определите ваши новые ZoneInterval значения.Я мог бы предоставить пример реализации этого, если вы хотите, но вы действительно хотите подумать, было ли это то, что вы хотели в первую очередь ...

Вот некоторый код, чтобы показать вам все часовые пояса, которые изменилисьих стандартное смещение в какой-то момент между 1930 и 2100 годами - очевидно, вы можете легко изменить интервал, чтобы изменить критерии для более точного соответствия вашему контексту.

using System;
using System.Linq;
using NodaTime;
using NodaTime.Extensions;

class Test
{
    static void Main()
    {
        Instant min = Instant.FromUtc(1930, 1, 1, 0, 0, 0);
        Instant max = Instant.FromUtc(2100, 1, 1, 0, 0, 0);

        foreach (var zone in DateTimeZoneProviders.Tzdb.GetAllZones())
        {
            var initialStandard = zone.GetZoneInterval(min).StandardOffset;
            var zoneIntervals = zone.GetZoneIntervals(min, max);
            var firstChange = zoneIntervals.FirstOrDefault(zi => zi.StandardOffset != initialStandard);
            if (firstChange != null)
            {
                Console.WriteLine(zone.Id);
                Console.WriteLine($"Initial standard offset: {initialStandard}");
                Console.WriteLine($"First different standard offset: {firstChange}");
                Console.WriteLine();
            }
        }
    }
}
...