用Java计算两个日期之间的天数

我想要一个Java程序来计算两个日期之间的天数。

  1. 输入第一个日期(德语表示法;有空格:"dd mm yyyy")
  2. 输入第二个日期。
  3. 程序应该计算两个日期之间的天数。

我怎样才能把闰年和夏天时包括进来呢?

我的代码:

import java.util.Calendar;
import java.util.Date;
import java.util.Scanner;


public class NewDateDifference {


public static void main(String[] args) {


System.out.print("Insert first date: ");
Scanner s = new Scanner(System.in);
String[] eingabe1 = new String[3];


while (s.hasNext()) {
int i = 0;
insert1[i] = s.next();
if (!s.hasNext()) {
s.close();
break;
}
i++;
}


System.out.print("Insert second date: ");
Scanner t = new Scanner(System.in);
String[] insert2 = new String[3];


while (t.hasNext()) {
int i = 0;
insert2[i] = t.next();
if (!t.hasNext()) {
t.close();
break;
}
i++;
}


Calendar cal = Calendar.getInstance();


cal.set(Calendar.DAY_OF_MONTH, Integer.parseInt(insert1[0]));
cal.set(Calendar.MONTH, Integer.parseInt(insert1[1]));
cal.set(Calendar.YEAR, Integer.parseInt(insert1[2]));
Date firstDate = cal.getTime();


cal.set(Calendar.DAY_OF_MONTH, Integer.parseInt(insert2[0]));
cal.set(Calendar.MONTH, Integer.parseInt(insert2[1]));
cal.set(Calendar.YEAR, Integer.parseInt(insert2[2]));
Date secondDate = cal.getTime();




long diff = secondDate.getTime() - firstDate.getTime();


System.out.println ("Days: " + diff / 1000 / 60 / 60 / 24);
}
}
704415 次浏览

更新: 2013年的原始答案现在已经过时了,因为一些类已经被替换了。新的方法是使用新的java.time类。

DateTimeFormatter dtf = DateTimeFormatter.ofPattern("dd MM yyyy");
String inputString1 = "23 01 1997";
String inputString2 = "27 04 1997";


try {
LocalDateTime date1 = LocalDate.parse(inputString1, dtf);
LocalDateTime date2 = LocalDate.parse(inputString2, dtf);
long daysBetween = Duration.between(date1, date2).toDays();
System.out.println ("Days: " + daysBetween);
} catch (ParseException e) {
e.printStackTrace();
}

注意,这个解决方案给出的是实际的24小时天数,而不是日历天数。对于后者,请使用

long daysBetween = ChronoUnit.DAYS.between(date1, date2)

原来的答案 (Java 8过时)

您正在使用字符串进行一些不必要的转换。有一个SimpleDateFormat类用于它-试试这个:

SimpleDateFormat myFormat = new SimpleDateFormat("dd MM yyyy");
String inputString1 = "23 01 1997";
String inputString2 = "27 04 1997";


try {
Date date1 = myFormat.parse(inputString1);
Date date2 = myFormat.parse(inputString2);
long diff = date2.getTime() - date1.getTime();
System.out.println ("Days: " + TimeUnit.DAYS.convert(diff, TimeUnit.MILLISECONDS));
} catch (ParseException e) {
e.printStackTrace();
}

编辑:因为有一些关于这段代码正确性的讨论:它确实照顾到了闰年。然而,TimeUnit.DAYS.convert函数会失去精度,因为毫秒被转换为天(更多信息请参阅链接文档)。如果这是一个问题,diff也可以手动转换:

float days = (diff / (1000*60*60*24));

注意,这是一个float值,不一定是int

当我运行你的程序时,它甚至没有得到我 直到我可以输入第二个日期。

这样更简单,更不容易出错。

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.text.SimpleDateFormat;
import java.util.Date;


public class Test001 {


public static void main(String[] args) throws Exception {


BufferedReader br = null;


br = new BufferedReader(new InputStreamReader(System.in));
SimpleDateFormat sdf = new SimpleDateFormat("dd MM yyyy");


System.out.println("Insert first date : ");
Date dt1 = sdf.parse(br.readLine().trim());


System.out.println("Insert second date : ");
Date dt2 = sdf.parse(br.readLine().trim());


long diff = dt2.getTime() - dt1.getTime();


System.out.println("Days: " + diff / 1000L / 60L / 60L / 24L);


if (br != null) {
br.close();
}
}
}

Java日期库是出了名的坏。我建议使用Joda的时间。它会为你照顾闰年、时区等。

最小工作示例:

import java.util.Scanner;
import org.joda.time.DateTime;
import org.joda.time.Days;
import org.joda.time.LocalDate;
import org.joda.time.format.DateTimeFormat;
import org.joda.time.format.DateTimeFormatter;


public class DateTestCase {


public static void main(String[] args) {


System.out.print("Insert first date: ");
Scanner s = new Scanner(System.in);
String firstdate = s.nextLine();
System.out.print("Insert second date: ");
String seconddate = s.nextLine();


// Formatter
DateTimeFormatter dateStringFormat = DateTimeFormat
.forPattern("dd MM yyyy");
DateTime firstTime = dateStringFormat.parseDateTime(firstdate);
DateTime secondTime = dateStringFormat.parseDateTime(seconddate);
int days = Days.daysBetween(new LocalDate(firstTime),
new LocalDate(secondTime)).getDays();
System.out.println("Days between the two dates " + days);
}
}

使用:

public int getDifferenceDays(Date d1, Date d2) {
int daysdiff = 0;
long diff = d2.getTime() - d1.getTime();
long diffDays = diff / (24 * 60 * 60 * 1000) + 1;
daysdiff = (int) diffDays;
return daysdiff;
}
String dateStart = "01/14/2015 08:29:58";
String dateStop = "01/15/2015 11:31:48";


//HH converts hour in 24 hours format (0-23), day calculation
SimpleDateFormat format = new SimpleDateFormat("MM/dd/yyyy HH:mm:ss");


Date d1 = null;
Date d2 = null;


d1 = format.parse(dateStart);
d2 = format.parse(dateStop);


//in milliseconds
long diff = d2.getTime() - d1.getTime();


long diffSeconds = diff / 1000 % 60;
long diffMinutes = diff / (60 * 1000) % 60;
long diffHours = diff / (60 * 60 * 1000) % 24;
long diffDays = diff / (24 * 60 * 60 * 1000);


System.out.print(diffDays + " days, ");
System.out.print(diffHours + " hours, ");
System.out.print(diffMinutes + " minutes, ");
System.out.print(diffSeconds + " seconds.");

当夏令时到来时,大多数/所有答案都给我们带来了问题。下面是我们针对所有日期的工作解决方案,不使用JodaTime。它利用日历对象:

public static int daysBetween(Calendar day1, Calendar day2){
Calendar dayOne = (Calendar) day1.clone(),
dayTwo = (Calendar) day2.clone();


if (dayOne.get(Calendar.YEAR) == dayTwo.get(Calendar.YEAR)) {
return Math.abs(dayOne.get(Calendar.DAY_OF_YEAR) - dayTwo.get(Calendar.DAY_OF_YEAR));
} else {
if (dayTwo.get(Calendar.YEAR) > dayOne.get(Calendar.YEAR)) {
//swap them
Calendar temp = dayOne;
dayOne = dayTwo;
dayTwo = temp;
}
int extraDays = 0;


int dayOneOriginalYearDays = dayOne.get(Calendar.DAY_OF_YEAR);


while (dayOne.get(Calendar.YEAR) > dayTwo.get(Calendar.YEAR)) {
dayOne.add(Calendar.YEAR, -1);
// getActualMaximum() important for leap years
extraDays += dayOne.getActualMaximum(Calendar.DAY_OF_YEAR);
}


return extraDays - dayTwo.get(Calendar.DAY_OF_YEAR) + dayOneOriginalYearDays ;
}
}
// date format, it will be like "2015-01-01"
private static final String DATE_FORMAT = "yyyy-MM-dd";


// convert a string to java.util.Date
public static Date convertStringToJavaDate(String date)
throws ParseException {
DateFormat dataFormat = new SimpleDateFormat(DATE_FORMAT);
return dataFormat.parse(date);
}


// plus days to a date
public static Date plusJavaDays(Date date, int days) {
// convert to jata-time
DateTime fromDate = new DateTime(date);
DateTime toDate = fromDate.plusDays(days);
// convert back to java.util.Date
return toDate.toDate();
}


// return a list of dates between the fromDate and toDate
public static List<Date> getDatesBetween(Date fromDate, Date toDate) {
List<Date> dates = new ArrayList<Date>(0);
Date date = fromDate;
while (date.before(toDate) || date.equals(toDate)) {
dates.add(date);
date = plusJavaDays(date, 1);
}
return dates;
}

在Java 8中,你可以通过使用LocalDateDateTimeFormatter来实现这一点。从LocalDateJavadoc中:

LocalDate是一个表示日期的不可变日期时间对象, 通常被视为年-月-日

该模式可以使用DateTimeFormatter来构造。下面是Javadoc,以及我使用的相关模式字符:

象征 -含义- 演讲 -示例

y -年代- 一年 - 2004;04

M / L -月-年- 数字/文本 - 7;07年;7月; 7月;J < / p >

d -日-月- 数量 - 10

下面是例子:

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.time.temporal.ChronoUnit;


public class Java8DateExample {
public static void main(String[] args) throws IOException {
final DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd MM yyyy");
final BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
final String firstInput = reader.readLine();
final String secondInput = reader.readLine();
final LocalDate firstDate = LocalDate.parse(firstInput, formatter);
final LocalDate secondDate = LocalDate.parse(secondInput, formatter);
final long days = ChronoUnit.DAYS.between(firstDate, secondDate);
System.out.println("Days between: " + days);
}
}

最近的输入/输出示例:

23 01 1997
27 04 1997
Days between: 94

最近的第一个:

27 04 1997
23 01 1997
Days between: -94

你可以用更简单的方法来做:

public static long betweenDates(Date firstDate, Date secondDate) throws IOException
{
return ChronoUnit.DAYS.between(firstDate.toInstant(), secondDate.toInstant());
}

最简单的方法:

public static long getDifferenceDays(Date d1, Date d2) {
long diff = d2.getTime() - d1.getTime();
return TimeUnit.DAYS.convert(diff, TimeUnit.MILLISECONDS);
}

最好的方法,它转换为一个字符串作为奖励;)

protected void onCreate(Bundle savedInstanceState) {


super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
try {
//Dates to compare
String CurrentDate=  "09/24/2015";
String FinalDate=  "09/26/2015";


Date date1;
Date date2;


SimpleDateFormat dates = new SimpleDateFormat("MM/dd/yyyy");


//Setting dates
date1 = dates.parse(CurrentDate);
date2 = dates.parse(FinalDate);


//Comparing dates
long difference = Math.abs(date1.getTime() - date2.getTime());
long differenceDates = difference / (24 * 60 * 60 * 1000);


//Convert long to String
String dayDifference = Long.toString(differenceDates);


Log.e("HERE","HERE: " + dayDifference);
}
catch (Exception exception) {
Log.e("DIDN'T WORK", "exception " + exception);
}
}

我们可以利用LocalDate和ChronoUnit java库,下面的代码工作正常。 Date格式为yyyy-MM-dd,

import java.time.LocalDate;
import java.time.temporal.ChronoUnit;
import java.util.*;
class Solution {
public int daysBetweenDates(String date1, String date2) {
LocalDate dt1 = LocalDate.parse(date1);
LocalDate dt2= LocalDate.parse(date2);


long diffDays = ChronoUnit.DAYS.between(dt1, dt2);


return Math.abs((int)diffDays);
}
}
public class TestCode {


public static void main(String[] args) {
String date1 = "23-04-2021";
String date2 = "24-05-2021";
System.out.println("NDays: " + nDays_Between_Dates(date1, date2));
}
    

public static int nDays_Between_Dates(String date1, String date2) {
int diffDays = 0;
try {
SimpleDateFormat dates = new SimpleDateFormat("dd-MM-yyyy");
Date startDate = dates.parse(date1);
Date endDate = dates.parse(date2);
long diff = endDate.getTime() - startDate.getTime();
diffDays = (int) (diff / (24 * 60 * 60 * 1000));
} catch (ParseException e) {
e.printStackTrace();
}
return Math.abs(diffDays);
}
}

输出:NDays: 31

想要得到只是天(没有时间),你可以使用ChronoUnit

ChronoUnit.DAYS.between(date1.toLocalDate(), date2.toLocalDate());

下面的方法非常适合我:

public int daysBetween(LocalDate later, LocalDate before) {
SimpleDateFormat myFormat = new SimpleDateFormat("dd MM yyyy");
int daysBetween = 0;
try {
Date dateBefore = myFormat.parse(localDateToString(before));
Date dateAfter = myFormat.parse(localDateToString(later));
long difference = dateAfter.getTime() - dateBefore.getTime();
daysBetween = (int) (difference / (1000 * 60 * 60 * 24));
} catch (Exception e) {
e.printStackTrace();
}
return daysBetween;
}


public String localDateToString(LocalDate date) {
DateTimeFormatter myFormat = DateTimeFormatter.ofPattern("dd MM yyyy");
return date.format(myFormat).toString();
}

我在用这个。

              try {
Date dateBefore = myFormat.parse(02-03-2022);
Date dateAfter = myFormat.parse(27-02-2022);
long difference = dateAfter.getTime() - dateBefore.getTime();
float daysBetween = (difference / (1000*60*60*24));
int count = Math.round(daysBetween);
Log.e("DateCount", "onClick: DateCount_Float: "+daysBetween );
Log.e("DateCount", "onClick: DateCount_Int: "+count);


} catch (Exception e) {
e.printStackTrace();
}

日志输出:

DateCount: onClick: DateCount_Float: 3.0

DateCount: onClick: DateCount_INT: 3