C# 使用NodaTime将特定国家/地区日期时间转换为UTC

C# 使用NodaTime将特定国家/地区日期时间转换为UTC,c#,nodatime,C#,Nodatime,我想通过提供国家代码将特定日期时间值转换为UTC和NodaTime 例如,国家是土耳其,国家代码是TR,具体日期时间是“2016年2月5日下午7:45”,可能是“2016年2月5日下午5:45”吗 另外,我的windows位置不是土耳其 提前谢谢你?好吧,你不能只凭国家代码就这么做,你需要一个时区。在一些国家有多个时区 一旦您将时区设置为DateTimeZone(通过BCLTimeZoneInfo或TZDB时区提供商),您将: 根据您得到的值构造一个LocalDateTime,例如使用Loca

我想通过提供国家代码将特定日期时间值转换为UTC和NodaTime

例如,国家是土耳其,国家代码是TR,具体日期时间是“2016年2月5日下午7:45”,可能是“2016年2月5日下午5:45”吗

另外,我的windows位置不是土耳其


提前谢谢你?

好吧,你不能只凭国家代码就这么做,你需要一个时区。在一些国家有多个时区

一旦您将时区设置为
DateTimeZone
(通过BCL
TimeZoneInfo
或TZDB时区提供商),您将:

  • 根据您得到的值构造一个
    LocalDateTime
    ,例如使用
    LocalDateTimePattern
    解析文本
  • 立即调用
    LocalDateTime.InZoneElevely
    (或类似功能-稍后将详细介绍),以获取
    ZoneDateTime
  • 使用
    WithZone(DateTimeZone.Utc)
    将其转换为基于Utc的
    ZonedDateTime
关于
inzonely
inzonetrictly
InZone(DateTimeZone,zonelocalmappingsolver)
的部分是因为本地日期和时间可能在DST转换前后出现两次或根本不出现。有关这方面的详细信息,请参阅

示例代码:

using System;
using NodaTime;
using NodaTime.Text;

class Test
{
    static void Main()
    {
        var text = "Feb 5, 2016 7:45 PM";
        var zone = DateTimeZoneProviders.Tzdb["Europe/Istanbul"];
        var pattern = LocalDateTimePattern.CreateWithInvariantCulture("MMM d, YYYY h:mm tt");
        var local = pattern.Parse(text).Value;
        var zoned = local.InZoneStrictly(zone);
        var utc = zoned.WithZone(DateTimeZone.Utc);
        Console.WriteLine(utc); // 2016-02-05T17:45:00 UTC (+00)
    }
}
现在,为了从国家代码中查找时区,TZDB(IANA)数据库提供了关于时区位置的信息,这些信息在Noda time中公开。例如,如果您有一个ISO-3166双字母国家代码,您可以使用:

using NodaTime;
using NodaTime.TimeZones;
using System.Linq;
...
var code = "TR"; // Turkey
var zoneId = TzdbDateTimeZoneSource.Default.ZoneLocations
                                   .Single(loc => loc.CountryCode == code)
                                   .ZoneId;
var zone = DateTimeZoneProviders.Tzdb[zoneId];
如果有多个区域具有给定的国家/地区代码(或没有),则单个调用将失败

如果要经常查找区域,可能需要建立一个字典:

var zonesByCountryCode = TzdbDateTimeZoneSource.Default
   .ZoneLocations
   .GroupBy(loc => loc.CountryCode)
   .Where(g => g.Count() == 1) // Single-zone countries only
   .ToDictionary(g => g.Key, g => g.First());

非常感谢您的快速回复。但我只有国家代码和国家名称,没有国家的城市或地区数据。我不需要转换时区不同的国家。例如希腊、冰岛、土耳其、伊朗等,它们只有一个时区。有可能吗?@Kerberos:基本上你需要一个从国家名称到时区ID的映射。这在野田佳彦的时间内并不存在,但你可以自己硬编码。对不起。我是时间转换方面的新手。zone Id是什么意思?我如何通过提供国家名称来查找zone Id?@Kerberos:事实上,我刚刚记得野田佳彦时代确实有国家信息。“@Kerberos:这取决于你的确切意思是什么时候。我想你会发现阿根廷的多个时区有不同的规则,这些规则在不同的时间生效——可能是历史性的,也可能是未来的。