如何使用NodaTime将IANA区域+日期时间转换为UTC +偏移量

时间:2014-12-30 16:07:34

标签: c# datetime utc nodatime iana

我有当地时间的字符串格式:“yyyy-MM-dd HH:mm:ss”和当时的IANA时区(例如“欧洲/伦敦”)。

如何在C#中将其转换为UTC + TimeZone Offset字符串

,可能使用NodaTime

e.g。 “yyyy-MM-dd HH:mm:ss + 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);

感谢Matt(见下面的答案),我现在拥有了我需要的功能(请注意,我最终需要的是UTC而不是日期时间+偏移量):

有点令人担忧的是,欧洲/莫斯科是UTC + 04:00,而实际上是UTC + 03:00,自2014年10月26日起。

    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 个答案:

答案 0 :(得分:8)

从您的问题中不清楚您是否认为原始值是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);

另外 - 你应该注意到,在12月,伦敦是格林威治标准时间(UTC + 00:00) - 因此,对于你提供的值,任一函数的输出都是"2014-12-31 12:30:00+00:00"