获得夏令时开始和结束在NodaTime [英] Getting Daylight Savings Time Start and End in NodaTime

查看:198
本文介绍了获得夏令时开始和结束在NodaTime的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如何使用Noda Time获取夏令时间的开始和结束日期?
下面的函数完成了这个任务,但是它是非常难以操作的,并且正在乞求一个更简单的解决方案。

How can I get the starting and ending dates for Daylight Savings Time using Noda Time? The function below accomplishes this task but it is horribly unwieldy and is begging for a simpler solution.

/// <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);
}


推荐答案

在我知道的功能,但数据都在那里,所以你一定可以创建自己的。

There's not a single built-in function that I am aware of, but the data is all there, so you can certainly create your own.

你在正确的轨道上,你有显示,但有一些事情要考虑:

You're on the right track with what you've shown, but there are a few things to consider:


  • 通常人们对结束感兴趣点间隔。通过返回只有中间间隔的开始和停止,您可能会获得与预期不同的值。例如,如果您使用美国时区之一,例如America / Los_Angeles,则您的函数将转换为 3/9 / 2014 3:00:00 AM 11/2/2014 2:00:00 AM ,您可能希望在凌晨2点

  • Normally people are interested in the end points of the intervals. By returning the start and stop of only the middle interval, you are likely getting values different than you expect. For example, if you use one of the US time zones, such as "America/Los_Angeles", your function returns the transitions as 3/9/2014 3:00:00 AM and 11/2/2014 2:00:00 AM, where you are probably expecting 2:00 AM for both.

使用DST的赤道以南的时区将在年底前开始,并在明年初结束。所以有时候,元组中的项目可能会从你期望的那样被扭转。

Time zones south of the equator that use DST will start it towards the end of the year, and end it towards the beginning of the next year. So sometimes the items in the tuple might be reversed from what you expect them to be.

有很多时区不使用日光节省时间,所以抛出异常并不是最好的想法。

There are quite a lot of time zones that don't use daylight saving time, so throwing an exception isn't the best idea.

至少有两个时区在一年内目前有四个转换(< a href =http://www.timeanddate.com/time/change/morocco/casablanca?year=2014> 非洲/卡萨布兰卡 非洲/开罗 ) - 在斋月的DST期间有休息。而且偶尔还有非DST相关的转换,例如萨摩亚在2011年更改其标准偏差,它在一年内给出了三个转换。

There are at least two time zones that presently have four transitions in a single year ("Africa/Casablanca" and "Africa/Cairo") - having a "break" in their DST periods for Ramadan. And occasionally, there are non-DST-related transitions, such as when Samoa changed its standard offset in 2011, which gave it three transitions in a single year.

考虑到这一点,返回单个转换点的列表似乎更好,而不是一组元素的转换。

Taking all of this into account, it would seem better to return a list of single transition points, rather than a tuple of pairs of transitions.

此外,这是次要的,但它会更好的形式是不要将方法绑定到系统时钟。年可以很容易地通过参数传递。然后,如果需要,您可以使用非当前年份的这种方法。

Also, this is minor, but it would be better form to not bind the method to the system clock at all. The year can easily be passed by parameter. Then you can use this method for non-current years if necessary.

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);
}

最后还要注意,只需要过滤掉因为这个时间间隔可能很好地延续到下一年,或者无限期地进行。

Also note at the end, it's important to filter just the values that are in the current year because the intervals may very well extend into the following year, or go on indefinitely.

这篇关于获得夏令时开始和结束在NodaTime的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆