开发者

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:

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 =开发者_JAVA百科 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:

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"

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. If you really want 3 days, the value should be 3*86400*1000. If you care about what happens with leap-seconds and daylight-savings-time changes, then the problem gets more complex.


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)

if you want 3 days difference use 24*60*60*1000 for a factor to scale the values


Your condition diff<3 || diff>3 is equivalent to diff != 3 and diff is expressed in milliseconds. This expression will never be true.


If you parse dates with a resolution of 1 day, i.e. 86.000.000 milliseconds, you will never get a situation where they are exactly 3 ms different.

getTime() returns the time in ms since "the start of the epoch", so it returns milliseconds, or 1/1000 s.

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.


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. You should be using those.


tl;dr

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

Using java.time

The modern approach uses the java.time classes rather than the troublesome old legacy date-time classes (Date, Calendar, and such).

Your input strings almost comply with the standard ISO 8601 format for date-only values: 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. 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. Apparently you meant to check for a count of days. For that, use the ChronoUnit enum.

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. Use the java.lang.Math class’ abs method to test absolute value of our result.

The ChronoUnit.DAYS.between method returns a long primitive. 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. 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.

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

About java.time

The java.time framework is built into Java 8 and later. These classes supplant the troublesome old legacy date-time classes such as java.util.Date, Calendar, & SimpleDateFormat.

The Joda-Time project, now in maintenance mode, advises migration to the java.time classes.

To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310.

Where to obtain the java.time classes?

  • Java SE 8, Java SE 9, and later
    • Built-in.
    • Part of the standard Java API with a bundled implementation.
    • Java 9 adds some minor features and fixes.
  • Java SE 6 and Java SE 7
    • Much of the java.time functionality is back-ported to Java 6 & 7 in ThreeTen-Backport.
  • Android
    • The ThreeTenABP project adapts ThreeTen-Backport (mentioned above) for Android specifically.
    • See How to use ThreeTenABP….

The ThreeTen-Extra project extends java.time with additional classes. This project is a proving ground for possible future additions to java.time. You may find some useful classes here such as Interval, YearWeek, YearQuarter, and more.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜