繁体   English   中英

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

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

我的输入是开始日期和结束日期。 我想检查一下它是在12月1日到3月31日之间。(年份可以更改,并且只有此日期或该日期以外的日期)。

到目前为止,Joda-time还没有找到任何解决方案。 有人可以给我一个起点怎么做(不是代码,只是逻辑)? 我尚未检查代码,但是非常丑陋,我想找到一种算法解决方案

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及其Interval类(带有overlap方法)。 很容易。

时区

与java.util.Date不同,DateTime真正知道其分配的时区。 通常,指定比依赖默认值更好。 请注意,如果要跟踪日期和时间(DateTime而不是LocalDate),则时区至关重要。 开始和结束的“天”的定义取决于时区。 跨时区工作的企业可以选择为此使用UTC。

时间跨度

仅供参考,除了Interval,Joda-Time还提供了Period和Duration类,用于处理一段时间。

一天的开始

当使用日期时间值但专注于“天”时,则将时间部分调整为该特定时区的一天的第一时刻。 在Joda-Time中,只需调用withTimeAtStartOfDay方法。

避免与“午夜”相关的类和方法。 Joda-Time团队不再推荐它们。

半开

比较时间跨度时,Joda-Time使用“半开放”方法。 开头(包括),结尾(包括)。 这意味着,由于您希望从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的间隔。 如果您仔细考虑一下,然后在StackOverflow上搜索“ joda interval”上的其他帖子,您就会发现这种方法的智慧。

比较方式

Interval类提供了方便的比较方法: containsabutsoverlapgap 请务必阅读文档以了解确切的详细信息。

java.time

Java 8带来了受JSR 310定义的,受Joda-Time启发的新java.time软件包。Joda-Time继续在Java 8中工作,但是如果您不熟悉Java,则可能要学习java.time而不是Joda-Time。日期时间工作。

范例程式码

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

转储到控制台...

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

运行时...

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

使用获取的开始日期和结束日期创建间隔。

创建从三月到十二月的间隔。

如果满足以下任一条件,则您的条件为true:

  • 3月到12月的间隔完全包含输入间隔,
  • 或两个间隔之间没有重叠。

在代码中将是:

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

Interval Javadàoc

由于您提到日期将是该期间内的两个日期,或者都将是两个期间,因此您只需要测试其中一个即可。

因此,只需测试beginDate.getMonthOfYear()是否返回beginDate.getMonthOfYear()或3。

暂无
暂无

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

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