0

I want to make a function for my android app, where i pass 3 variables

  1. From (string representing a date)
  2. To (string representing a date)
  3. unit (integer)

What the result should be, is the difference of these two date in weeks, or days or years depending on unit. This is my code:

 private int datesDifference(String from, String to, int unit){
   Calendar from_date = Calendar.getInstance();
   Calendar to_date = Calendar.getInstance();
   DebugLogger.debug("From date = "+from+" to date = "+to);

   SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MMM-dd", Locale.getDefault());
   try {
       from_date.setTime(sdf.parse(from));
       to_date.setTime(sdf.parse(to));
   } catch (ParseException e) {
       e.printStackTrace();
   }

   int from_year = from_date.get(Calendar.YEAR);
   int from_month = from_date.get(Calendar.MONTH)+1;
   int from_day = from_date.get(Calendar.DAY_OF_MONTH);
   DebugLogger.debug("from_year "+from_year+" from month "+from_month+" from day "+from_day);

   int to_year = to_date.get(Calendar.YEAR);
   int to_month = to_date.get(Calendar.MONTH)+1;
   int to_day = to_date.get(Calendar.DAY_OF_MONTH);
   DebugLogger.debug("to_year "+to_year+" to month "+to_month+" to day "+to_day);


   from_date.set(from_year, from_month, from_day);//set begin_of_goal_date
   to_date.set(to_year, to_month, to_day);//set now_date

   if(unit==0){
       //TODO unit for days difference
       return 0;
   }else if(unit==1){
       //TODO unit for week difference
       long milliseconds1 = from_date.getTimeInMillis();
       long milliseconds2 = to_date.getTimeInMillis();
       long diff = milliseconds2 - milliseconds1;
       long diffWeeks = diff / (7*24 * 60 * 60 * 1000);
       int weeks = (int) diffWeeks;
       DebugLogger.debug("Difference in weeks "+weeks);
       return weeks;
   }else{
       //TODO unit for years difference
       return 0;
   }

}

The above code is not working correctly, as it does not take date from and to as calendar object but instead gets a from_date and to_date equal today! What is wrong with my code?

UPDATE

this is the data i pass in my function

    String begin_of_goal_date="2016-01-20";//when we changed the goal
    String now_date="2016-04-18";//now
    int weeks = datesDifference(begin_of_goal_date,now_date,1);
2

3 Answers 3

2

If data example is in this format 2016-01-20

Change SimpleDateFormat format from yyyy-MMM-dd to yyyy-MM-dd:

SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd", Locale.getDefault());

With this call:

datesDifference("2016-01-01", "2016-02-01", 1);

OUTPUT

From date = 2016-01-01 to date = 2016-02-01
from_year 2016 from month 1 from day 1
to_year 2016 to month 2 to day 1
Difference in weeks 4

With your example:

String begin_of_goal_date="2016-01-20";//when we changed the goal
String now_date="2016-04-18";//now
int weeks = datesDifference(begin_of_goal_date,now_date,1);

OUTPUT:

From date = 2016-01-20 to date = 2016-04-18
from_year 2016 from month 1 from day 20
to_year 2016 to month 4 to day 18
Difference in weeks 12
Sign up to request clarification or add additional context in comments.

Comments

1

java.time

The legacy date-time API (java.util date-time types and their formatting type, SimpleDateFormat) is outdated and error-prone. It is recommended to stop using it completely and switch to java.time, the modern date-time API*.

Solution using the modern API:

import java.time.LocalDate;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeFormatterBuilder;
import java.time.temporal.ChronoField;
import java.time.temporal.ChronoUnit;
import java.util.Locale;

public class Main {
    public static void main(String[] args) {
        // Test
        System.out.println(getDuration("2020-05-05", "2021-05-07", ChronoUnit.YEARS));
        System.out.println(getDuration("2020-05-05", "2021-05-07", ChronoUnit.MONTHS));
        System.out.println(getDuration("2020-05-05", "2021-05-07", ChronoUnit.DAYS));
        System.out.println(getDuration("2020-05-05 10:20:30", "2021-05-07 5:10:15", ChronoUnit.YEARS));
        System.out.println(getDuration("2020-05-05 10:20:30", "2021-05-07 5:10:15", ChronoUnit.MONTHS));
        System.out.println(getDuration("2020-05-05 10:20:30", "2021-05-07 5:10:15", ChronoUnit.DAYS));
        System.out.println(getDuration("2020-05-05 10:20:30", "2021-05-07 5:10:15", ChronoUnit.HOURS));
        System.out.println(getDuration("2020-05-05 10:20:30", "2021-05-07 5:10:15", ChronoUnit.MINUTES));
        System.out.println(getDuration("2020-05-05 10:20:30", "2021-05-07 5:10:15", ChronoUnit.SECONDS));
        System.out.println(getDuration("5:10:15", "10:20:30", ChronoUnit.HOURS));
        System.out.println(getDuration("5:10:15", "10:20:30", ChronoUnit.MINUTES));
        System.out.println(getDuration("5:10:15", "10:20:30", ChronoUnit.SECONDS));
    }

    public static long getDuration(String from, String to, ChronoUnit unit) {
        ZonedDateTime zdt = LocalDate.now().atStartOfDay(ZoneId.systemDefault());
        
        DateTimeFormatter dtf = new DateTimeFormatterBuilder()
                                .appendPattern("[u-M-d][ ][H[:m[:s]]]")
                                .parseDefaulting(ChronoField.YEAR, zdt.getYear())
                                .parseDefaulting(ChronoField.MONTH_OF_YEAR, zdt.getMonthValue())
                                .parseDefaulting(ChronoField.DAY_OF_MONTH, zdt.getDayOfMonth())
                                .parseDefaulting(ChronoField.HOUR_OF_DAY, zdt.getHour())
                                .parseDefaulting(ChronoField.MINUTE_OF_HOUR, zdt.getMinute())
                                .parseDefaulting(ChronoField.SECOND_OF_MINUTE, zdt.getSecond()) 
                                .parseDefaulting(ChronoField.NANO_OF_SECOND, zdt.getNano()) 
                                .toFormatter(Locale.ENGLISH)
                                .withZone(ZoneId.systemDefault());
        
        return unit.between(ZonedDateTime.parse(from, dtf), ZonedDateTime.parse(to, dtf));
    }
}

Output:

1
12
367
1
12
366
8802
528169
31690185
5
310
18615

Note that DateTimeFormatter allows specifying optional patterns using square brackets. Alternatively, it can be done with the help of DateTimeFormatterBuilder#optionalStart and DateTimeFormatterBuilder#optionalEnd.

Learn more about the the modern date-time API* from Trail: Date Time.


* For any reason, if you have to stick to Java 6 or Java 7, you can use ThreeTen-Backport which backports most of the java.time functionality to Java 6 & 7. If you are working for an Android project and your Android API level is still not compliant with Java-8, check Java 8+ APIs available through desugaring and How to use ThreeTenABP in Android Project.

Comments

0

Simply use Joda Time

Days d = Days.daysBetween(startDate, endDate);
int days = d.getDays();

http://joda-time.sourceforge.net/faq.html#datediff

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.