-1

I have 2 dates in String with format (MMM dd, yyyy hh:mm:ss a). How to convert two Strings into date and find the difference in minutes ?

DateFormat df = new SimpleDateFormat("MMM dd, yyyy hh:mm:ss a", Locale.ENGLISH);  
Date start = df.parse(startstring);
Date end = df.parse(endstring);

After I want to take the difference in minutes and I am using this code:

long result = ((end.getTime()/60000) - (start.getTime()/60000));

But the result is 0. How can I solve this problem ? My Strings are :

start: Fri Mar 07 23:45:43 GMT+04:00 2014
end: Fri Mar 07 23:46:01 GMT+04:00 2014

HK.avdalyan
  • 724
  • 1
  • 6
  • 21
  • 5
    Are they the same time? – djechlin Mar 07 '14 at 19:42
  • 3
    You may need to use a `double` instead of a `long`. –  Mar 07 '14 at 19:43
  • Can you provide the 2 dates or all the dates you try result in 0? – Jonathan Drapeau Mar 07 '14 at 19:44
  • 1
    Well what are your inputs? Bear in mind that with your current approach, you'll get one minute even if the times are (say) 3:34:59 and 3:35:00... and you'll get the same result for 3:34:01 to 3:35:59. Is that what you want? – Jon Skeet Mar 07 '14 at 19:44
  • possible duplicate of [Compare dates in Java](http://stackoverflow.com/questions/2592501/compare-dates-in-java) – aliteralmind Mar 07 '14 at 19:48
  • 4
    the difference between your dates is only 18 seconds which is equal to 0 minutes. – PC. Mar 07 '14 at 19:48
  • Yeah @JonSkeet I need that – HK.avdalyan Mar 07 '14 at 19:48
  • 1
    @PC.: But they're in different minutes, so I'd *expect* the OP's code to work. – Jon Skeet Mar 07 '14 at 19:50
  • 3
    The code you've given doesn't manage to parse the sample inputs you've given. Your `DateFormat` is expecting a 12-hour clock, an AM/PM designator, no time zone information, and the year after the month and day. Compare that with what you've provided. – Jon Skeet Mar 07 '14 at 19:52
  • The format, at least on my pc, should look like `Mar 06, 2014 02:48:41 PM` – Jonathan Drapeau Mar 07 '14 at 19:54
  • And when I change the start and end values to "Mar 07, 2014 11:45:43 PM" and "Mar 07, 2014 11:45:43 PM", the result is 1. – Jon Skeet Mar 07 '14 at 19:54
  • I actually do get 1 when I run your dates, but I had to modify the format string to match your input. Can you please post accurate input for a test case? – Jason C Mar 07 '14 at 19:54
  • @JonSkeet I would be suprised that it gives you 1 for the same date... but I'm sure that's a copy/paste error :) – Jonathan Drapeau Mar 07 '14 at 19:58
  • 2
    I Can Has [Joda-Time](http://joda-time.sourceforge.net/)? [`Minutes.minutesBetween(start,end)`](http://joda-time.sourceforge.net/apidocs/org/joda/time/Minutes.html#minutesBetween(org.joda.time.ReadableInstant,%20org.joda.time.ReadableInstant)) – Anthony Accioly Mar 07 '14 at 20:00
  • @JonSkeet ^ Reminded me of a comment I saw on http://meta.stackexchange.com/questions/19478/the-many-memes-of-meta, which amusingly turns out to be yours now that I look at it. – Jason C Mar 07 '14 at 20:05
  • 1
    Yes, yes, you should definitively drop that and use jQuery Joda-Time. – Anthony Accioly Mar 07 '14 at 20:11
  • @JonathanDrapeau: Yes, an unfortunate c&p error of having to head out the door as a child taxi... – Jon Skeet Mar 07 '14 at 20:17

3 Answers3

3

You could use this approach (first calculate the minutes since epoch, then subtract them) -

private static long getTimeInMinutesFromEpoch(Date d) {
    if (d == null) {
        return 0;
    }
    return d.getTime() / (60 * 1000);
}

public static long getMinuteDifference(Date a, Date b) {
    return Math.abs(getTimeInMinutesFromEpoch(b)
            - getTimeInMinutesFromEpoch(a));
}

public static void main(String[] args) throws ParseException {
    String startstring = "Mar 07, 2014 23:45:43 PM";
    String endstring = "Mar 07, 2014 23:46:01 PM";
    DateFormat df = new SimpleDateFormat("MMM dd, yyyy hh:mm:ss a",
            Locale.ENGLISH);

    Date start = df.parse(endstring);
    Date end = df.parse(startstring);
    System.out.println(getMinuteDifference(start, end));
}

Output is

1
Elliott Frisch
  • 198,278
  • 20
  • 158
  • 249
  • 1
    @GigantoMK: That's effectively what you've already got in your question! Your existing code already works if you give it valid input. My guess is that your *real* code before was masking the parse exception... – Jon Skeet Mar 07 '14 at 20:18
  • Dear @JonSkeet thanks for your response and support. I have done some mistakes in my code before and i got exceptions. now everything is clear – HK.avdalyan Mar 07 '14 at 20:23
  • 1
    @GigantoMK: The main thing to learn from this is that exception handling is important. Indeed, I dislike the exception handling in this answer - catching `Exception` is almost always a bad idea, as is just printing the stack trace and continuing. It's that sort of code that leads to the problem you had :( – Jon Skeet Mar 07 '14 at 20:24
  • @JonSkeet You are correct, so I cleaned up the exception handling. Obviously in my own "real" code I am not so cavalier. – Elliott Frisch Mar 07 '14 at 21:08
  • @ElliottFrisch: Well it's still just continuing - personally I'd declare that it just throws `ParseException` and not catch it. Doesn't matter much for `main`, but I see *far* too much code that catches exceptions and then keeps going... – Jon Skeet Mar 07 '14 at 21:09
  • @JonSkeet Exceptions should be *exceptional*, but I see *far* too many bug reports that don't include exceptions (because they are swallowed silently); and, that I think is the really problematic code (e.g. it catches the error, eats it, and then continues). – Elliott Frisch Mar 07 '14 at 21:13
  • @ElliottFrisch: Sure - but an exception which is never caught is hard to swallow, which is why I'm suggesting that the fewer `catch` blocks you have, the better :) – Jon Skeet Mar 07 '14 at 21:15
  • @JonSkeet Careful, it sounds like you are approaching an argument against checked exceptions (or exceptions in general). If we make every class immutable, implement some option type and (while we're at it) make functions first class objects... why are the LISPers and Schemers pointing and laughing? – Elliott Frisch Mar 07 '14 at 21:20
  • 1
    The argument is against liberal use of `catch` blocks, which is *usually* a red flag indicating that logic and exception handling could use some improvement. In an ideal situation, code would be structured so that an exception at any point still leaves the program in a determinate state, and the exception will *only* need to be caught at the very highest level where distinct recovery actions need to take place (note that notifying a user of an error is a recovery action). The ability to structure code that way is precisely the benefit of exceptions. I presume this is where @JonSkeet was going. – Jason C Mar 07 '14 at 21:55
  • @JasonC: Yup, that's pretty much it. I don't mind catching an exception to throw a more context-sensitive one, but it's *rarely* a good idea to catch it and just keep going. (Not impossible, but rare.) (And yes, I'm a big fan of immutable classes and first class functions too... what's wrong with that?) – Jon Skeet Mar 07 '14 at 22:33
2

From the looks of it you're creating the start date immediately before the end date (unless there is non-included relevant information).

Date start = df.parse(startstring);
Date end = df.parse(endstring);

These are going to be created in exactly the same minute and therefore give you 0 when you try to find the difference in minutes.

EDIT

Your times:

start: Fri Mar 07 23:45:43 GMT+04:00 2014
end: Fri Mar 07 23:46:01 GMT+04:00 2014

are 18 seconds apart. You're going to get 0 for the difference in minutes.

leigero
  • 3,233
  • 12
  • 42
  • 63
  • Deleted comment. Good spot. +1. – christopher Mar 07 '14 at 19:51
  • The dates are parsed from strings, not created from the current time. Also you would not expect to get 0 for the difference in minutes for the OP's implementation, as he is doing (integer division) `(end/60000)-(start/60000)` not `(end-start)/60000`. `end/60000` would result in a value that is 1 greater than `start/60000` there. – Jason C Mar 07 '14 at 19:56
1

You can make Calendar object instead of Date and then you can get the minutes using Calendar.get(Calendar.MINUTE). Note that by using this logic, the difference between 22:45:43 GMT+04:00 2014 and 23:45:43 GMT+04:00 2014 will be zero minutes.

PC.
  • 6,870
  • 5
  • 36
  • 71
  • That's one way to do it, but it's not required, and "must" is somewhat misleading. Also if you are simply grabbing the minute and subtracting, you will end up with incorrect results at hour boundaries. – Jason C Mar 07 '14 at 19:58
  • You found that offensive!? I changed it to **can** :) – PC. Mar 07 '14 at 19:59
  • Misleading != offensive; but calculating the difference based only on the minute component is the real issue. – Jason C Mar 07 '14 at 20:02