.NET Noda Time 将本地日期时间转换为特定时区的 UTC
.NET Noda Time Converting Local DateTime To UTC for a specific Timezone
我正在使用 Noda Time 将 local datetime 转换为 UTC。
这是我目前拥有的:
static string LocalTimeToUTC(string timeZone, string localDateTime)
{
var pattern = LocalDateTimePattern.CreateWithInvariantCulture("dd/MM/yyyy HH:mm:ss");
LocalDateTime ldt = pattern.Parse(localDateTime).Value;
ZonedDateTime zdt = ldt.InZoneLeniently(DateTimeZoneProviders.Tzdb[timeZone]);
Instant instant = zdt.ToInstant();
ZonedDateTime utc = instant.InUtc();
string output = utc.ToString("dd/MM/yyyy HH:mm:ss", CultureInfo.InvariantCulture);
return output;
}
static void Main(string[] args)
{
foreach (DateTime d in myDates)
{
DateTime utcTime = Convert.ToDateTime(LocalTimeToUTC("Europe/Amsterdam", d.ToString()));
Console.WriteLine(utcTime);
}
Console.ReadKey();
}
问题出在夏令时:当时钟倒退 1 小时时。少了一个小时,看下面的结果。
25/10/2014 19:00:00
25/10/2014 20:00:00
25/10/2014 21:00:00
25/10/2014 22:00:00
25/10/2014 23:00:00
26/10/2014 01:00:00
26/10/2014 02:00:00
如您所见,由于时钟更改,26/10/2014 00:00:00 丢失了。
我的问题是,有没有一种方法可以处理这个问题,这样就不会错过任何时间?填充缺失的时间?
您错过了一个小时,因为有两个 UTC 时刻都对应于相同的本地时间,因为时钟倒退。避免 "missing hours" 的唯一方法是在不明确的当地时间发出 两个 条目。
让我们看看 table 反过来,从 UTC 到本地时间,每个经过的小时有一个条目:
UTC Local time
2014-10-25 21:00:00Z 2014-10-25 23:00:00 +02
2014-10-25 22:00:00Z 2014-10-26 00:00:00 +02
2014-10-25 23:00:00Z 2014-10-26 01:00:00 +02
2014-10-26 00:00:00Z 2014-10-26 02:00:00 +02
2014-10-26 01:00:00Z 2014-10-26 02:00:00 +01 (clocks back!)
2014-10-26 02:00:00Z 2014-10-26 03:00:00 +01
所以左侧有 6 个不同的值,但右侧只有 5 个不同的值。
您可以使用 DateTimeZone.MapLocal(LocalDateTime)
得到一个 ZoneLocalMapping
,其中将包含 0、1 或 2 个值,具体取决于本地 date/time 是否被跳过(由于向前跳转),明确的,或重复的(由于跳回)。 可能 给你你想要的,但你并不清楚你想要达到什么或你的输入数据代表什么。
我正在使用 Noda Time 将 local datetime 转换为 UTC。
这是我目前拥有的:
static string LocalTimeToUTC(string timeZone, string localDateTime)
{
var pattern = LocalDateTimePattern.CreateWithInvariantCulture("dd/MM/yyyy HH:mm:ss");
LocalDateTime ldt = pattern.Parse(localDateTime).Value;
ZonedDateTime zdt = ldt.InZoneLeniently(DateTimeZoneProviders.Tzdb[timeZone]);
Instant instant = zdt.ToInstant();
ZonedDateTime utc = instant.InUtc();
string output = utc.ToString("dd/MM/yyyy HH:mm:ss", CultureInfo.InvariantCulture);
return output;
}
static void Main(string[] args)
{
foreach (DateTime d in myDates)
{
DateTime utcTime = Convert.ToDateTime(LocalTimeToUTC("Europe/Amsterdam", d.ToString()));
Console.WriteLine(utcTime);
}
Console.ReadKey();
}
问题出在夏令时:当时钟倒退 1 小时时。少了一个小时,看下面的结果。
25/10/2014 19:00:00
25/10/2014 20:00:00
25/10/2014 21:00:00
25/10/2014 22:00:00
25/10/2014 23:00:00
26/10/2014 01:00:00
26/10/2014 02:00:00
如您所见,由于时钟更改,26/10/2014 00:00:00 丢失了。
我的问题是,有没有一种方法可以处理这个问题,这样就不会错过任何时间?填充缺失的时间?
您错过了一个小时,因为有两个 UTC 时刻都对应于相同的本地时间,因为时钟倒退。避免 "missing hours" 的唯一方法是在不明确的当地时间发出 两个 条目。
让我们看看 table 反过来,从 UTC 到本地时间,每个经过的小时有一个条目:
UTC Local time
2014-10-25 21:00:00Z 2014-10-25 23:00:00 +02
2014-10-25 22:00:00Z 2014-10-26 00:00:00 +02
2014-10-25 23:00:00Z 2014-10-26 01:00:00 +02
2014-10-26 00:00:00Z 2014-10-26 02:00:00 +02
2014-10-26 01:00:00Z 2014-10-26 02:00:00 +01 (clocks back!)
2014-10-26 02:00:00Z 2014-10-26 03:00:00 +01
所以左侧有 6 个不同的值,但右侧只有 5 个不同的值。
您可以使用 DateTimeZone.MapLocal(LocalDateTime)
得到一个 ZoneLocalMapping
,其中将包含 0、1 或 2 个值,具体取决于本地 date/time 是否被跳过(由于向前跳转),明确的,或重复的(由于跳回)。 可能 给你你想要的,但你并不清楚你想要达到什么或你的输入数据代表什么。