如何获取英国时区夏令时起止时间?是否有C#方法或可用库?
在C#中获取任意时区的夏令时起止时间
你完全不需要硬编码夏令时规则,C#内置API和成熟的第三方库都能帮你适配任意时区的夏令时计算,无需针对不同时区重写逻辑。
一、使用C#内置的TimeZoneInfo类
TimeZoneInfo是.NET原生提供的时区处理类,通过它的GetAdjustmentRules()方法可以获取目标时区的夏令时调整规则,进而计算出指定年份的夏令时起止时间。
核心代码实现
using System; using System.Linq; public static class TimeZoneHelper { public static (DateTime DstStartLocal, DateTime DstEndLocal) GetDstRangeForYear(string timeZoneId, int year) { var timeZone = TimeZoneInfo.FindSystemTimeZoneById(timeZoneId); var adjustmentRules = timeZone.GetAdjustmentRules(); // 定位当前年份适用的调整规则 var targetRule = adjustmentRules.FirstOrDefault(rule => year >= rule.DateStart.Year && year <= rule.DateEnd.Year); if (targetRule == null) throw new InvalidOperationException($"No daylight saving rule found for year {year} in time zone {timeZoneId}"); // 计算夏令时开始的本地时间 var dstStart = CalculateTransitionLocalTime(targetRule.DaylightTransitionStart, year, timeZone); // 计算夏令时结束的本地时间 var dstEnd = CalculateTransitionLocalTime(targetRule.DaylightTransitionEnd, year, timeZone); return (dstStart, dstEnd); } private static DateTime CalculateTransitionLocalTime(TimeZoneInfo.TransitionTime transition, int year, TimeZoneInfo timeZone) { // 获取目标月份的最后一天 var lastDayOfMonth = new DateTime(year, transition.Month, DateTime.DaysInMonth(year, transition.Month)); // 倒推找到当月最后一个指定星期几的日期 int daysToSubtract = (lastDayOfMonth.DayOfWeek - transition.DayOfWeek + 7) % 7; var transitionDate = lastDayOfMonth.AddDays(-daysToSubtract); // 拼接切换时间点 var transitionDateTime = transitionDate.Add(transition.TimeOfDay); // 转换为目标时区的本地时间(处理偏移量) return TimeZoneInfo.ConvertTime(transitionDateTime, TimeZoneInfo.Local, timeZone); } }
调用示例
// 获取英国时区(Windows时区ID:GMT Standard Time;Linux/macOS时区ID:Europe/London)2024年夏令时 var (ukDstStart, ukDstEnd) = TimeZoneHelper.GetDstRangeForYear("GMT Standard Time", 2024); Console.WriteLine($"英国夏令时开始:{ukDstStart:yyyy-MM-dd HH:mm:ss}"); Console.WriteLine($"英国夏令时结束:{ukDstEnd:yyyy-MM-dd HH:mm:ss}"); // 切换到美国东部时区(Windows:Eastern Standard Time;Linux/macOS:America/New_York) var (usDstStart, usDstEnd) = TimeZoneHelper.GetDstRangeForYear("Eastern Standard Time", 2024);
注意:Windows和类Unix系统的时区ID不统一,如果需要跨平台兼容,推荐使用下文的第三方库。
二、使用第三方库Noda Time
Noda Time是专门处理日期时间的.NET库,原生支持IANA时区(全球统一标准),处理夏令时更直观、不易出错。
核心代码实现
using NodaTime; public static class NodaTimeHelper { public static (DateTime DstStartUtc, DateTime DstEndUtc) GetDstRangeForYear(string ianaTimeZoneId, int year) { var timeZone = DateTimeZoneProviders.Tzdb[ianaTimeZoneId]; var yearStart = new LocalDate(year, 1, 1).AtMidnight().InZone(timeZone).ToInstant(); var yearEnd = new LocalDate(year + 1, 1, 1).AtMidnight().InZone(timeZone).ToInstant(); // 获取当年所有时区区间,筛选出夏令时区间(偏移量不为0) var dstInterval = timeZone.GetZoneIntervals(yearStart, yearEnd) .FirstOrDefault(interval => interval.Savings != Offset.Zero); if (dstInterval == null) throw new InvalidOperationException($"No daylight saving time observed in {ianaTimeZoneId} for year {year}"); // 转换为UTC时间的DateTime对象 return ( dstInterval.Start.ToDateTimeUtc(), dstInterval.End.ToDateTimeUtc() ); } }
调用示例
// 用IANA时区ID获取英国夏令时 var (ukDstStart, ukDstEnd) = NodaTimeHelper.GetDstRangeForYear("Europe/London", 2024); // 转换为本地时间 var ukDstStartLocal = TimeZoneInfo.ConvertTimeFromUtc(ukDstStart, TimeZoneInfo.FindSystemTimeZoneById("Europe/London"));
关键优势
- 无需硬编码任何夏令时规则,只需传入目标时区ID即可适配全球任意时区
- 自动处理时区规则的更新(比如部分国家调整夏令时政策),内置API和Noda Time都会随系统/库更新同步规则
内容的提问来源于stack exchange,提问作者Vivek Nuna
相关产品推荐
相关产品推荐

