Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/date/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 在NodaTime中开始和结束夏令时_C#_Date_Dst_Nodatime - Fatal编程技术网

C# 在NodaTime中开始和结束夏令时

C# 在NodaTime中开始和结束夏令时,c#,date,dst,nodatime,C#,Date,Dst,Nodatime,如何使用野田时间获取夏令时的开始和结束日期? 下面的函数完成了这个任务,但它非常笨拙,需要一个更简单的解决方案 /// <summary> /// Gets the start and end of daylight savings time in a given time zone /// </summary> /// <param name="tz">The time zone in question</param> /// <retur

如何使用野田时间获取夏令时的开始和结束日期? 下面的函数完成了这个任务,但它非常笨拙,需要一个更简单的解决方案

/// <summary>
/// Gets the start and end of daylight savings time in a given time zone
/// </summary>
/// <param name="tz">The time zone in question</param>
/// <returns>A tuple indicating the start and end of DST</returns>
/// <remarks>Assumes this zone has daylight savings time</remarks>
private Tuple<LocalDateTime, LocalDateTime> GetZoneStartAndEnd(DateTimeZone tz)
{
    int thisYear = TimeUtils.SystemLocalDateTime.Year; // Get the year of the current LocalDateTime

    // Get January 1, midnight, of this year and next year.
    var yearStart = new LocalDateTime(thisYear, 1, 1, 0, 0).InZoneLeniently(tz).ToInstant();
    var yearEnd = new LocalDateTime(thisYear + 1, 1, 1, 0, 0).InZoneLeniently(tz).ToInstant();

    // Get the intervals that we experience in this year
    var intervals = tz.GetZoneIntervals(yearStart, yearEnd).ToArray();

    // Assuming we are in a US-like daylight savings scheme,
    // we should see three intervals:
    // 1. The interval that January 1st sits in
    // 2. At some point, daylight savings will start.
    // 3. At some point, daylight savings will stop.
    if (intervals.Length == 1)
        throw new Exception("This time zone does not use daylight savings time");
    if (intervals.Length != 3)
        throw new Exception("The daylight savings scheme in this time zone is unexpected.");

    return new Tuple<LocalDateTime,LocalDateTime>(intervals[1].IsoLocalStart, intervals[1].IsoLocalEnd);
}
//
///获取给定时区中夏令时的开始和结束时间
/// 
///讨论中的时区
///指示DST开始和结束的元组
///假定此分区具有夏令时
私有元组GetZoneStartAndEnd(DateTimeZone tz)
{
int thiswear=TimeUtils.SystemLocalDateTime.Year;//获取当前LocalDateTime的年份
//今年和明年的1月1日午夜。
var yearStart=newlocaldatetime(今年,1,1,0,0).inzonelinely(tz).ToInstant();
var yearEnd=新的LocalDateTime(thisYear+1,1,0,0);
//获取我们今年经历的时间间隔
var interval=tz.GetZoneIntervals(yearStart,yearEnd).ToArray();
//假设我们在一个类似美国的夏令时计划中,
//我们应该看到三个间隔:
//1.1月1日所在的时间间隔
//2.在某个时候,夏令时将开始。
//在某个时候,夏令时将停止。
if(interval.Length==1)
抛出新异常(“此时区不使用夏令时”);
如果(间隔长度!=3)
抛出新的异常(“此时区的夏令时计划是意外的。”);
返回新元组(间隔[1]。IsoLocalStart,间隔[1]。ISOLOCALAND);
}

据我所知,没有一个内置函数,但数据都在那里,因此您当然可以创建自己的函数

您所展示的内容是正确的,但有几件事需要考虑:

  • 通常人们对间隔的终点感兴趣。通过仅返回中间间隔的开始和停止,您可能会得到与预期不同的值。例如,如果您使用一个美国时区,例如
    “America/Los_Angeles”
    ,则函数将转换返回为
    3/9/2014 3:00:00 AM
    11/2/2014 2:00:00 AM
    ,您可能希望这两个时区都是凌晨2:00

  • 赤道以南使用DST的时区将在年底开始,在明年初结束。因此,有时元组中的项可能与您期望的相反

  • 有相当多的时区不使用夏令时,所以抛出异常不是最好的主意

  • 目前,至少有两个时区在一年内(和)有四次转换——在斋月的DST期间有一次“休息”。偶尔也会有一些与DST无关的转换,比如when,它在一年内完成了三次转换

考虑到所有这些因素,返回单个转换点的列表似乎比返回成对转换的元组更好

此外,这是次要的,但最好不要将方法绑定到系统时钟。可以通过参数轻松地传递年份。如果有必要,您可以在非当前年份使用此方法

public IEnumerable<LocalDateTime> GetDaylightSavingTransitions(DateTimeZone timeZone, int year)
{
    var yearStart = new LocalDateTime(year, 1, 1, 0, 0).InZoneLeniently(timeZone).ToInstant();
    var yearEnd = new LocalDateTime(year + 1, 1, 1, 0, 0).InZoneLeniently(timeZone).ToInstant();
    var intervals = timeZone.GetZoneIntervals(yearStart, yearEnd);

    return intervals.Select(x => x.IsoLocalEnd).Where(x => x.Year == year);
}
public IEnumerable GetDaylightSavingTransitions(日期时区时区,整数年)
{
var yearStart=newlocaldatetime(year,1,1,0,0).inzonelinely(timeZone).ToInstant();
var yearEnd=newlocaldatetime(year+1,1,0,0);
var间隔=时区。GetZoneIntervals(年开始,年结束);
返回间隔。选择(x=>x.IsoLocalEnd)。其中(x=>x.Year==Year);
}

最后还要注意,只过滤当前年份中的值很重要,因为间隔很可能延伸到下一年,或者无限期地延续下去。

此代码片段还可以帮助您检查时间是否在daylightsavingstime

public static bool IsDaylightSavingsTime(this DateTimeOffset dateTimeOffset)
        {
            var timezone = "Europe/London"; //https://nodatime.org/TimeZones
            ZonedDateTime timeInZone = dateTimeOffset.DateTime.InZone(timezone);
            var instant = timeInZone.ToInstant();
            var zoneInterval = timeInZone.Zone.GetZoneInterval(instant);
            return zoneInterval.Savings != Offset.Zero;
        }
如何使用它

var testDate = DateTimeOffset.Now;
var isDst = testDate.IsDaylightSavingsTime();

根据您的情况,您可以稍微修改它

这是简单的bool-IsDaylightSavings(DateTimeZone-timeZone,Instant-Instant)方法的正确基础,还是有更好的方法?您的方法做什么?野田佳彦的文档不容易理解。我不知道什么是
IsoLocalEnd
,也不知道如何使用它来获取DST过渡时间。@方位角-根据文档,一个
ZoneInterval
“表示一个特定偏移应用的时间范围”及其属性返回间隔的本地开始时间,如ISO日历中的
LocalDateTime
。这不包括任何夏令时。这是半开放的时间间隔,因此这为我们提供了转换发生的本地时间。例如,在美国,我们刚刚进行了后退转换,我们通常说“在本地时间2:00,回到本地时间1:00”。实际上,这是“当时钟接近2:00时”“。如果你实际上是在2:00,那么转换已经发生在一个小时之前。但当我们要求过渡时,这仍然是我们感兴趣的2:00时间。因此,我们需要区域间隔的
IsoLocalEnd
值。不幸的是,他们的文档远非易懂。。。