在java中,如何检测日期是在本周还是下周?

在java中,如何检测日期是在本周还是下周?,java,date,Java,Date,如果我有一个事件的日期,比如2011-01-03,如何在java中检测它是在本周还是下周?有样本代码吗 编辑: 我以为这是一个简单的问题,结果比我想象的要复杂得多,我本周要做的是:从过去的这个太阳到本周六,下周是从下个太阳到之后的周六。这部分取决于你所说的“本周”和“下周”是什么意思。。。但是,我们当然可以很容易地确定它是在“今天还是未来7天”中: LocalDate event = getDateFromSomewhere(); LocalDate today = new LocalDate(

如果我有一个事件的日期,比如2011-01-03,如何在java中检测它是在本周还是下周?有样本代码吗

编辑:


我以为这是一个简单的问题,结果比我想象的要复杂得多,我本周要做的是:从过去的这个太阳到本周六,下周是从下个太阳到之后的周六。

这部分取决于你所说的“本周”和“下周”是什么意思。。。但是,我们当然可以很容易地确定它是在“今天还是未来7天”中:

LocalDate event = getDateFromSomewhere();
LocalDate today = new LocalDate();
LocalDate weekToday = today.plusWeeks(1);
LocalDate fortnightToday = weekToday.plusWeeks(1);

if (today.compareTo(event) <= 0 && event.compareTo(weekToday) < 0)
{
    // It's within the next 7 days
}
else if (weekToday.compareTo(event) <= 0 && event.compareTo(fornightToday) < 0)
{
    // It's next week
}

然后执行与上述相同的代码,但与
startOfWeek

相关提示:使用日历。为示例事件日期创建它的新实例。然后,比较当前日期的一年中的一周和事件的日期。

您可以使用日历API检索给定日期的一周

Calendar cal = Calendar.getInstance();
cal.setTime(somedate);
int week = cal.get(Calendar.WEEK_OF_YEAR);
这个怎么样:

Calendar c=Calendar.getInstance();
c.set(Calendar.DAY_OF_WEEK,Calendar.SUNDAY);
c.set(Calendar.HOUR_OF_DAY,0);
c.set(Calendar.MINUTE,0);
c.set(Calendar.SECOND,0);
DateFormat df=new SimpleDateFormat("EEE yyyy/MM/dd HH:mm:ss");
System.out.println(df.format(c.getTime()));      // This past Sunday [ May include today ]
c.add(Calendar.DATE,7);
System.out.println(df.format(c.getTime()));      // Next Sunday
c.add(Calendar.DATE,7);
System.out.println(df.format(c.getTime()));      // Sunday after next
结果是:

Sun 2010/12/26 00:00:00
Sun 2011/01/02 00:00:00
Sun 2011/01/09 00:00:00

前两天之间的任何一天都是本周,后两天之间的任何一天都是下周。

对于那些必须坚持JDK 7并且不能使用joda.time的人,我编写了这个方法并进行了测试

public static boolean inSameWeek(Date date1, Date date2) {
    if (null == date1 || null == date2) {
        return false;
    }

    Calendar earlier = Calendar.getInstance();
    Calendar later = Calendar.getInstance();

    if (date1.before(date2)) {
        earlier.setTime(date1);
        later.setTime(date2);
    } else {
        earlier.setTime(date2);
        later.setTime(date1);
    }
    if (inSameYear(date1, date2)) {
        int week1 = earlier.get(Calendar.WEEK_OF_YEAR);
        int week2 = later.get(Calendar.WEEK_OF_YEAR);
        if (week1 == week2) {
            return true;
        }
    } else {
        int dayOfWeek = earlier.get(Calendar.DAY_OF_WEEK); 
        earlier.add(Calendar.DATE, 7 - dayOfWeek);
        if (inSameYear(earlier.getTime(), later.getTime())) {
            int week1 = earlier.get(Calendar.WEEK_OF_YEAR);
            int week2 = later.get(Calendar.WEEK_OF_YEAR);
            if (week1 == week2) {
                return true;
            }
        }
    }
    return false;
}

public static boolean inSameYear(Date date1, Date date2) {
    if (null == date1 || null == date2) {
        return false;
    }
    Calendar cal1 = Calendar.getInstance();
    cal1.setTime(date1);
    int year1 = cal1.get(Calendar.YEAR);
    Calendar cal2 = Calendar.getInstance();
    cal2.setTime(date2);
    int year2 = cal2.get(Calendar.YEAR);
    if (year1 == year2)
        return true;

    return false;
}

尽管老问题仍然相关。这里投票最多的答案是正确的wrt到Joda time和wrt到JDK8以及一些语法更改。这里有一个可能会帮助那些在JDK8世界中四处寻找的人

 public static boolean isLocalDateInTheSameWeek(LocalDate date1, LocalDate date2) {
    LocalDate sundayBeforeDate1 = date1.with(TemporalAdjusters.previousOrSame(DayOfWeek.SUNDAY));
    LocalDate saturdayAfterDate1 = date1.with(TemporalAdjusters.nextOrSame(DayOfWeek.SATURDAY));
    return  ((date2.isEqual(sundayBeforeDate1) || date2.isAfter(sundayBeforeDate1)) 
            && (date2.isEqual(saturdayAfterDate1) || date2.isBefore(saturdayAfterDate1)));
}
tl;博士 使用名为
ta
TemporalAdjuster
测试一对
LocalDate
对象,该类使用
org.threeten.extra.LocalDateRange
类确定一周的第一天

        LocalDateRange.of( 
            localDate1.with( ta ) , 
            localDate1.with( ta ).plusWeeks( 1 ) 
        )
        .contains( 
            localDate2 
        )
额外加三十 该项目向java中内置的java.time类(由JSR310定义)添加了额外的功能

添加的类中包括。此类表示附加到时间轴的时间跨度。换句话说,一对
LocalDate
对象。此类提供了方便的比较方法,例如
重叠
包含
,以及
邻接
。这是我们需要的

定义一种方法,在其中传递两个日期加上一周的第一天(枚举对象)

我们使用在课堂上找到的
临时调整器来确定一周中第一天的日期。然后加上一周,得到一周的结束时间(根据时间跨度的半开放定义)

我们可以很可爱,看看两个日期是否相同。如果你的应用程序中经常出现这种情况,那么这是一个值得检查的问题

对于第2周,让我们使用一行程序作为替代语法

public boolean inSameWeek ( LocalDate localDate1 , LocalDate localDate2 , DayOfWeek firstDayOfWeek ) {
    Objects.requireNonNull( localDate1 ) ;  // … ditto for other arguments.

    if( localDate1.isEqual( localDate2 ) ) { return true ; }

    TemporalAdjuster ta = TemporalAdjusters.previousOrSame( firstDayOfWeek ) ;

    LocalDate weekStart1 = localDate1.with( ta ) ;
    LocalDate weekStop1 = weekStart1.plusWeeks( 1 ) ;
    LocalDateRange week1 = LocalDateRange.of( weekStart1 , weekStop1 ) ;

    LocalDateRange week2 = 
        LocalDateRange.of(
            localDate2.with( ta ) ,
            localDate2.with( ta ).plusWeeks( 1 ) 
        )
    ;

    // Compare the weeks.
    return week1.equals( week2 ) ;
}
或者更紧凑

public boolean inSameWeek ( LocalDate localDate1 , LocalDate localDate2 , DayOfWeek firstDayOfWeek ) {
    Objects.requireNonNull( localDate1 ) ;  // … ditto for other arguments.

    if( localDate1.isEqual( localDate2 ) ) { return true ; }

    TemporalAdjuster ta = TemporalAdjusters.previousOrSame( firstDayOfWeek ) ;
    return 
        LocalDateRange.of( 
            localDate1.with( ta ) , 
            localDate1.with( ta ).plusWeeks( 1 ) 
        )
        .equals( 
            LocalDateRange.of( 
                localDate2.with( ta ) , 
                localDate2.with( ta ).plusWeeks( 1 ) 
            )
        )
    ;
}
我们真的不需要第二周。我们只关心第一周是否确定了第二个通过日期参数

public boolean inSameWeek ( LocalDate localDate1 , LocalDate localDate2 , DayOfWeek firstDayOfWeek ) {
    Objects.requireNonNull( localDate1 ) ;  // … ditto for other arguments.

    if( localDate1.isEqual( localDate2 ) ) { return true ; }

    TemporalAdjuster ta = TemporalAdjusters.previousOrSame( firstDayOfWeek ) ;
    return 
        LocalDateRange.of( 
            localDate1.with( ta ) , 
            localDate1.with( ta ).plusWeeks( 1 ) 
        )
        .contains( 
            localDate2
        )
    ;
}
使用它

LocalDate localDate = LocalDate.of( 2019 , Month.JANUARY , 23 ) ;
LocalDate today = LocalDate.now( ZoneId.of( "Africa/Tunis") ) ;

boolean sameWeek = this.inSameWeek( localDate , today , DayOfWeek.SUNDAY ) ;

警告:我没有运行任何代码。

这里的大多数答案都不能让我满意。他们要么使用过时的
日历
-API(在Java8之前的时代给出的旧答案是可以理解的,因此批评这些答案是不公平的),要么甚至是部分错误或不必要的复杂。例如,Jon Skeet投票最多的答案建议通过Joda表达式
new LocalDate().withDayOfWeek(DateTimeConstants.SUNDAY)
确定一周的第一天。但此类代码使用ISO定义的周一开始的一周,其结果是,如果当前日期不在周日,代码将生成下周日,而不是OP所需的前周日。Joda Time无法处理非ISO周

其他答案的另一个小缺点是不关心当前和下周是否包含给定的日期-如OP要求的那样。因此,我在现代Java中的改进建议如下:

LocalDate today = LocalDate.now(); // involves the system time zone and clock of system
LocalDate startOfCurrentWeek =
  today.with(TemporalAdjusters.previousOrSame(DayOfWeek.SUNDAY));
LocalDate endOfNextWeek =
  startOfCurrentWeek.plusDays(13);

LocalDate event = LocalDate.of(2011, 1, 3); // input of example given by OP

boolean matchingResult =
  !(event.isBefore(startOfCurrentWeek) || event.isAfter(endOfNextWeek));

旁注:这个问题启发我在我的库中的类
DateInterval
中添加一个如何以一种非常通用的方式确定当前日历周的方法。

这就是在Java 8中对我有效的方法

import java.time.LocalDate;

LocalDate today = LocalDate.now();
LocalDate twoWeeksBefore = today.minusWeeks(2);
LocalDate checkDate = someObject.getSomeDate();

if(checkDate.compareTo(twoWeeksBefore) > 0) {
    // do something if checkDate is within last two weeks
} else {
    // do something if checkDate is on or before last two weeks
}

你如何定义一周?在其他文化中,如果定义与您在自己的文化中使用的定义不同,该怎么办?那会发生什么呢?只是标准的星期一。。星期六。@Frank据我所知,没有一个标准将一周定义为星期天到星期六。这在美国很常见,但在世界上大部分地区并不常见,尤其是在商业领域。比如将一周定义为周一到周日,以及定义一年中的周数。我强烈建议不要使用日历,因为它通常是一个可怕的API。使用一年中的第二天会让一周变得非常棘手,这一周涵盖了两个不同的年份……乔恩,我实际上是指一年中的第二周,我试图立即纠正。我真的希望我正确地理解了这个问题。@Arturs:对,每年的第二周会有帮助。。。但是,检查“下周”仍然是相对棘手的,因为你需要检查总结以及它是哪一年。我仍然建议使用Joda Time。@Arturs:Joda Time在很多方面都更好。这很大程度上是因为它区分了所涉及的许多不同类型——日期、时间、日期和时间,那些是本地的,而那些有时区的等等。同时,不变性也使得它更容易推理。@Jon谢谢。我还浏览了“为什么是Joda时间?”和“用户指南”部分,现在我看到了lib背后的动机,以及它是如何超越JDK日历的。但是不要错过一年前的最后一周!第一次比较“其他”不是多余的吗?他还澄清说,他指的是太阳-卫星周,而不仅仅是接下来的7天。@Matthew:为什么?例如,事件可能发生在过去。你是对的,我误读了。:)但是,您可以今天将
拉出。将(事件)
与包含
if
else if
if
进行比较。那么,我提到的比较就没有必要了。@Matthew:你可以,是的。就我个人而言,我喜欢每一对比较都做了测试条件所需的一切。。。但是,是的,它的效率比可能的要低一些。我添加了一个wee日的编辑
import java.time.LocalDate;

LocalDate today = LocalDate.now();
LocalDate twoWeeksBefore = today.minusWeeks(2);
LocalDate checkDate = someObject.getSomeDate();

if(checkDate.compareTo(twoWeeksBefore) > 0) {
    // do something if checkDate is within last two weeks
} else {
    // do something if checkDate is on or before last two weeks
}