Как преобразовать зону IANA + datetime в UTC + Offset с помощью NodaTime

У меня местное время в строковом формате: «гггг-ММ-дд ЧЧ: мм: сс» и часовой пояс IANA для этого времени (например, «Европа / Лондон»).

Как преобразовать это в C #, возможно, используя NodaTime, в строку смещения UTC + TimeZone

например "гггг-ММ-дд ЧЧ: мм: сс + 01: 00"?

Даже не знаю с чего начать!

Насколько я понимаю (боюсь, я новичок в C Sharp): я понимаю, что мне нужно преобразовать его в мгновение, но просто не могу разобраться с библиотекой.

string dateTime = "2014-12-31 12:30:00";
string IANA = "Europe/London";
Instant instDateTime = NodaTime.Instant.FromDateTimeUtc(Convert.ToDateTime(dateTime));
string outputUTC = string.Format("yyyy-MM-dd HH:mm:ssZ", instDateTime);

Благодаря Мэтту (см. Ответ ниже) у меня теперь есть нужные мне функции (обратите внимание, что в итоге мне понадобилось UTC, а не дата, время + смещение):

Что немного беспокоит, так это то, что там сказано, что Европа / Москва - это UTC + 04:00, тогда как на самом деле это UTC + 03:00 с 26 октября 2014 года.

    static void Main(string[] args)
    {
        string dateTime = "2014-12-31T12:30:00";
        string timeZone = "Europe/Moscow";

        Console.WriteLine(timeZone + " Local time '" + dateTime + "' to Zulu time");
        Console.WriteLine(ConvertIANALocalTimeToZulu(timeZone, dateTime));
        Console.WriteLine();
        Console.WriteLine("Zulu time '" + dateTime + "' to " + timeZone + " local time");
        Console.WriteLine(ConvertZuluTimeToIANALocalTime(timeZone, dateTime));

        Console.ReadLine();
    }

    static string ConvertIANALocalTimeToZulu(string timeZoneIANA, string localDateTime)
    {
        var pattern = LocalDateTimePattern.CreateWithInvariantCulture("yyyy-MM-ddTHH:mm:ss");
        LocalDateTime ldt = pattern.Parse(localDateTime).Value;
        ZonedDateTime zdt = ldt.InZoneLeniently(DateTimeZoneProviders.Tzdb[timeZoneIANA]);
        Instant instant = zdt.ToInstant();
        ZonedDateTime zulu = instant.InUtc();
        ////string output = zulu.ToString("yyyy-MM-dd HH:mm:sso<m>", CultureInfo.InvariantCulture);
        string output = zulu.ToString("yyyy-MM-ddTHH:mm:ss", CultureInfo.InvariantCulture);

        return output;
    }

    static string ConvertZuluTimeToIANALocalTime(string timeZoneIANA, string zuluDateTime)
    {
        var pattern = InstantPattern.CreateWithInvariantCulture("yyyy-MM-ddTHH:mm:ss");
        Instant instant = pattern.Parse(zuluDateTime).Value;
        ZonedDateTime zdt = instant.InZone(DateTimeZoneProviders.Tzdb[timeZoneIANA]);
        ////string output = zdt.ToString("yyyy-MM-dd HH:mm:sso<m>", CultureInfo.InvariantCulture);
        string output = zdt.ToString("yyyy-MM-ddTHH:mm:ss", CultureInfo.InvariantCulture);

        return output;
    }

person Paul Panayis    schedule 30.12.2014    source источник
comment
Начните с кода публикации. Даже ужасно сломанный код позволяет кому-то помочь вам преодолеть первое препятствие, которое вы не преодолели.   -  person bmike    schedule 30.12.2014
comment
Проявите достойные усилия и вам кто-то поможет!   -  person mybirthname    schedule 30.12.2014
comment
Я прочитал этот пост о преобразовании текста из IANA в Windows, но я не понимаю, что здесь происходит. преобразование часового пояса iana в Windows   -  person Paul Panayis    schedule 30.12.2014
comment
@PaulPanayis - Этот вопрос касается преобразования между системой часовых поясов IANA и системой часовых поясов Microsoft Windows - это не то, что вам кажется интересным из вашего сообщения. Дополнительные сведения см. В вики-странице тега часового пояса.   -  person Matt Johnson-Pint    schedule 31.12.2014


Ответы (1)


Из вашего вопроса неясно, имели ли вы в виду, что исходное значение было в UTC или по местному времени.

Если это время в формате UTC, сделайте следующее:

string dateTime = "2014-12-31 12:30:00";
string timeZone = "Europe/London";

var pattern = InstantPattern.CreateWithInvariantCulture("yyyy-MM-dd HH:mm:ss");
Instant instant = pattern.Parse(dateTime).Value;
ZonedDateTime zdt = instant.InZone(DateTimeZoneProviders.Tzdb[timeZone]);
string output = zdt.ToString("yyyy-MM-dd HH:mm:sso<m>", CultureInfo.InvariantCulture);

Если это местное время, сделайте следующее:

string dateTime = "2014-12-31 12:30:00";
string timeZone = "Europe/London";

var pattern = LocalDateTimePattern.CreateWithInvariantCulture("yyyy-MM-dd HH:mm:ss");
LocalDateTime ldt = pattern.Parse(dateTime).Value;
ZonedDateTime zdt = ldt.InZoneLeniently(DateTimeZoneProviders.Tzdb[timeZone]);
string output = zdt.ToString("yyyy-MM-dd HH:mm:sso<m>", CultureInfo.InvariantCulture);

Также - вы должны отметить, что в декабре Лондон находится по Гринвичу (UTC + 00: 00) - поэтому результат любой функции будет "2014-12-31 12:30:00+00:00" для значений, которые вы указали.

person Matt Johnson-Pint    schedule 30.12.2014
comment
Привет, Мэтт, извини, что я не понял. Я начинаю с местного времени. Я действительно хочу преобразовать в Zulu Time, которое, как я понимаю, вообще не включает смещение? - person Paul Panayis; 31.12.2014
comment
Спасибо за помощь, указанную выше. Он исчерпывающе отвечает на мой вопрос и дает мне необходимое начало, чтобы разобраться во всем этом. - person Paul Panayis; 31.12.2014
comment
Рад помочь. Также обратите внимание, что вы, вероятно, можете немного упростить свои функции. Если вы используете полный формат ISO8601 (с разделителем T), вам помогут такие свойства, как LocalDateTimePattern.GeneralIsoPattern. Кроме того, если вы планируете форматировать без смещения или Z, вы можете повторно использовать один и тот же экземпляр LocalDateTimePattern для синтаксического анализа и форматирования вместо вызова ToString. Кроме того, вы можете пропустить шаг InUTC и отформатировать момент напрямую, так как это уже внутреннее всемирное координированное время. - person Matt Johnson-Pint; 31.12.2014
comment
Что касается часового пояса Москвы, то это изменение было внесено в tzdb после выпуска NodaTime 1.3. Встроенные данные NodaTime не обновляются автоматически. Вы должны сами управлять этим с помощью внешних данных, как описано в руководстве пользователя здесь. - person Matt Johnson-Pint; 31.12.2014