Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/date/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java中两个日期之间的周数_Java_Date_Datetime - Fatal编程技术网

Java中两个日期之间的周数

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

我的目的是得到两个日期范围之间的周数。第24天在第34周,第26天在第35周。现在的问题是,如果我把
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(week
public 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]
。使用locale
en_US
和区域id
America/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() )
);