我有 4 个日期,即今天(当前系统日期)、活动日期、quoteFinishFirstFolloupDate 和 quoteFinishSecondFollowupDate,我是根据某些标准计算出来的,但如果计算出的日期正好在周末(即周六、周日),那么我们需要增加或添加天数,以便下一个日期为工作日。那么,我如何计算天数并将其添加到工作日日期呢?我已经尝试了一些但是对于 Date 对象,我无法计算天数。
这是我的一段代码:
if (logs != null && logs.size() > 0) {
ActivityLog latestActivityLog = logs.get(0);
Date activityDate = latestActivityLog.getActivityDate();
Date today = new Date();
Calendar cal = Calendar.getInstance();
cal.setTime(today);
cal.set(Calendar.HOUR_OF_DAY, 0);
cal.set(Calendar.MINUTE, 0);
cal.set(Calendar.SECOND, 0);
cal.set(Calendar.MILLISECOND, 0);
int dayOfWeek = cal.get(Calendar.DAY_OF_WEEK);
// check if it is Saturday(day=7) or Sunday(day=1)
if ((dayOfWeek == 7)) {
cal.add(Calendar.DAY_OF_WEEK, 2);
today = cal.getTime();
}else if ((dayOfWeek == 1)) {
cal.add(Calendar.DAY_OF_WEEK, 2);
today = cal.getTime();
}else {
today = cal.getTime();
}
// @TODO: @RD to check +1 day logic
// plus 1 to include the endate=today+26 with time at 1pm
Date quoteFinishFirstFolloupDate = DateUtils.addDays(activityDate, -1 * getUnboundQuoteFirstFollowupDays());
Date quoteFinishSecondFollowupDate = DateUtils.addDays(quoteFinishFirstFolloupDate, getUnboundQuoteSecondFollowupDays());
if (today.compareTo(quoteFinishFirstFolloupDate) == 0 || today.compareTo(quoteFinishSecondFollowupDate) == 0) {
isValidCCVB_ActivityLog = Boolean.TRUE;
log.info("isValidCCVB_ActivityLog:" + isValidCCVB_ActivityLog);
}
}
有人能帮帮我吗?
Calendar c =
GregorianCalendar.from( // A subclass of `Calendar` legacy class.
myLegacyJavaUtilDate // Legacy class representing a moment as seen in UTC.
.toInstant() // Convert this moment as seen in UTC from legacy class to modern class.
.atZone( ZoneId.of( "Asia/Tokyo" ) ) // See the same moment through the wall-clock date & time of a particular time zone. Returns an `ZonedDateTime`.
.toLocalDate() // Extract a date-only value.
.with( org.threeten.extra.Temporals.nextWorkingDayOrSame() // Move to the next weekday if not already a weekday.
.atStartOfDay( ZoneId.of( "Asia/Tokyo" ) ) // Determine the first moment of the day as seen in that zone on that date. Returns an `ZonedDateTime`.
)
;
避免有问题的遗留日期时间类,例如
Date
类。如果需要与尚未更新到 java.time 类的旧代码进行互操作,请在 java.time 中编写新逻辑,最后转换为遗留对象。
java.time.Instant
是新的java.util.Date
.java.util.Date
类被java.time.Instant
取代。使用添加到旧类的新方法进行转换。
Instant instant = myJUDate.toInstant() ;
LocalDate
你说:
Date today = new Date();
Calendar cal = Calendar.getInstance();
cal.setTime(today);
cal.set(Calendar.HOUR_OF_DAY, 0);
cal.set(Calendar.MINUTE, 0);
cal.set(Calendar.SECOND, 0);
cal.set(Calendar.MILLISECOND, 0);
显然,您想从
java.util.Date
对象中提取仅日期值,该对象包含日期和时间,与 UTC 的偏移量为零小时-分钟-秒。要正确提取日期,您必须指定要解释日期的时区。对于任何给定时刻,世界各地的日期因时区而异。
Instant instant = myJUDate.toInstant() ; // A moment as seen in UTC.
ZoneId z = ZoneId.of( "Asia/Tokyo" );
ZonedDateTime zdt = instant.atZone( z ) ; // The same simultaneous moment, but as seen through a particular time zone. The time of day, and even the date, may differ from that of the `Instant` above.
LocalDate localDate = zdt.toLocalDate() ; // Extract a date only, discarding the time-of-day and the time zone.
或更简单地说:
LocalDate localDate =
myJUDate
.toInstant()
.atZone( ZoneId.of( "Asia/Tokyo" ) )
.toLocalDate()
;
对 4 个
java.util.Date
输入中的 3 个使用这种代码。对于当前日期,今天,使用这个:
LocalDate today = LocalDate.now( z ) ;
你问:
如果计算出的日期正好是周末(即周六、周日),那么我们需要增加或增加天数,以便下一个日期为工作日。
这在 java.time.
中非常简单TemporalAdjuster
界面提供从一个日期移动到另一个日期。您希望在日期之间跳转的算法在该接口的实现中定义。
TemporalAdjusters
类提供了几个有用的此类实现。但是这些捆绑的实现都不会在周六和周日跳转。
第三方库ThreeTen-Extra恰好提供了
TemporalAdjuster
的实现,它做的正是你想要的,跳过周六和周日。将该库添加到您的项目中。然后访问调用 TemporalAdjuster
返回的
org.threeten.extra.Temporals.nextWorkingDayOrSame()
对象。 “OrSame”表示如果日期已经是工作日,则保留它,无需移动到另一个日期。
TemporalAdjuster nextOrSameWeekdayAdjuster = org.threeten.extra.Temporals.nextWorkingDayOrSame() ;
让调节器在您关心的每个日期工作。
LocalDate nextOrSameWeekDayClosestToToday = today.with( nextOrSameWeekdayAdjuster ) ;
注意java.time 使用不可变对象。不是改变(“变异”)原始对象,而是返回一个新对象,其值基于原始对象。
所以我们调整了一些
LocalDate
对象来避开周末。但是你要求java.util.Date
对象(显然)。
要从仅限日期的值 (
LocalDate
) 到某个时刻,我们必须应用一个时区来确定该地区当天的第一时刻。
不要假设一天从 00:00 开始。某些时区的某些日期从另一个时间开始,例如 01:00。让java.time确定第一个时刻。
ZonedDateTime firstMomentOfNextOrSameWeekDayClosestToToday = nextOrSameWeekDayClosestToToday.atStartOfDay( z ) ;
您评论:
但是由于一些限制,我使用的是日期和日历类。
如上所述,您应该避免使用遗留的日期时间类。他们真的有那么麻烦。
但是,如果您必须让遗留类的对象与尚未更新到 java.time 的旧代码进行互操作,请调用添加到旧类的新转换方法。
要转换,首先从我们的
java.time.Instant
对象中提取一个java.time.ZonedDateTime
。
Instant instant = firstMomentOfNextOrSameWeekDayClosestToToday.toInstant() ;
然后从现代转换为传统。
java.util.Date d = java.util.Date.from( instant ) ;
如果您想要在我们特定时区看到的时刻而不是 UTC (
java.util.Date
) 中看到的时刻,请将 ZonedDateTime
转换为从 GregorianCalendar
延伸的 Calendar
类。
Calendar c = GregorianCalendar.from( firstMomentOfNextOrSameWeekDayClosestToToday ) ;
将所有这些代码放在一起:
Calendar c =
GregorianCalendar.from(
myJUDate
.toInstant()
.atZone( ZoneId.of( "Asia/Tokyo" ) )
.toLocalDate()
.with( org.threeten.extra.Temporals.nextWorkingDayOrSame() )
.atStartOfDay( ZoneId.of( "Asia/Tokyo" ) )
)
;