Java中两个日期之间的周数
我的目的是得到两个日期范围之间的周数。第24天在第34周,第26天在第35周。现在的问题是,如果我把Java中两个日期之间的周数,java,date,datetime,Java,Date,Datetime,我的目的是得到两个日期范围之间的周数。第24天在第34周,第26天在第35周。现在的问题是,如果我把2018-08-22T12:18:06166作为开始日期,我会得到34,35,36。我在这里不期望36,因为结束日期不在第36周。有人能帮我吗。这个问题与这里提供的解决方案不同。解决方案有一个我最近检测到的问题 下面是获取它的代码: public static void main(String[] args) { DateTimeFormatter format = DateTimeFor
2018-08-22T12:18:06166
作为开始日期,我会得到34,35,36。我在这里不期望36,因为结束日期不在第36周。有人能帮我吗。这个问题与这里提供的解决方案不同。解决方案有一个我最近检测到的问题
下面是获取它的代码:
public static void main(String[] args) {
DateTimeFormatter format = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss','SSS");
LocalDateTime startDate = LocalDateTime.parse("2018-08-24T12:18:06,166", format);
LocalDateTime endDate = LocalDateTime.parse("2018-08-26T12:19:06,188", format);
numberOfWeeks(startDate, endDate);
}
public static void numberOfWeeks(LocalDateTime startDate, LocalDateTime endDate) {
int addWeek = 0;
TemporalField tf = WeekFields.SUNDAY_START.weekOfYear();
if (startDate.get(tf) < endDate.get(tf)) {
addWeek = 1;
}
long weeks = WEEKS.between(startDate, endDate) + addWeek;
List<String> numberWeeks = new ArrayList<>();
if (weeks >= 0) {
int week = 0;
do {
//Get the number of week
LocalDateTime dt = startDate.plusWeeks(week);
int weekNumber = dt.get(tf);
numberWeeks.add(String.format("%d-W%d", dt.getYear(), weekNumber));
week++;
} while (week <= weeks);
}
System.out.println(numberWeeks);
}
publicstaticvoidmain(字符串[]args){
DateTimeFormatter format=模式的DateTimeFormatter.of(“yyyy-MM-dd'T'HH:MM:ss','SSS”);
LocalDateTime startDate=LocalDateTime.parse(“2018-08-24T12:18:06166”,格式);
LocalDateTime endDate=LocalDateTime.parse(“2018-08-26T12:19:06188”,格式);
周数(开始日期、结束日期);
}
公共静态无效周数(LocalDateTime开始日期、LocalDateTime结束日期){
int addWeek=0;
TemporalField tf=WeekFields.SUNDAY_START.weekOfYear();
if(startDate.get(tf)=0){
整周=0;
做{
//获取周数
LocalDateTime dt=startDate.plusWeeks(周);
int weekNumber=dt.get(tf);
add(String.format(“%d-W%d”,dt.getYear(),weekNumber));
周++;
}while(weekpublic static void numberOfWeeks(LocalDateTime startDateTime,LocalDateTime endDateTime){
if(startDateTime.isAfter(endDateTime)){
抛出新的IllegalArgumentException(“结束日期不得早于开始日期”);
}
LocalDate endDate=endDateTime.toLocalDate();
List numberWeeks=new ArrayList();
LocalDate currentDate=startDateTime.toLocalDate();
while(currentDate.isBefore(endDate)){
numberWeeks.add(formatWeek(currentDate));
currentDate=currentDate.plusWeeks(1);
}
//现在currentDate在endDate上或之后,但它们是否在同一周?
if(currentDate.get(WeekFields.SUNDAY\u START.weekOfWeekBasedYear())
==endDate.get(WeekFields.SUNDAY\u START.weekOfWeekBasedYear()){
numberWeeks.add(formatWeek(currentDate));
}
系统输出打印项次(周数);
}
公共静态字符串formatWeek(LocalDate currentDate){
返回字符串。格式(“%d-W%d”,
currentDate.get(WeekFields.SUNDAY\u START.weekBasedYear()),
currentDate.get(WeekFields.SUNDAY\u START.weekOfWeekBasedYear());
}
使用上述方法打印问题中的main
方法:
[2018-W342018-W35]
我看到你在链接的问题中忽略了,一个使用了Three Ten Extra library中的YearWeek
。所以我假设你不想这样做。所以我在这几周使用LocalDate
虽然有几个用户未能重现您的确切问题,但我同意您的问题代码存在缺陷。tl;dr
[34,35]
溪流
让我们考虑一下中所示的WeekFields
,但是使用Java流技术缩短代码
首先分析输入字符串以获取LocalDate
对象。该类表示一个只包含日期的值,不包含一天中的时间,也不包含时区
不幸的是,java.time类不支持逗号作为小数秒分隔符,而是希望使用句点(句号)。这与同时允许逗号和实际上更喜欢逗号的标准背道而驰。这是我在其他优秀的java.time类中发现的为数不多的缺陷之一,可能是由于来自美国的程序员的偏见。为了避免此缺陷,我们用句号代替逗号
LocalDate inputDateStart =
LocalDateTime.parse(
"2018-08-24T12:18:06,166".replace( "," , "." ) // Unfortunately, the *java.time* classes fail to support the comma and instead only period. This runs contrary to the ISO 8601 standard which allows both and prefers comma.
)
.toLocalDate()
;
LocalDate inputDateStop =
LocalDateTime.parse(
"2018-08-26T12:19:06,188".replace( "," , "." )
)
.toLocalDate()
;
您希望工作周定义为从星期日开始。因此,请将输入日期调整为该日期当天或之前的星期日
请注意,这里我们在止损处增加了一周,以适应问题的需要。更常见的情况是,我们不会这样做,而是遵循半开放的方法来定义一个时间跨度,其中开始是包容性的,而结束是排他性的。与半开放相比,问题显然需要完全封闭的方法,其中e开头和结尾都包含在内(我不建议这样做)
将一系列日期定义为一个流
。我们通过传递一周的周期来一次跳过一周
Stream< LocalDate > stream =
startDate
.datesUntil(
stopDate ,
Period.ofWeeks( 1 )
)
;
转储到控制台
System.out.println( weekNumbers );
[34,35]
一班轮
如果你真的想在简洁方面发疯,我们可以在一行代码中完成这一切。我不推荐这样做,但尝试起来很有趣
System.out.println(
LocalDateTime.parse( "2018-08-24T12:18:06,166".replace( "," , "." ) ).toLocalDate()
.with( TemporalAdjusters.previousOrSame( DayOfWeek.SUNDAY ) )
.datesUntil(
LocalDateTime.parse( "2018-08-26T12:19:06,188".replace( "," , "." ) ).toLocalDate()
.with( TemporalAdjusters.previousOrSame( DayOfWeek.SUNDAY ) )
.plusWeeks( 1 )
,
Period.ofWeeks( 1 )
)
.map( localDate -> localDate.get( WeekFields.SUNDAY_START.weekOfWeekBasedYear() ) )
.collect( Collectors.toList() )
);
[34,35]
请删除重复项,因为这个问题是出于增强目的@Henry您的第一段很混乱。您能更清楚地说明业务规则吗?并给出简单的示例:输入->输出。并消除字符串到LocalDateTime
的解析,因为这与您的问题无关。因为您显然,你知道如何获得日期的周数(在你的例子中是34和35),为什么不从开始周循环到结束周,而不是有缺陷的周数逻辑?无法复制。“如果我把2018-08-22T12:18:06166
作为开始日期,我得到34,35,36“我没有。我得到[2018-W34,2018-W35]
。使用localeen_US
和区域idAmerica/New_York
2018-08-22T12:18:06166运行,因为开始日期仍然是[2018-W34,2018-W35]
,另一个优雅的解决方案。非常令人愉快。谢谢。谢谢@basily您的第一个和最后一个代码块的可读性很低,并且很难在将来重用。您能让它更具可读性,从而对其他开发人员产生更好的影响吗?下面是一些建议
Stream< LocalDate > stream =
startDate
.datesUntil(
stopDate ,
Period.ofWeeks( 1 )
)
;
List< LocalDate > dates = stream.collect( Collectors.toList() );
System.out.println( dates );
List< Integer > weekNumbers =
stream
.map(
localDate -> localDate.get( WeekFields.SUNDAY_START.weekOfWeekBasedYear() )
)
.collect( Collectors.toList() )
;
System.out.println( weekNumbers );
System.out.println(
LocalDateTime.parse( "2018-08-24T12:18:06,166".replace( "," , "." ) ).toLocalDate()
.with( TemporalAdjusters.previousOrSame( DayOfWeek.SUNDAY ) )
.datesUntil(
LocalDateTime.parse( "2018-08-26T12:19:06,188".replace( "," , "." ) ).toLocalDate()
.with( TemporalAdjusters.previousOrSame( DayOfWeek.SUNDAY ) )
.plusWeeks( 1 )
,
Period.ofWeeks( 1 )
)
.map( localDate -> localDate.get( WeekFields.SUNDAY_START.weekOfWeekBasedYear() ) )
.collect( Collectors.toList() )
);