简体   繁体   English

如何检查两个日期是否在一个周期(间隔)之间?

[英]How can I check that a two dates are between a period(interval)?

My input is a beginning date and an end date. 我的输入是开始日期和结束日期。 And I want to check that it is between December 1 and March 31. (The year can change, and there will be only dates in, or dates outside this period). 我想检查一下它是在12月1日到3月31日之间。(年份可以更改,并且只有此日期或该日期以外的日期)。

So far I didn't found any solution with Joda-time. 到目前为止,Joda-time还没有找到任何解决方案。 Can somebody give me a starting point how to do(not code, just the logic)? 有人可以给我一个起点怎么做(不是代码,只是逻辑)? I didn't checked the code yet, but it is VERY Ugly, and I want to find an algorithmic solution 我尚未检查代码,但是非常丑陋,我想找到一种算法解决方案

public static boolean isInWinter(Contract contract) {
    logger.info("begin isInWinter:");
    DateTime beginDate = contract.getBeginningDate();
    DateTime endDate = contract.getEndDate();
    /*
     * If the year is different (etc 2012 dec,2013 marc) check that the
     * beginning month is december, and the end month is jan,feb,marc
     */
    if (endDate.getYear() - beginDate.getYear() == 1) {
        if ((beginDate.getMonthOfYear() == 12)
                && ((endDate.getMonthOfYear() == 1
                        || endDate.getMonthOfYear() == 2 || endDate
                        .getMonthOfYear() == 3))) {
            logger.info("return true different year");
            return true;
        }
        /*
         * Same year can be if begin and end date is december or begin and
         * and date is jan,febr,marc TODO REMOVE Auto formatter
         */
    } else if (endDate.getYear() - beginDate.getYear() == 0) {
        if ((beginDate.getMonthOfYear() == 12 && endDate.getMonthOfYear() == 12)
                || ((beginDate.getMonthOfYear() == 1
                        || beginDate.getMonthOfYear() == 2 || beginDate
                        .getMonthOfYear() == 3) && (endDate
                        .getMonthOfYear() == 1
                        || endDate.getMonthOfYear() == 2 || endDate
                        .getMonthOfYear() == 3))) {
            logger.info("return true same year");
            return true;
        }

    }
    logger.info("return false");
    return false;
}

Joda-Time 乔达时代

Joda-Time and its Interval class with the overlap method is just what you need. 您需要的是Joda-Time及其Interval类(带有overlap方法)。 Very easy. 很容易。

Time Zone 时区

Unlike java.util.Date, a DateTime truly knows its assigned time zone. 与java.util.Date不同,DateTime真正知道其分配的时区。 Generally better to specify than rely on default. 通常,指定比依赖默认值更好。 Note that if you are tracking date+time (a DateTime rather than a LocalDate), then time zone is critical. 请注意,如果要跟踪日期和时间(DateTime而不是LocalDate),则时区至关重要。 The definition of a "day" beginning and ending depends on time zone. 开始和结束的“天”的定义取决于时区。 Businesses that work across time zones may choose to use UTC for this purpose. 跨时区工作的企业可以选择为此使用UTC。

Span of Time 时间跨度

FYI, besides Interval, Joda-Time also offers the Period and Duration classes for working with a span of time. 仅供参考,除了Interval,Joda-Time还提供了Period和Duration类,用于处理一段时间。

Start of Day 一天的开始

When working with date-time values but focusing on a "day", then adjust the time portion to the first moment of the day for that particular time zone. 当使用日期时间值但专注于“天”时,则将时间部分调整为该特定时区的一天的第一时刻。 In Joda-Time, simply call the withTimeAtStartOfDay method. 在Joda-Time中,只需调用withTimeAtStartOfDay方法。

Avoid the "midnight"-related classes and methods. 避免与“午夜”相关的类和方法。 They are no longer recommended by the Joda-Time team. Joda-Time团队不再推荐它们。

Half-Open 半开

Joda-Time uses the "Half-Open" approach when comparing spans of time. 比较时间跨度时,Joda-Time使用“半开放”方法。 The beginning in inclusive and the ending is exclusive. 开头(包括),结尾(包括)。 That means since you want from December 1 to March 31 that we define an Interval of the first moment of the day of December 1 to the first moment of the day of April 1 . 这意味着,由于您希望从12月1日到3月31日,我们定义12月1日这the first moment of the day of December 1 the first moment of the day of April 1 the first moment of the day of December 1的间隔。 If you ponder this, and search StackOverflow for other postings on "joda interval", you'll come to see the wisdom of this approach. 如果您仔细考虑一下,然后在StackOverflow上搜索“ joda interval”上的其他帖子,您就会发现这种方法的智慧。

Comparison 比较方式

The Interval class offers handy comparison methods: contains , abuts , overlap , and gap . Interval类提供了方便的比较方法: containsabutsoverlapgap Be sure to read the doc to understand exact details. 请务必阅读文档以了解确切的详细信息。

java.time java.time

Java 8 brings the new java.time package, inspired by Joda-Time, defined by JSR 310. Joda-Time continues to work in Java 8, but you may want to learn java.time rather than Joda-Time if you are new to date-time work. Java 8带来了受JSR 310定义的,受Joda-Time启发的新java.time软件包。Joda-Time继续在Java 8中工作,但是如果您不熟悉Java,则可能要学习java.time而不是Joda-Time。日期时间工作。

Example Code 范例程式码

DateTimeZone timeZone = DateTimeZone.forID( "Europe/Budapest" ); // Or, perhaps DateTimeZone.UTC

// Inputs
DateTime contractStart = new DateTime( 2014, 1, 2, 0, 0, 0, timeZone );
DateTime contractStop = new DateTime( 2014, 5, 6, 0, 0, 0, timeZone );
Interval contractInterval = new Interval( contractStart, contractStop );

// Target to test
DateTime targetStart = new DateTime( 2013, DateTimeConstants.DECEMBER, 1, 0, 0, 0, timeZone );
DateTime targetStop = targetStart.plusMonths( 4 );
Interval targetInterval = new Interval( targetStart, targetStop );

boolean targetContainsContract = targetInterval.contains( contractInterval );
boolean targetOverlapsContract = ( targetInterval.overlap( contractInterval ) != null );

Dump to console… 转储到控制台...

System.out.println( "contractInterval: " + contractInterval );
System.out.println( "targetInterval: " + targetInterval );
System.out.println( "targetContainsContract: " + targetContainsContract );
System.out.println( "targetOverlapsContract: " + targetOverlapsContract );

When run… 运行时...

contractInterval: 2014-01-02T00:00:00.000+01:00/2014-05-06T00:00:00.000+02:00
targetInterval: 2013-12-01T00:00:00.000+01:00/2014-04-01T00:00:00.000+02:00
targetContainsContract: false
targetOverlapsContract: true

Create an interval with the beginning and end date you get as inputs. 使用获取的开始日期和结束日期创建间隔。

Create an interval going from March to December. 创建从三月到十二月的间隔。

Your condition is true if either: 如果满足以下任一条件,则您的条件为true:

  • the march to december interval entirely contains the input interval, 3月到12月的间隔完全包含输入间隔,
  • or there is no overlap between the two intervals. 或两个间隔之间没有重叠。

In code that would be: 在代码中将是:

marchToDecember.contains(interval) || marchToDecember.overlap(interval) == null

Javadàoc for Interval Interval Javadàoc

Since you mention that the dates will be either both in or both out the period, you'll only need to test one of them. 由于您提到日期将是该期间内的两个日期,或者都将是两个期间,因此您只需要测试其中一个即可。

So just test whether beginDate.getMonthOfYear() returns either 12, 1, 2 or 3. 因此,只需测试beginDate.getMonthOfYear()是否返回beginDate.getMonthOfYear()或3。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM