6

I am given two dates (one of which is the present) and need to find the difference between the two. My code is giving me bad output (sometimes even negative).

I have tried using the Months, Days, Seconds, Hours, and Years classes and appropriate between methods with no luck.

Edit: Went back to my original code but without Duration. @Basil Bourque posted a great solution but I just don't have enough experience with Periods/Duration and all that to format dynamically from them.

Solution

public static String formattedTime(DateTime d){
    DateTime present = new DateTime(Calendar.getInstance());

    //dont really want to deal with WHY its 7hrs ahead. o well
    DateTime date = d.minusHours(7);

    int diff = Seconds.secondsBetween(date,present).getSeconds();
    String postfix = "s";
    Log.i("time", "" + diff);

    if(diff>59){
        diff = Minutes.minutesBetween(date, present).getMinutes();
        postfix = "s";
        if(diff>59){
            diff = Hours.hoursBetween(date, present).getHours();
            postfix = "hr";
            if(diff>1)
                postfix+="s";
            if(diff>23){
                diff = Days.daysBetween(date, present).getDays();
                postfix = "d";
                if(diff>6){
                    diff = Weeks.weeksBetween(date, present).getWeeks();
                    postfix = "wk";
                    if(diff>1)
                        postfix+="s";
                    if(diff>3){
                        diff = Months.monthsBetween(date, present).getMonths();
                        postfix = "m";
                        if(diff>11){
                            diff = Years.yearsBetween(date, present).getYears();
                            postfix = "yr";
                            if(diff>1)
                                postfix+="s";
                        }
                    }
                }
            }
        }
    }
    return diff+postfix;
}
Zach
  • 447
  • 6
  • 16
  • I have just realized that the server is in a different timezone. will update soon when i account for that – Zach Aug 03 '15 at 06:26

3 Answers3

6

You are working too hard. You are using the wrong class for your purpose.

Period Class

In Joda-Time, use the Period class when you want to represent a span of time as a number of years, months, days, hours, minutes, seconds. Joda-Time represents a span of time in any of three ways: Interval, Duration, or Period.

Joda-Time follows the ISO 8601 standard for parsing and generating string representations of the date-time values. For Period that means the PnYnMnDTnHnMnS format where P marks the beginning while the T separates the year-month-day portion from the hour-minute-second portion. A half-hour is PT30M. P3Y6M4DT12H30M5S represents "three years, six months, four days, twelve hours, thirty minutes, and five seconds". Search StackOverflow.com for more info and examples.

Look at the PeriodFormatter and PeriodFormatterBuilder classes if you want to pretty-print with words.

You can also ask the Period object for the various component numbers if you need the integers.

Time Zone

Also, you should specify a time zone. If omitted then your JVM’s current default time zone is applied implicitly. Better to specify explicitly the time zone you desire/expect.

Always use proper time zone names, never the 3-4 letter codes. Those codes are neither standardized nor unique. And they further confuse the issue of Daylight Saving Time (DST).

Furthermore, commonly servers are kept on UTC time zone. Usually best to do nearly all of your business logic, data storage, data exchange, and logging in UTC.

Example Code

Note that you can ask DateTime for current moment without involving a java.util.Date object (as seen in your Question).

Example code for Period.

DateTimeZone zone = DateTimeZone.forID( "America/Detroit" ) ;
DateTime then = new DateTime( yourJUDate , zone ) ;
DateTime now = DateTime.now( zone ) ;
Period period = new Period( then , now ) ;
Basil Bourque
  • 303,325
  • 100
  • 852
  • 1,154
  • That looks pretty good, but unfortunately i'm not sure how to use the formatter correctly. I think your answer is great but it should also be noted that with a difference of one day, getSeconds will return 0. Also, the formatter seems a bit limited with having to define one specifically for years.. but what if the date difference isnt a year? It would need cases. I ended up using Days/Seconds/Hours classes again and discovered that it was the date I retrieved from the server that was wrong. – Zach Aug 04 '15 at 05:25
  • 1
    @Zach Do you really want total leaped time in a big number of seconds? Looking at your code it seemed you only asked for total seconds in order to calculate the other granularities. Period handles the other granularities so no need for total seconds. But if you really do want total seconds, call [`period.toStandardSeconds()`](http://www.joda.org/joda-time/apidocs/org/joda/time/Period.html#toStandardSeconds--). For a period of a day, that method will give you 24 * 60 * 60. As for formatting, it is very powerful, flexible, and convenient. Read the doc and search StackOverflow for examples. – Basil Bourque Aug 04 '15 at 06:04
  • I guess it just made sense to start at one end of the spectrum of time units and I picked seconds. That's good to know though, I will definitely try to optimize it from here – Zach Aug 04 '15 at 18:06
1

You can see the answer just here: Number of days between two dates and adapt it with the unit you want.

Community
  • 1
  • 1
bryce
  • 842
  • 11
  • 35
0

Make two strings that compare each other, you can split it with the String#split() method to find out the year/month/day etc.

rockinroll99
  • 9
  • 1
  • 5
  • while that does seem like a surefire way to get my result, i'm looking for something a bit more elegant. I've read other questions like mine where people used the same code and achieved the correct results, so i must not be using Duration right – Zach Aug 03 '15 at 06:20