上下文
我们有一个处理时间的C#程序。
我们在法国有客户,因此我们将时间与法国时区之间进行转换。
在C#代码中:我们使用Central European Standard Time
作为法国的时区。
它描述了一个时区,它遵循DST更改:
我们的情况
问题是:法国于1996年与CEST保持一致;
在该日期之前,法国将在9月的最后一个星期日从夏季更改为冬季。
Window的CEST
时区(准确地)描述了CEST,在1995年10月之前的日期恰好不等于法国的时区。
当测试IANA database(在Windows子系统中,用于Linux)时,事实证明欧洲/巴黎时区在9月底准确切换了<1995年的日期。
问题
有没有:
Europe/Paris
时区的表示形式?我们用于将时间转换为UTC的示例代码:
using System;
using System.Globalization;
namespace TestingApp
{
class Program
{
static void Main(string[] args)
{
var tz = TimeZoneInfo.FindSystemTimeZoneById("Central European Standard Time");
string[] times = {
// In 1995 :
// last sunday in september was sept. 24th
// last sunday in october was oct. 29th
"1995/09/23 12:00:00", "1995/09/24 12:00:00",
"1995/10/28 12:00:00", "1995/10/29 12:00:00",
};
foreach (var t in times) {
var utc = DateTime.ParseExact(t, "yyyy/MM/dd HH:mm:ss", CultureInfo.InvariantCulture, DateTimeStyles.None);
utc = TimeZoneInfo.ConvertTime(utc, tz, TimeZoneInfo.Utc);
Console.WriteLine(String.Format("Paris: {0} -> UTC: {1}", t, utc.ToString()));
}
}
}
}
// Output :
// Paris: 1995/09/23 12:00:00 -> UTC: 23/09/1995 10:00:00
// Paris: 1995/09/24 12:00:00 -> UTC: 24/09/1995 10:00:00 <- instead of 11:00:00 UTC
// Paris: 1995/10/28 12:00:00 -> UTC: 28/10/1995 10:00:00 <- instead of 11:00:00 UTC
// Paris: 1995/10/29 12:00:00 -> UTC: 29/10/1995 11:00:00
答案 0 :(得分:5)
是否可以使用C#使用IANA数据库(和欧洲/巴黎)?
是的-使用Noda Time项目-我是主要贡献者,因此对我有偏见,但是使用该项目的主要原因之一是支持IANA(又名TZDB)时区。
>这里有一些示例代码可以与您问题中的代码匹配:
using NodaTime;
using System;
using System.Linq;
namespace TestingApp
{
class Program
{
static void Main(string[] args)
{
var tz = DateTimeZoneProviders.Tzdb["Europe/Paris"];
var localDates = new[]
{
new LocalDate(1995, 9, 23),
new LocalDate(1995, 9, 24),
new LocalDate(1995, 10, 28),
new LocalDate(1995, 10, 29)
};
var midday = new LocalTime(12, 0, 0);
var localDateTimes = localDates.Select(date => date.At(midday));
foreach (var localDateTime in localDateTimes)
{
var utc = localDateTime.InZoneStrictly(tz).WithZone(DateTimeZone.Utc);
Console.WriteLine($"Paris: {localDateTime:yyyy/MM/dd HH:mm:ss} -> UTC: {utc:yyyy/MM/dd HH:mm:ss}");
}
}
}
}
答案 1 :(得分:1)
请参阅@JonSkeet解决方案。它比这简单得多。我不会删除更复杂的答案,因为这种解释对于某人了解标准的.NET TimeZone
会发生什么很有用。
这有点复杂,但是可能。
.NET框架使用TimeZoneInfo
定义时间更改规则。此类具有嵌套的TimeZoneInfo.AdjustmentRule
,该嵌套的目的是定义小时的变化时间。
我住在西班牙(欧洲),所以我的Windows已安装欧洲时区信息。您可以使用方法TimeZoneInfo.GetSystemTimeZones()
获取系统的所有时区信息。
唯一提到法国的是:
{(UTC+01:00) Bruselas, Copenhague, Madrid, París}
如果您进行检查,只会发现一个TimeZoneInfo.AdjustmentRule
来定义当前的小时更改,而不是您需要使用的旧的更改:
+ DateStart {01/01/0001 0:00:00} System.DateTime
+ DateEnd {31/12/9999 0:00:00} System.DateTime
+ DaylightDelta {01:00:00} System.TimeSpan
- DaylightTransitionStart {System.TimeZoneInfo.TransitionTime} System.TimeZoneInfo.TransitionTime
Day 1 int
DayOfWeek Sunday System.DayOfWeek
IsFixedDateRule false bool
Month 3 int
+ TimeOfDay {01/01/0001 2:00:00} System.DateTime
Week 5 int
- DaylightTransitionEnd {System.TimeZoneInfo.TransitionTime} System.TimeZoneInfo.TransitionTime
Day 1 int
DayOfWeek Sunday System.DayOfWeek
IsFixedDateRule false bool
Month 10 int
+ TimeOfDay {01/01/0001 3:00:00} System.DateTime
Week 5 int
因此,至少在西班牙语Windows(我怀疑在所有欧洲Windows)上,法国对小时更改的旧规则没有定义。
我认为唯一的解决方案是创建自己的自定义时区并在应用程序TimeZoneInfo.CreateCustomTimeZone Method中使用它
创建此自定义时区信息时,可以包括旧的调整规则:
-为旧规则和新规则指定有效的DateStart,DateEnd
-为每个属性指定其余属性:DaylightDelta, DaylightTransitionEnd, Day, DayOfweek...
,依此类推,以此类推。
我不知道是否可以在任何地方找到此规则,但是创建自定义规则可以解决您的问题。