【问题标题】:Difference between two date strings in javajava中两个日期字符串的区别
【发布时间】:2017-05-10 03:29:40
【问题描述】:

我正在尝试计算两个日期字符串之间的差异,这两个日期字符串都是通过格式 (yyyy/MM/dd) 的 html 表单从用户那里获取的 代码:

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;
    }       
 }

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

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.required 映射到“检查日期”的地方

所以,问题是两个日期字符串的任何值都会打印“检查日期”错误。

【问题讨论】:

  • 你不需要两个格式化程序。
  • @Pablo :没关系我删除了第二个格式化程序,但问题仍然存在....:(

标签: java


【解决方案1】:

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

【讨论】:

    【解决方案2】:

    从 yyyy/MM/dd 格式的字符串获取的两个日期之间永远不会相差 3 毫秒(最大精度为 24 小时)

    如果您想要 3 天的差异,请使用 24*60*60*1000 作为缩放值的因子

    【讨论】:

      【解决方案3】:

      您的条件差异3 等价于 diff != 3 并且 diff 以毫秒表示。这个表达式永远不会是真的。

      【讨论】:

        【解决方案4】:

        如果您以 1 天的分辨率(即 86.000.000 毫秒)解析日期,您将永远不会遇到恰好相差 3 毫秒的情况。

        getTime() 返回自“纪元开始”以来的时间(以毫秒为单位),因此它返回毫秒或 1/1000 秒。

        diff < 3 || diff > 3
        

        相同
        diff != 3
        

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

        【讨论】:

          【解决方案5】:

          java.util.Calendar 有一个方法add,它接受一个数量和一个时间单位,还有一个名为compareTo 的方法,它接受另一个日历。你应该使用那些。

          【讨论】:

            【解决方案6】:

            tl;博士

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

            使用 java.time

            现代方法使用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.time

            java.time 框架内置于 Java 8 及更高版本中。这些类取代了麻烦的旧 legacy 日期时间类,例如 java.util.DateCalendarSimpleDateFormat

            Joda-Time 项目现在位于maintenance mode,建议迁移到java.time 类。

            要了解更多信息,请参阅Oracle Tutorial。并在 Stack Overflow 上搜索许多示例和解释。规格为JSR 310

            从哪里获得 java.time 类?

            ThreeTen-Extra 项目通过附加类扩展了 java.time。该项目是未来可能添加到 java.time 的试验场。您可以在这里找到一些有用的类,例如IntervalYearWeekYearQuartermore

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2014-11-15
              • 2011-08-22
              • 2021-10-07
              • 2020-12-25
              • 2016-12-01
              相关资源
              最近更新 更多