Java中两个日期字符串的区别

5ktev3wc  于 9个月前  发布在  Java
关注(0)|答案(7)|浏览(91)

我试图计算两个日期字符串之间的差异,这两个字符串都是从用户通过格式的HTML表单(yyyy/MM/DD)代码:

public boolean diffDate() throws ParseException
 {
     date1 = getissuedate();
     date2 = getduedate();
         Calendar cal1 = Calendar.getInstance();
    Calendar cal2 = Calendar.getInstance();
    SimpleDateFormat formatter1 = new SimpleDateFormat("yyyy/MM/dd");
    SimpleDateFormat formatter2 = new SimpleDateFormat("yyyy/MM/dd"); 
Date date_old = formatter1.parse(date1);
Date date_new = formatter2.parse(date2);
long milis1 = date_old.getTime();
long milis2 = date_new.getTime();

long diff = milis2 - milis1;       

    if( diff<3 || diff>3)
    {
        return true;
    }
    else 
    {       
        return false;
    }       
 }

字符串
现在我使用一个if条件来报告我的网页中的错误,如果日期之间的差异不等于3。代码:

try {
        if(diffDate())
        {
            errors.add("duedate", new ActionMessage("error.duedate.required"));
        }
    } catch (ParseException ex) {
        Logger.getLogger(IssueBookForm.class.getName()).log(Level.SEVERE, null, ex);
    }


其中,error.duedate.requiredMap为“check date”
因此,问题是“检查日期”错误打印两个日期字符串的任何值。

nbysray5

nbysray51#

你正在测试两个日期是否相差3毫秒,这几乎总是正确的。如果你真的想要3天,值应该是3864001000。如果你关心闰秒和夏令时的变化,那么问题就会变得更加复杂。

7uhlpewt

7uhlpewt2#

从yyyy/MM/dd格式的字符串中获得的两个日期之间的差异永远不会正好为3 * 毫秒 *(最大精度为24小时)
如果你想要3天的差异,使用24*60*60*1000作为因子来缩放值

x6492ojm

x6492ojm3#

你的病情差<3|| diff>3等价于diff!= 3,并且diff以毫秒为单位表示。这个表达式永远不会为真。

8iwquhpp

8iwquhpp4#

如果你解析日期的分辨率为1天,即86.000.000毫秒,你永远不会得到它们相差3毫秒的情况。
getTime()以ms为单位返回自“epoch开始”以来的时间,因此它返回毫秒或1/1000 s。

diff < 3 || diff > 3

字符串
是一样的

diff != 3


如果您想检测正好相差3天的日期,您可以在比较之前将米利斯的数量除以ms/天的数量。

r1wp621o

r1wp621o5#

Calendar有一个方法add,它接受一个量和一个时间单位,还有一个方法compareTo,它接受另一个日历。

gwo2fgha

gwo2fgha6#

tl;干

java.lang.Math.abs (
    ChronoUnit.DAYS.between(
        LocalDate.parse( "2017/01/23".replace( "/" , "-" ) ) ,
        LocalDate.parse( "2017/02/14".replace( "/" , "-" ) ) 
    )
) > 3L

字符串

使用java.时间

现代的方法使用java.time类,而不是麻烦的旧的遗留日期-时间类(DateCalendar等)。
您的输入字串几乎符合日期值的标准ISO 8601:YYYY-MM-DD。若要完全符合,请以勒胡号字符取代斜扛字符。

String inputA = "2017/01/23".replace( "/" , "-" ) ;
String inputB = "2017/02/14".replace( "/" , "-" ) ;


java.time类在解析/生成字符串时默认使用标准格式,所以不需要指定格式模式。

LocalDate ldA = LocalDate.parse( inputA );
LocalDate ldB = LocalDate.parse( inputB );


问题的其余部分没有意义,因为它测试的是+/-3毫秒,而这在日期之间不可能是真的。显然,您是要检查天数。为此,请使用ChronoUnit枚举。

long daysBetween = ChronoUnit.DAYS.between( ldA , ldB );


如果第二个日期实际上发生在第一个日期 * 之前 *,则结果为负数。您似乎希望使用±3的公差来测试这两种情况。请使用java.lang.Math类的abs方法来测试我们的结果的绝对值。
ChronoUnit.DAYS.between方法返回一个long基元。因此,我们将该结果与我们的三个限制进行比较的测试必须与该类型匹配。请注意,使用L来指示3Llong类型的三个基元值。编译器可能会将3的默认值从int(32位)升级到long(64位),但我更喜欢使用3L来显式地显示。

if( abs( daysBetween ) > 3L ) { … }

关于java.时间

java.time框架内置于Java 8和更高版本中。这些类取代了麻烦的旧legacy日期-时间类,如java.util.DateCalendarSimpleDateFormat
Joda-Time项目(现在在maintenance mode中)建议迁移到java.time类。
要了解更多信息,请参阅Oracle Tutorial。并搜索堆栈溢出以获得许多示例和解释。规范是JSR 310
在哪里可以获得java.time类?

*Java SE 8Java SE 9及更高版本

  • 内建的。
  • 标准Java API的一部分,具有捆绑的实现。
  • Java 9添加了一些次要的特性和修复。
    *Java SE 6Java SE 7
  • 大多数java.time功能都是在ThreeTen-Backport中向后移植到Java 6和7的。
  • Android
  • ThreeTenABP项目专门针对Android调整了 ThreeTen-Backport(如上所述)。
  • 请参见How to use ThreeTenABP…

ThreeTen-Extra项目使用其他类扩展了java.time。此项目是将来可能添加到java. time的试验场。您可能会在此处找到一些有用的类,如IntervalYearWeekYearQuartermore

kse8i1jr

kse8i1jr7#

DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSSSSS");
public long diff(String start, String end) {
    LocalDateTime dateTime1 = LocalDateTime.parse(start, dtf);
    LocalDateTime dateTime2 = LocalDateTime.parse(end, dtf);
    Duration duration = Duration.between(dateTime1, dateTime2);
    return Math.abs(duration.toMillis());
}

字符串

相关问题