可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
I am getting the current date (in format 12/31/1999 i.e. mm/dd/yyyy) as using the below code:
Textview txtViewData;
txtViewDate.setText(\"Today is \" +
android.text.format.DateFormat.getDateFormat(this).format(new Date()));
and I am having another date in format as: 2010-08-25 (i.e. yyyy/mm/dd) ,
so I want to find the difference between date in number of days, how do I find difference in days?
(In other words, I want to find the difference between CURRENT DATE - yyyy/mm/dd formatted date)
回答1:
Not really a reliable method, better of using JodaTime
Calendar thatDay = Calendar.getInstance();
thatDay.set(Calendar.DAY_OF_MONTH,25);
thatDay.set(Calendar.MONTH,7); // 0-11 so 1 less
thatDay.set(Calendar.YEAR, 1985);
Calendar today = Calendar.getInstance();
long diff = today.getTimeInMillis() - thatDay.getTimeInMillis(); //result in millis
Here\'s an approximation...
long days = diff / (24 * 60 * 60 * 1000);
To Parse the date from a string, you could use
String strThatDay = \"1985/08/25\";
SimpleDateFormat formatter = new SimpleDateFormat(\"yyyy/MM/dd\");
Date d = null;
try {
d = formatter.parse(strThatDay);//catch exception
} catch (ParseException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Calendar thatDay = Calendar.getInstance();
thatDay.setTime(d); //rest is the same....
Although, since you\'re sure of the date format...
You Could also do Integer.parseInt()
on it\'s Substrings to obtain their numeric values.
回答2:
This is NOT my work, found the answer here. did not want a broken link in the future :).
The key is this line for taking daylight setting into account, ref Full Code.
TimeZone.setDefault(TimeZone.getTimeZone(\"Europe/London\"));
or try passing TimeZone
as a parameter to daysBetween()
and call setTimeZone()
in the sDate
and eDate
objects.
So here it goes:
public static Calendar getDatePart(Date date){
Calendar cal = Calendar.getInstance(); // get calendar instance
cal.setTime(date);
cal.set(Calendar.HOUR_OF_DAY, 0); // set hour to midnight
cal.set(Calendar.MINUTE, 0); // set minute in hour
cal.set(Calendar.SECOND, 0); // set second in minute
cal.set(Calendar.MILLISECOND, 0); // set millisecond in second
return cal; // return the date part
}
getDatePart() taken from here
/**
* This method also assumes endDate >= startDate
**/
public static long daysBetween(Date startDate, Date endDate) {
Calendar sDate = getDatePart(startDate);
Calendar eDate = getDatePart(endDate);
long daysBetween = 0;
while (sDate.before(eDate)) {
sDate.add(Calendar.DAY_OF_MONTH, 1);
daysBetween++;
}
return daysBetween;
}
The Nuances:
Finding the difference between two dates isn\'t as straightforward as subtracting the two dates and dividing the result by (24 * 60 * 60 * 1000). Infact, its erroneous!
For example: The difference between the two dates 03/24/2007 and 03/25/2007 should be 1 day; However, using the above method, in the UK, you\'ll get 0 days!
See for yourself (code below). Going the milliseconds way will lead to rounding off errors and they become most evident once you have a little thing like Daylight Savings Time come into the picture.
Full Code:
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.TimeZone;
public class DateTest {
public class DateTest {
static SimpleDateFormat sdf = new SimpleDateFormat(\"dd-MMM-yyyy\");
public static void main(String[] args) {
TimeZone.setDefault(TimeZone.getTimeZone(\"Europe/London\"));
//diff between these 2 dates should be 1
Date d1 = new Date(\"01/01/2007 12:00:00\");
Date d2 = new Date(\"01/02/2007 12:00:00\");
//diff between these 2 dates should be 1
Date d3 = new Date(\"03/24/2007 12:00:00\");
Date d4 = new Date(\"03/25/2007 12:00:00\");
Calendar cal1 = Calendar.getInstance();cal1.setTime(d1);
Calendar cal2 = Calendar.getInstance();cal2.setTime(d2);
Calendar cal3 = Calendar.getInstance();cal3.setTime(d3);
Calendar cal4 = Calendar.getInstance();cal4.setTime(d4);
printOutput(\"Manual \", d1, d2, calculateDays(d1, d2));
printOutput(\"Calendar \", d1, d2, daysBetween(cal1, cal2));
System.out.println(\"---\");
printOutput(\"Manual \", d3, d4, calculateDays(d3, d4));
printOutput(\"Calendar \", d3, d4, daysBetween(cal3, cal4));
}
private static void printOutput(String type, Date d1, Date d2, long result) {
System.out.println(type+ \"- Days between: \" + sdf.format(d1)
+ \" and \" + sdf.format(d2) + \" is: \" + result);
}
/** Manual Method - YIELDS INCORRECT RESULTS - DO NOT USE**/
/* This method is used to find the no of days between the given dates */
public static long calculateDays(Date dateEarly, Date dateLater) {
return (dateLater.getTime() - dateEarly.getTime()) / (24 * 60 * 60 * 1000);
}
/** Using Calendar - THE CORRECT WAY**/
public static long daysBetween(Date startDate, Date endDate) {
...
}
OUTPUT:
Manual - Days between: 01-Jan-2007 and 02-Jan-2007 is: 1
Calendar - Days between: 01-Jan-2007 and 02-Jan-2007 is: 1
Manual - Days between: 24-Mar-2007 and 25-Mar-2007 is: 0
Calendar - Days between: 24-Mar-2007 and 25-Mar-2007 is: 1
回答3:
Most of the answers were good and right for your problem of
so i want to find the difference between date in number of days, how do i find difference in days?
I suggest this very simple and straightforward approach that is guaranteed to give you the correct difference in any time zone:
int difference=
((int)((startDate.getTime()/(24*60*60*1000))
-(int)(endDate.getTime()/(24*60*60*1000))));
And that\'s it!
回答4:
Use jodatime API
Days.daysBetween(start.toDateMidnight() , end.toDateMidnight() ).getDays()
where \'start\' and \'end\' are your DateTime objects. To parse your date Strings into DateTime objects use the parseDateTime method
There is also an android specific JodaTime library.
回答5:
This fragment accounts for daylight savings time and is O(1).
private final static long MILLISECS_PER_DAY = 24 * 60 * 60 * 1000;
private static long getDateToLong(Date date) {
return Date.UTC(date.getYear(), date.getMonth(), date.getDate(), 0, 0, 0);
}
public static int getSignedDiffInDays(Date beginDate, Date endDate) {
long beginMS = getDateToLong(beginDate);
long endMS = getDateToLong(endDate);
long diff = (endMS - beginMS) / (MILLISECS_PER_DAY);
return (int)diff;
}
public static int getUnsignedDiffInDays(Date beginDate, Date endDate) {
return Math.abs(getSignedDiffInDays(beginDate, endDate));
}
回答6:
This is Simple and best calculation for me and may be for you.
try {
/// String CurrDate= \"10/6/2013\";
/// String PrvvDate= \"10/7/2013\";
Date date1 = null;
Date date2 = null;
SimpleDateFormat df = new SimpleDateFormat(\"M/dd/yyyy\");
date1 = df.parse(CurrDate);
date2 = df.parse(PrvvDate);
long diff = Math.abs(date1.getTime() - date2.getTime());
long diffDays = diff / (24 * 60 * 60 * 1000);
System.out.println(diffDays);
} catch (Exception e1) {
System.out.println(\"exception \" + e1);
}
回答7:
The Correct Way
from Sam Quest\'s answer only works if the first date is earlier than the second. Moreover, it will return 1 if the two dates are within a single day.
This is the solution that worked best for me. Just like most other solutions, it would still show incorrect results on two days in a year because of wrong day light saving offset.
private final static long MILLISECS_PER_DAY = 24 * 60 * 60 * 1000;
long calculateDeltaInDays(Calendar a, Calendar b) {
// Optional: avoid cloning objects if it is the same day
if(a.get(Calendar.ERA) == b.get(Calendar.ERA)
&& a.get(Calendar.YEAR) == b.get(Calendar.YEAR)
&& a.get(Calendar.DAY_OF_YEAR) == b.get(Calendar.DAY_OF_YEAR)) {
return 0;
}
Calendar a2 = (Calendar) a.clone();
Calendar b2 = (Calendar) b.clone();
a2.set(Calendar.HOUR_OF_DAY, 0);
a2.set(Calendar.MINUTE, 0);
a2.set(Calendar.SECOND, 0);
a2.set(Calendar.MILLISECOND, 0);
b2.set(Calendar.HOUR_OF_DAY, 0);
b2.set(Calendar.MINUTE, 0);
b2.set(Calendar.SECOND, 0);
b2.set(Calendar.MILLISECOND, 0);
long diff = a2.getTimeInMillis() - b2.getTimeInMillis();
long days = diff / MILLISECS_PER_DAY;
return Math.abs(days);
}
回答8:
best and easiest way to do this
public int getDays(String begin) throws ParseException {
long MILLIS_PER_DAY = 24 * 60 * 60 * 1000;
SimpleDateFormat dateFormat = new SimpleDateFormat(\"dd-MM-yyyy\", Locale.ENGLISH);
long begin = dateFormat.parse(begin).getTime();
long end = new Date().getTime(); // 2nd date want to compare
long diff = (end - begin) / (MILLIS_PER_DAY);
return (int) diff;
}
回答9:
Use the following functions:
/**
* Returns the number of days between two dates. The time part of the
* days is ignored in this calculation, so 2007-01-01 13:00 and 2007-01-02 05:00
* have one day inbetween.
*/
public static long daysBetween(Date firstDate, Date secondDate) {
// We only use the date part of the given dates
long firstSeconds = truncateToDate(firstDate).getTime()/1000;
long secondSeconds = truncateToDate(secondDate).getTime()/1000;
// Just taking the difference of the millis.
// These will not be exactly multiples of 24*60*60, since there
// might be daylight saving time somewhere inbetween. However, we can
// say that by adding a half day and rounding down afterwards, we always
// get the full days.
long difference = secondSeconds-firstSeconds;
// Adding half a day
if( difference >= 0 ) {
difference += SECONDS_PER_DAY/2; // plus half a day in seconds
} else {
difference -= SECONDS_PER_DAY/2; // minus half a day in seconds
}
// Rounding down to days
difference /= SECONDS_PER_DAY;
return difference;
}
/**
* Truncates a date to the date part alone.
*/
@SuppressWarnings(\"deprecation\")
public static Date truncateToDate(Date d) {
if( d instanceof java.sql.Date ) {
return d; // java.sql.Date is already truncated to date. And raises an
// Exception if we try to set hours, minutes or seconds.
}
d = (Date)d.clone();
d.setHours(0);
d.setMinutes(0);
d.setSeconds(0);
d.setTime(((d.getTime()/1000)*1000));
return d;
}
回答10:
There\'s a simple solution, that at least for me, is the only feasible solution.
The problem is that all the answers I see being tossed around - using Joda, or Calendar, or Date, or whatever - only take the amount of milliseconds into consideration. They end up counting the number of 24-hour cycles between two dates, rather than the actual number of days. So something from Jan 1st 11pm to Jan 2nd 1am will return 0 days.
To count the actual number of days between startDate
and endDate
, simply do:
// Find the sequential day from a date, essentially resetting time to start of the day
long startDay = startDate.getTime() / 1000 / 60 / 60 / 24;
long endDay = endDate.getTime() / 1000 / 60 / 60 / 24;
// Find the difference, duh
long daysBetween = endDay - startDay;
This will return \"1\" between Jan 2nd and Jan 1st. If you need to count the end day, just add 1 to daysBetween
(I needed to do that in my code since I wanted to count the total number of days in the range).
This is somewhat similar to what Daniel has suggested but smaller code I suppose.
回答11:
All of these solutions suffer from one of two problems. Either the solution isn\'t perfectly accurate due to rounding errors, leap days and seconds, etc. or you end up looping over the number of days in between your two unknown dates.
This solution solves the first problem, and improves the second by a factor of roughly 365, better if you know what your max range is.
/**
* @param thisDate
* @param thatDate
* @param maxDays
* set to -1 to not set a max
* @returns number of days covered between thisDate and thatDate, inclusive, i.e., counting both
* thisDate and thatDate as an entire day. Will short out if the number of days exceeds
* or meets maxDays
*/
public static int daysCoveredByDates(Date thisDate, Date thatDate, int maxDays) {
//Check inputs
if (thisDate == null || thatDate == null) {
return -1;
}
//Set calendar objects
Calendar startCal = Calendar.getInstance();
Calendar endCal = Calendar.getInstance();
if (thisDate.before(thatDate)) {
startCal.setTime(thisDate);
endCal.setTime(thatDate);
}
else {
startCal.setTime(thatDate);
endCal.setTime(thisDate);
}
//Get years and dates of our times.
int startYear = startCal.get(Calendar.YEAR);
int endYear = endCal.get(Calendar.YEAR);
int startDay = startCal.get(Calendar.DAY_OF_YEAR);
int endDay = endCal.get(Calendar.DAY_OF_YEAR);
//Calculate the number of days between dates. Add up each year going by until we catch up to endDate.
while (startYear < endYear && maxDays >= 0 && endDay - startDay + 1 < maxDays) {
endDay += startCal.getActualMaximum(Calendar.DAY_OF_YEAR); //adds the number of days in the year startDate is currently in
++startYear;
startCal.set(Calendar.YEAR, startYear); //reup the year
}
int days = endDay - startDay + 1;
//Honor the maximum, if set
if (maxDays >= 0) {
days = Math.min(days, maxDays);
}
return days;
}
If you need days between dates (uninclusive of the latter date), just get rid of the + 1
when you see endDay - startDay + 1
.
回答12:
tl;dr
ChronoUnit.DAYS.between(
LocalDate.parse( \"1999-12-28\" ) ,
LocalDate.parse( \"12/31/1999\" , DateTimeFormatter.ofPattern( \"MM/dd/yyyy\" ) )
)
Details
Other answers are outdated. The old date-time classes bundled with the earliest versions of Java have proven to be poorly designed, confusing, and troublesome. Avoid them.
java.time
The Joda-Time project was highly successful as a replacement for those old classes. These classes provided the inspiration for the java.time framework built into Java 8 and later.
Much of the java.time functionality is back-ported to Java 6 & 7 in ThreeTen-Backport and further adapted to Android in ThreeTenABP.
LocalDate
The LocalDate
class represents a date-only value without time-of-day and without time zone.
Parsing strings
If your input strings are in standard ISO 8601 format, the LocalDate
class can directly parse the string.
LocalDate start = LocalDate.parse( \"1999-12-28\" );
If not in ISO 8601 format, define a formatting pattern with DateTimeFormatter
.
String input = \"12/31/1999\";
DateTimeFormatter formatter = DateTimeFormatter.ofPattern( \"MM/dd/yyyy\" );
LocalDate stop = LocalDate.parse( input , formatter );
Elapsed days via ChronoUnit
Now get a count of days elapsed between that pair of LocalDate
objects. The ChronoUnit
enum calculates elapsed time.
long totalDays = ChronoUnit.DAYS.between( start , stop ) ;
If you are unfamiliar with Java enums, know they are far more powerful and useful that conventional enums in most other programming languages. See the Enum
class doc, the Oracle Tutorial, and Wikipedia to learn more.
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 and 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 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.
回答13:
One another way:
public static int numberOfDaysBetweenDates(Calendar fromDay, Calendar toDay) {
fromDay = calendarStartOfDay(fromDay);
toDay = calendarStartOfDay(toDay);
long from = fromDay.getTimeInMillis();
long to = toDay.getTimeInMillis();
return (int) TimeUnit.MILLISECONDS.toDays(to - from);
}
回答14:
I found a very easy way to do this and it\'s what I\'m using in my app.
Let\'s say you have the dates in Time objects (or whatever, we just need the milliseconds):
Time date1 = initializeDate1(); //get the date from somewhere
Time date2 = initializeDate2(); //get the date from somewhere
long millis1 = date1.toMillis(true);
long millis2 = date2.toMillis(true);
long difference = millis2 - millis1 ;
//now get the days from the difference and that\'s it
long days = TimeUnit.MILLISECONDS.toDays(difference);
//now you can do something like
if(days == 7)
{
//do whatever when there\'s a week of difference
}
if(days >= 30)
{
//do whatever when it\'s been a month or more
}
回答15:
Joda-Time
Best way is to use Joda-Time, the highly successful open-source library you would add to your project.
String date1 = \"2015-11-11\";
String date2 = \"2013-11-11\";
DateTimeFormatter formatter = new DateTimeFormat.forPattern(\"yyyy-MM-dd\");
DateTime d1 = formatter.parseDateTime(date1);
DateTime d2 = formatter.parseDateTime(date2);
long diffInMillis = d2.getMillis() - d1.getMillis();
Duration duration = new Duration(d1, d2);
int days = duration.getStandardDays();
int hours = duration.getStandardHours();
int minutes = duration.getStandardMinutes();
If you\'re using Android Studio, very easy to add joda-time. In your build.gradle (app):
dependencies {
compile \'joda-time:joda-time:2.4\'
compile \'joda-time:joda-time:2.4\'
compile \'joda-time:joda-time:2.2\'
}
回答16:
Date userDob = new SimpleDateFormat(\"yyyy-MM-dd\").parse(dob);
Date today = new Date();
long diff = today.getTime() - userDob.getTime();
int numOfDays = (int) (diff / (1000 * 60 * 60 * 24));
int hours = (int) (diff / (1000 * 60 * 60));
int minutes = (int) (diff / (1000 * 60));
int seconds = (int) (diff / (1000));
回答17:
use these functions
public static int getDateDifference(int previousYear, int previousMonthOfYear, int previousDayOfMonth, int nextYear, int nextMonthOfYear, int nextDayOfMonth, int differenceToCount){
// int differenceToCount = can be any of the following
// Calendar.MILLISECOND;
// Calendar.SECOND;
// Calendar.MINUTE;
// Calendar.HOUR;
// Calendar.DAY_OF_MONTH;
// Calendar.MONTH;
// Calendar.YEAR;
// Calendar.----
Calendar previousDate = Calendar.getInstance();
previousDate.set(Calendar.DAY_OF_MONTH, previousDayOfMonth);
// month is zero indexed so month should be minus 1
previousDate.set(Calendar.MONTH, previousMonthOfYear);
previousDate.set(Calendar.YEAR, previousYear);
Calendar nextDate = Calendar.getInstance();
nextDate.set(Calendar.DAY_OF_MONTH, previousDayOfMonth);
// month is zero indexed so month should be minus 1
nextDate.set(Calendar.MONTH, previousMonthOfYear);
nextDate.set(Calendar.YEAR, previousYear);
return getDateDifference(previousDate,nextDate,differenceToCount);
}
public static int getDateDifference(Calendar previousDate,Calendar nextDate,int differenceToCount){
// int differenceToCount = can be any of the following
// Calendar.MILLISECOND;
// Calendar.SECOND;
// Calendar.MINUTE;
// Calendar.HOUR;
// Calendar.DAY_OF_MONTH;
// Calendar.MONTH;
// Calendar.YEAR;
// Calendar.----
//raise an exception if previous is greater than nextdate.
if(previousDate.compareTo(nextDate)>0){
throw new RuntimeException(\"Previous Date is later than Nextdate\");
}
int difference=0;
while(previousDate.compareTo(nextDate)<=0){
difference++;
previousDate.add(differenceToCount,1);
}
return difference;
}