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

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

问题描述

我怎样才能用野田佳彦时间为夏令时的开始和结束日期?低于
功能完成这个任务,但它是可怕的笨拙,乞求一个简单的解决方案。

  /// <总结> 
///获取给定的时区
的开始和夏令时结束///< /总结>
///< PARAM NAME =TZ>在问题<时区; /参数>
///<返回>一种元组表示DST<的开始和结束; /回报>
///<&言论GT;假设该区域具有夏令时和LT; /言论>
私人元组LT; LocalDateTime,LocalDateTime> GetZoneStartAndEnd(DateTimeZone TZ)
{
INT thisYear = TimeUtils.SystemLocalDateTime.Year; //获取当前LocalDateTime

的一年//获取1月1日午夜,在今年和明年。
变种yearStart =新LocalDateTime(thisYear,1,1,0,0).InZoneLeniently(TZ).ToInstant();
变种年终=新LocalDateTime(thisYear + 1,1,1,0,0).InZoneLeniently(TZ).ToInstant();

//获得我们在今年
变种的时间间隔= tz.GetZoneIntervals(yearStart,年末).ToArray()体验的时间间隔;

//假设我们是在一个美国式日光节约计划,
//我们应该看到三个区间:
// 1. 1月1日在位于$间隔b $ b // 2。在某些时候,夏令时开始。
// 3。在某些时候,夏令时将停止。
如果(intervals.Length == 1)
抛出新的异常(该时区不使用夏令时);
如果(intervals.Length = 3!)
抛出新的异常(该时区中的夏令方案是意想不到的。);

返回新的记录< LocalDateTime,LocalDateTime>(间隔[1] .IsoLocalStart,间隔时间[1] .IsoLocalEnd);
}


解决方案

有不是一个单一的内置在我所知道的,但数据都在那里,所以你当然可以创建自己的功能。



您是在正确的轨道上你已经上了什么示,但也有考虑一些事情:




  • 通常人们有兴趣在结束的间隔的点。通过返回只有中间间隔的启动和停止,你很可能得到不同的值比预期的。例如,如果您使用美国时区,如美国/洛杉矶之一,您函数返回转换为 2014年11月2日上午02时零零分00秒,您很可能希望2:00 AM为两者。


  • 时区南部使用DST将启动其争取在今年年底,并结束其对明年年初的赤道。所以有时在元组中的项目可能会从你期望他们有什么要发生逆转。


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


  • 有至少两个时区是目前在一个单一的一年四个转变(< A HREF =http://www.timeanddate.com/time/change/morocco/casablanca?year=2014相对=nofollow> 非洲/卡萨布兰卡 非洲/开罗 ) - 具有斋月他们DST周期的破发。偶尔,还有非DST相关的转换,比如当萨摩亚改变了它的标准在2011年偏移量,这给它的在一个单一的一年三的转变。




考虑到所有的这种考虑,它似乎更好返回单个过渡点的列表,而不是对转换的元组



此外,这是未成年人,但它会更好的形式的方法与系统时钟不绑定的。年份可以容易地通过参数传递。然后你可以使用非流动资产年,如果需要这个方法

 公开的IEnumerable< LocalDateTime> GetDaylightSavingTransitions(DateTimeZone的时区,年整型)
{
变种yearStart =新LocalDateTime(年,1,1,0,0).InZoneLeniently(的timeZone).ToInstant();
变种年终=新LocalDateTime(年+ 1,1,1,0,0).InZoneLeniently(的timeZone).ToInstant();
变种的时间间隔= timeZone.GetZoneIntervals(yearStart,年底);

返回intervals.Select(X => x.IsoLocalEnd)。凡(X => x.Year ==年);
}



在最后还要注意,它过滤只是在价值观是非常重要的当年,因为区间很可能延长到下一年,或无限期地继续下去。


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:

  • 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.

  • 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.

  • 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天全站免登陆