简体   繁体   English

java 中两个日期字符串之间的差异

[英]Difference between two date strings in java

I am trying to calculate difference between two date strings both of which are taken from user through a html form in format (yyyy/MM/dd) Code:我正在尝试计算两个日期字符串之间的差异,这两个日期字符串都是通过 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;
    }       
 }

Now am using an if condition to report error in my webpage if difference between the date is not equal to 3. Code:如果日期之间的差异不等于 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);
    }

where error.duedate.required is mapped to "check date"其中 error.duedate.required 映射到“检查日期”

So, the issue is "check date" error is printed for any value of both date string.因此,问题是两个日期字符串的任何值都会打印“检查日期”错误。

You're testing if two dates differ by 3 milliseconds, which will almost always be true.您正在测试两个日期是否相差 3 毫秒,这几乎总是正确的。 If you really want 3 days, the value should be 3*86400*1000.如果你真的想要 3 天,这个值应该是 3*86400*1000。 If you care about what happens with leap-seconds and daylight-savings-time changes, then the problem gets more complex.如果您关心闰秒和夏令时更改会发生什么,那么问题就会变得更加复杂。

Your condition diff<3 ||您的条件差异<3 || diff>3 is equivalent to diff.= 3 and diff is expressed in milliseconds. diff>3 等价于 diff.= 3 并且 diff 以毫秒表示。 This expression will never be true.这个表达式永远不会是真的。

If you parse dates with a resolution of 1 day, ie 86.000.000 milliseconds, you will never get a situation where they are exactly 3 ms different.如果您以 1 天的分辨率(即 86.000.000 毫秒)解析日期,您将永远不会遇到它们恰好相差 3 毫秒的情况。

getTime() returns the time in ms since "the start of the epoch", so it returns milliseconds, or 1/1000 s. getTime() 返回自“纪元开始”以来的时间(以毫秒为单位),因此它返回毫秒或 1/1000 秒。

diff < 3 || diff > 3

is the same as是相同的

diff != 3

If you want to detect dates which are exactly 3 days different, you could divide the number of millis by the number of ms/day before comparing.如果您想检测正好相差 3 天的日期,您可以在比较之前将毫秒数除以毫秒/天数。

you'll never get a difference of exactly 3 milliseconds between two dates gotten from a yyyy/MM/dd formatted string (maximum accuracy will be 24 hours)从 yyyy/MM/dd 格式的字符串获得的两个日期之间永远不会相差 3毫秒(最大精度为 24 小时)

if you want 3 days difference use 24*60*60*1000 for a factor to scale the values如果您想要 3 天的差异,请使用24*60*60*1000作为缩放值的因子

java.util.Calendar has a method add , that takes a quantity and a unit of time, and a method called compareTo , that takes another calendar. java.util.Calendar 有一个方法add ,它需要一个数量和一个时间单位,以及一个名为compareTo的方法,它需要另一个日历。 You should be using those.你应该使用那些。

tl;dr tl;博士

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

Using java.time使用 java.time

The modern approach uses the java.time classes rather than the troublesome old legacy date-time classes ( Date , Calendar , and such).现代方法使用java.time类,而不是麻烦的旧旧日期时间类( DateCalendar等)。

Your input strings almost comply with the standard ISO 8601 format for date-only values: YYYY-MM-DD.您的输入字符串几乎符合仅日期值的标准ISO 8601格式:YYYY-MM-DD。 To fully comply, replace the slash characters with hyphen characters.要完全遵守,请将斜杠字符替换为连字符。

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

The java.time classes by default use the standard formats when parsing/generating strings. java.time 类在解析/生成字符串时默认使用标准格式。 So no need to specify a formatting pattern.所以不需要指定格式模式。

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

The rest of your Question does not make sense as it tests for +/- three milliseconds which cannot ever be true between dates.您问题的 rest 没有意义,因为它测试了 +/- 3 毫秒,这在日期之间永远不会是真的。 Apparently you meant to check for a count of days.显然你的意思是检查天数。 For that, use the ChronoUnit enum.为此,请使用ChronoUnit枚举。

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

If the second date actually occurs before the first date, the result is a negative number.如果第二个日期实际发生第一个日期之前,则结果为负数。 You seem to want to test for either case, using a tolerance of ±3.您似乎想使用 ±3 的容差来测试这两种情况。 Use the java.lang.Math class' abs method to test absolute value of our result.使用java.lang.Math类的abs方法来测试我们结果的绝对值。

The ChronoUnit.DAYS.between method returns a long primitive. ChronoUnit.DAYS.between方法返回一个long原语。 So our test comparing that result to our limit of three must match that type.因此,我们将该结果与我们的三个限制进行比较的测试必须与该类型匹配。 Note the use of the L to indicate that 3L is a primitive value of three of type long .请注意使用L表示3Llong类型的 3 的原始值。 The compiler might upgrade the default of 3 from int (32-bit) to long (64-bit), but I prefer to be explicit by using 3L .编译器可能会将默认值3int (32 位)升级到long (64 位),但我更喜欢使用3L来明确。

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

About java.time关于java.time

The java.time framework is built into Java 8 and later.java.time框架内置于 Java 8 及更高版本中。 These classes supplant the troublesome old legacy date-time classes such as java.util.Date , Calendar , & SimpleDateFormat .这些类取代了麻烦的日期时间类,例如java.util.DateCalendarSimpleDateFormat

The Joda-Time project, now in maintenance mode , advises migration to the java.time classes.现在处于维护模式Joda-Time项目建议迁移到java.time类。

To learn more, see the Oracle Tutorial .要了解更多信息,请参阅Oracle 教程 And search Stack Overflow for many examples and explanations.并在 Stack Overflow 上搜索许多示例和解释。 Specification is JSR 310 .规范是JSR 310

Where to obtain the java.time classes?从哪里获得 java.time 课程?

The ThreeTen-Extra project extends java.time with additional classes. ThreeTen-Extra项目通过附加类扩展了 java.time。 This project is a proving ground for possible future additions to java.time.该项目是未来可能添加到 java.time 的试验场。 You may find some useful classes here such as Interval , YearWeek , YearQuarter , and more .您可以在这里找到一些有用的类,例如IntervalYearWeekYearQuarter等等

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM