为了账号安全,请及时绑定邮箱和手机立即绑定

如何使用公历和 While 循环计算两个日期之间的天数

如何使用公历和 While 循环计算两个日期之间的天数

茅侃侃 2021-12-10 10:52:30
public class DVD implements Serializable {private static final long serialVersionUID = 1L;protected GregorianCalendar rentedOn;protected GregorianCalendar dueBack;protected String title;protected String nameOfRenter;public double getCost(GregorianCalendar ActualDatRented) {    double cost = 3;    double count = 0;    if (ActualDatRented.after(this.dueBack)) {        while(!dueBack.equals(ActualDatRented)) {            count++;            dueBack.add(Calendar.DATE,1);            cost = cost + count;            return cost;        }    }else if(ActualDatRented.equals(dueBack))        cost = 3;    return cost;  }}此代码假设计算dueBack 和ActualDatRented 之间的天数,并在dueBack 日期之后的每一天增加1 美元的成本。它不需要在 while 循环中,但我认为它会更容易编写,但我知道如果在 while 循环中编写,它将必须每天循环,直到 ActualDatRented 等于 DueBack 日期和添加 1 以计算每个循环的成本。我如何使此代码工作?
查看完整描述

2 回答

?
白猪掌柜的

TA贡献1893条经验 获得超10个赞

为了回答您的问题,您的代码在一个循环后停止的原因是returnwhile 循环末尾的语句。此外,如果dueBack与 相同ActualDateRented,它将根据您的 else 语句返回 3。

但是这段代码还有其他一些问题。您正在dueBackActualDateRentedusing进行比较!=,它用于对象检查它们是否是完全相同的对象,而不是比较值。您应该使用该equals方法来比较日期。

从更一般的意义上说,您使用GregorianCalendarJava 8 的日期/时间 API是否有特殊原因?“新”API 更易于使用,您无需编写自己的循环来确定天之间的差异。您可以查看https://www.baeldung.com/java-8-date-time-intro了解更多信息。


查看完整回答
反对 回复 2021-12-10
?
守着星空守着你

TA贡献1799条经验 获得超8个赞

数天。


ChronoUnit.DAYS.between( 

    myGregorianCalendar_Start.toZonedDateTime().toLocalDate() , 

    myGregorianCalendar_Stop.toZonedDateTime().toLocalDate() 

)

比较。


if( 

     myGregorianCalendar_Start.toZonedDateTime().toLocalDate()

     .isBefore( 

          myGregorianCalendar_Stop.toZonedDateTime().toLocalDate()

     )

) { … }

做数学。(未经测试的代码,用作概念指南,实际上需要根据您的业务规则指定四舍五入到一美分或十分之一美分)


new BigDecimal( "3" )  // Base cost.

.add( 

    new BigDecimal(

        ChronoUnit.DAYS.between(  // Calculate days overdue.

            myGregorianCalendar_Start.toZonedDateTime().toLocalDate() , 

            myGregorianCalendar_Stop.toZonedDateTime().toLocalDate() 

         )

    )

    .multiply(

        new BigDecimal( "1.5" )  // Daily overdue fee.

    )

)

细节

瑞克的答案是正确的,应该被接受。


正如他指出的那样,您正在使用糟糕的旧日期时间类 ( GregorianCalendar),这些类在多年前被JSR 310 中定义的java.time类取代。


该GregorianCalendar班所取代ZonedDateTime。您应该完全避免使用旧类。但是当需要与尚未更新为java.time 的旧代码进行交互时,您可以使用添加到旧类的新方法进行转换。


ZonedDateTime zdt = myGregorianCalendar.toZonedDateTime() ;

然后再回来。


GregorianCalendar myGregorianCalendar = GregorianCalendar.from( zdt ) ;

ZonedDateTime手头有一个对象,您可以提取仅日期部分,而无需时间和时区。


LocalDate ld = zdt.toLocalDate() ;

使用ChronoUnit枚举计算经过的天数。


long days = ChronoUnit.DAYS.between( ldStart , ldStop ) ;

请注意,结果是long(64 位整数),而不是 32 位int,因此如果与其他需要int.


int days = ( int ) ChronoUnit.DAYS.between( ldStart , ldStop ) ;

BigDecimal

顺便说一句,在实际工作中,永远不要使用double或Double也不要float或Float为金钱。这些类型使用浮点技术,以牺牲准确性来获得快速性能。


在任何准确性很重要的上下文中,例如处理金钱,只使用慢但准确的类BigDecimal。


查看完整回答
反对 回复 2021-12-10
  • 2 回答
  • 0 关注
  • 194 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信