我应该在法国使用哪个时区来支持新旧夏令时调整?

LeG*_*GEC 4 c# windows timezone datetime

语境

我们有一个处理时间的C#程序。

我们在法国有客户,因此我们将时间与法国时区之间进行转换。

在我们的C#代码中:我们将其Central European Standard Time用作法国的时区。

它描述了一个时区,该时区遵循DST更改:

  • 在3月的最后一个星期日(凌晨3点),时钟旋转到夏令时向前移动1小时
  • 在10月的最后一个星期日(凌晨3点),时钟切换为冬季时间,并向后移动1小时

我们的情况

问题是:法国在1996年与CEST保持一致;
在此日期之前,法国将在9月的最后一个星期日从夏季更改为冬季。

Window的CEST时区(准确地)描述了CEST,在1995年10月之前的日期恰好不等于法国的时区。

当测试IANA数据库(在Windows子系统中为Linux)时,事实证明欧洲/巴黎时区在9月底准确地切换了<1995年的日期。

题

有没有:

  • Europe/Paris在Window的标准时区列表中表示时区?
  • 一种从C#使用IANA数据库(和欧洲/巴黎)的方法?

我们用于将时间转换为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    
Run Code Online (Sandbox Code Playgroud)

Jon*_*eet 7

有没有办法使用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}");
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)