When developing an Android application, it is occasionally necessary to use a function that prompts the user to use the number of days. From the implementation point of view, it is nothing more than persistently storing the time firstTime (through SharedPreferences, xml, sqlite, etc.) of the user's first use of the application. When using the application, the time presentTime is obtained at this time, and the number of days between the two times is calculated.
When two time variables are obtained, the method of calculating the date interval on the Internet is usually like this (the difference between the milliseconds of the two times is obtained and then processed):
- long beginTime = beginDate.getTime();
- long endTime = endDate.getTime();
- long betweenDays = (long)((endTime - beginTime) / (1000 * 60 * 60 *24));
long beginTime = beginDate.getTime(); long endTime = endDate.getTime(); long betweenDays = (long)((endTime - beginTime) / (1000 * 60 * 60 *24));
Let's test two special cases:
Case 1:
- Calendar beginCalendar = Calendar.getInstance();
- beginCalendar.set( 2017, 2, 3, 1, 0, 0); //Set the time to March 3, 2017 1:0:0
- Calendar endCalendar = Calendar.getInstance();
- endCalendar.set( 2017, 2, 3, 14, 0, 0); //Set the time to 14:0:0 on March 3, 2017
- long beginTime = beginCalendar.getTime().getTime();
- long endTime = endCalendar.getTime().getTime();
- long betweenDays = (long)((endTime - beginTime) / (1000 * 60 * 60 *24));
- System.out.println(betweenDays); //The output is 0
Calendar beginCalendar = Calendar.getInstance(); beginCalendar.set(2017,2,3,1,0,0); //Set the time to 1:0:0 on March 3, 2017 Calendar endCalendar = Calendar.getInstance(); endCalendar.set(2017,2,3,14,0,0); //Set the time to 14:0:0 on March 3, 2017 long beginTime = beginCalendar.getTime().getTime(); long endTime = endCalendar.getTime().getTime(); long betweenDays = (long)((endTime - beginTime) / (1000 * 60 * 60 *24)); System.out.println(betweenDays); //The output is 0
Case 2:
- Calendar beginCalendar = Calendar.getInstance();
- beginCalendar.set( 2017, 2, 2, 20, 20, 20);<span style= "white-space: pre;"> </span> //Set the time to 20:20 on March 2, 2017: 20
- Calendar endCalendar = Calendar.getInstance();
- endCalendar.set( 2017, 2, 3, 10, 10, 10); //Set the time to 10:10:10 on March 3, 2017
- long beginTime = beginCalendar.getTime().getTime();
- long endTime = endCalendar.getTime().getTime();
- long betweenDays = (long)((endTime - beginTime) / (1000 * 60 * 60 *24));
- System.out.println(betweenDays); //The output is 0, but it should be 1
Calendar beginCalendar = Calendar.getInstance();
beginCalendar.set(2017,2,2,20,20,20); //Set the time to 20:20:20 on March 2, 2017
Calendar endCalendar = Calendar.getInstance();
endCalendar.set(2017,2,3,10,10,10); //Set the time to 10:10:10 on March 3, 2017
long beginTime = beginCalendar.getTime().getTime();
long endTime = endCalendar.getTime().getTime();
long betweenDays = (long)((endTime - beginTime) / (1000 * 60 * 60 *24));
System.out.println(betweenDays); //The output is 0, but it should be 1
It can be seen that the code output is 0 for the case where the time interval should be 1. The reason is because when the difference between the milliseconds of the two dates is less than the milliseconds of a day (1000 *60*60*24) , even if the two dates span a day, the result will become 0 after the coercion. From the figure below, you can see two cases where the difference in milliseconds is less than one day.
Case 1 (the difference in milliseconds is less than one day and does not span days, the date interval should be 0):
Case 2 (difference in milliseconds is less than one day and across days, date interval should be 1):
So the above code needs to be improved so that it can recognize the special case of crossing the sky:
- public static int getTimeDistance(Date beginDate , Date endDate ) {
- Calendar beginCalendar = Calendar.getInstance();
- beginCalendar.setTime(beginDate);
- Calendar endCalendar = Calendar.getInstance();
- endCalendar.setTime(endDate);
- long beginTime = beginCalendar.getTime().getTime();
- long endTime = endCalendar.getTime().getTime();
- int betweenDays = ( int)((endTime - beginTime) / ( 1000 * 60 * 60 * 24)); //First calculate the difference between the milliseconds of the two times is greater than the number of days in a day
- endCalendar.add(Calendar.DAY_OF_MONTH, -betweenDays); //Subtract these days from endCalendar, and convert the problem into a situation where the difference between the milliseconds of the two times is less than one day
- endCalendar.add(Calendar.DAY_OF_MONTH, - 1); // subtract 1 day from endCalendar
- if(beginCalendar.get(Calendar.DAY_OF_MONTH)==endCalendar.get(Calendar.DAY_OF_MONTH)) //Compare whether the DAY_OF_MONTH of the two dates are equal
- return betweenDays + 1; //Equal means that the day is indeed crossed
- else
- return betweenDays + 0; //Inequality means that the day is not crossed
- }
public static int getTimeDistance(Date beginDate , Date endDate ) { Calendar beginCalendar = Calendar.getInstance(); beginCalendar.setTime(beginDate); Calendar endCalendar = Calendar.getInstance(); endCalendar.setTime(endDate); long beginTime = beginCalendar.getTime().getTime(); long endTime = endCalendar.getTime().getTime(); int betweenDays = (int)((endTime - beginTime) / (1000 * 60 * 60 *24));//First calculate the difference between the milliseconds of the two times is greater than the number of days in a day endCalendar.add(Calendar.DAY_OF_MONTH, -betweenDays);//Subtract these days from endCalendar and convert the problem to a situation where the difference between the milliseconds of the two times is less than one day endCalendar.add(Calendar.DAY_OF_MONTH, -1);//Subtract 1 day from endCalendar if(beginCalendar.get(Calendar.DAY_OF_MONTH)==endCalendar.get(Calendar.DAY_OF_MONTH))//Compare the DAY_OF_MONTH of the two dates are equal return betweenDays + 1; //Equal means that the day is indeed crossed else return betweenDays + 0; //Inequality means that the day is not crossed }
There is a detail in the code that needs attention. I first use endCalendar.add(Calendar.DAY_OF_MONTH, -1), and then compare the DAY_OF_MONTH time values of the two dates to determine the return value.
rather than directly
- return betweenDays + endCalendar.get(Calendar.DAY_OF_MONTH)-beginCalendar.get(Calendar.DAY_OF_MONTH);
return betweenDays + endCalendar.get(Calendar.DAY_OF_MONTH)-beginCalendar.get(Calendar.DAY_OF_MONTH);
This is because there may be cross-month situations. For example, the date of beginCalendar is February 28, the date of endCalendar is March 1, and the value of endCalendar.get(Calendar.DAY_OF_MONTH)-beginCalendar.get(Calendar.DAY_OF_MONTH) will be -27 instead of 1 as expected. And using endCalendar.add(Calendar.DAY_OF_MONTH, -1), the Calendar class method will automatically convert the cross-month situation.