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