Как преобразовать зону IANA + дату и время в UTC + смещение с помощью 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;
    }

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);

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

Другие вопросы по тегам