用于查找年,月和日中2个日期对象之间差异的Java方法

我有一个开始日期和结束日期。 两个日期之间的持续时间应为年,月和日。 我是java的新手。 当我运行以下方法时,我获得的是0年,12个月1天。 请建议一种替代方案,以获得年,月和日的准确差异。

import java.sql.Date; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.*; public class Duration { private String getAssignmentDuration(java.util.Date oldDate, java.util.Date newDate) { Calendar c1 = Calendar.getInstance(); Calendar c2 = Calendar.getInstance(); if (oldDate.compareTo(newDate) > 0) { c1.setTime(newDate); c2.setTime(oldDate); } else { System.out.println("invalid"); return "Invalid selection"; } int year = 0; int month = 0; int days = 0; boolean doneMonth = false; boolean doneYears = false; while (c1.before(c2)) { //log.debug("Still in Loop"); if (!doneYears) { c1.add(Calendar.YEAR, 1); year++; } if (c1.after(c2) || doneYears) { if (!doneYears) { doneYears = true; year--; c1.add(Calendar.YEAR, -1); } if (!doneMonth) { c1.add(Calendar.MONTH, 1); month++; } if (c1.after(c2) || doneMonth) { if (!doneMonth) { doneMonth = true; month--; c1.add(Calendar.MONTH, -1); } c1.add(Calendar.DATE, 1); days++; if (c1.after(c2)) { days--; } // this will not be executed if (days == 31 || month==12) { break; } } } } System.out.println(year + " years, " + month + " months, " + days + " days"); return year + " years, " + month + " months, " + days + " days"; } public static void main(String[] args) { Duration d1= new Duration(); SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd"); java.util.Date oldDate = null; try { oldDate = sdf.parse("2012/08/29"); } catch (ParseException e) { // TODO Auto-generated catch block e.printStackTrace(); } java.util.Date newDate = null; try { newDate = sdf.parse("2013/08/31"); } catch (ParseException e) { // TODO Auto-generated catch block e.printStackTrace(); } d1.getAssignmentDuration(oldDate, newDate); } } 

  public static String getDateDifferenceInDDMMYYYY(Date from, Date to) { Calendar fromDate=Calendar.getInstance(); Calendar toDate=Calendar.getInstance(); fromDate.setTime(from); toDate.setTime(to); int increment = 0; int year,month,day; System.out.println(fromDate.getActualMaximum(Calendar.DAY_OF_MONTH)); if (fromDate.get(Calendar.DAY_OF_MONTH) > toDate.get(Calendar.DAY_OF_MONTH)) { increment =fromDate.getActualMaximum(Calendar.DAY_OF_MONTH); } System.out.println("increment"+increment); // DAY CALCULATION if (increment != 0) { day = (toDate.get(Calendar.DAY_OF_MONTH) + increment) - fromDate.get(Calendar.DAY_OF_MONTH); increment = 1; } else { day = toDate.get(Calendar.DAY_OF_MONTH) - fromDate.get(Calendar.DAY_OF_MONTH); } // MONTH CALCULATION if ((fromDate.get(Calendar.MONTH) + increment) > toDate.get(Calendar.MONTH)) { month = (toDate.get(Calendar.MONTH) + 12) - (fromDate.get(Calendar.MONTH) + increment); increment = 1; } else { month = (toDate.get(Calendar.MONTH)) - (fromDate.get(Calendar.MONTH) + increment); increment = 0; } // YEAR CALCULATION year = toDate.get(Calendar.YEAR) - (fromDate.get(Calendar.YEAR) + increment); return year+"\tYears\t\t"+month+"\tMonths\t\t"+day+"\tDays"; } public static void main(String[] args) { Calendar calendar = Calendar.getInstance(); calendar.set(1999,01,8); /* Calendar calendar1 = Calendar.getInstance(); calendar1.set(2012,01,23);*/ System.out.println(getDateDifferenceInDDMMYYYY(calendar.getTime(),new Date())); } 

假设您有Date date1, date2并且它们被初始化为date1>date2

 long diff = date1.getTime() - date2.getTime(); //this is going to give you the difference in milliseconds Date result = new Date(diff); Format frmt = new SimpleDateFormat("yy MM dd HH:mm:ss"); return frmt.format(result).toString();//or if you want system.out.println(...); 

Joda Time有一个可以使用的时间间隔概念,例如:

 Interval interval = new Interval(oldDate.getTime(), newDate.getTime()); 

然后使用Period对象,如:

 Period period = interval.toPeriod().normalizedStandard(PeriodType.yearMonthDay()); PeriodFormatter formatter = new PeriodFormatterBuilder() .appendYears() .appendSuffix(" year ", " years ") .appendSeparator(" and ") .appendMonths() .appendSuffix(" month ", " months ") .appendSeparator(" and ") .appendDays() .appendSuffix(" day ", " days ") .toFormatter(); System.out.println(formatter.print(period)); 

您可以轻松地在数年和数月内打印您的差异。

可能你在发布问题时改变了一些东西,因为要修复你的代码(注意我没有测试你的代码是否适用于所有类型的范围),你只需要正确初始化Calendar对象并反转无效的选择检查:

 Calendar c1 = Calendar.getInstance(); Calendar c2 = Calendar.getInstance(); if (oldDate.compareTo(newDate) < 0) { c2.setTime(newDate); c1.setTime(oldDate); } else { System.out.println("invalid"); return "Invalid selection"; } 
  long diff = today.getTimeInMillis() - birth.getTimeInMillis(); // Calculate difference in seconds long Seconds = diff / 1000; // Calculate difference in minutes long Minutes = diff / (60 * 1000); // Calculate difference in hours long Hours = diff / (60 * 60 * 1000); // Calculate difference in days long Days = diff / (24 * 60 * 60 * 1000); long Months = diff / (24 * 60 * 60 * 12 * 1000); //lblTsec, lblTmint, lblthours,lblTdays; System.out.println("Seconds : " + Seconds + ""); System.out.println("Minutes : " + Minutes + ""); System.out.println("Hours : " + Hours + ""); System.out.println("Days : " + Days + ""); 
 public static long[] differenceBetweenDates(Date fromDate, Date toDate) { Calendar startDate = Calendar.getInstance(); startDate.setTime(fromDate); long years = 0; long months = 0; long days = 0; Calendar endDate = Calendar.getInstance(); endDate.setTime(toDate); Calendar tmpdate = Calendar.getInstance(); tmpdate.setTime(startDate.getTime()); tmpdate.add(Calendar.YEAR, 1); while (tmpdate.compareTo(endDate) <= 0) { startDate.add(Calendar.YEAR, 1); tmpdate.add(Calendar.YEAR, 1); years++; } tmpdate.setTime(startDate.getTime()); tmpdate.add(Calendar.MONTH, 1); while (tmpdate.compareTo(endDate) <= 0) { startDate.add(Calendar.MONTH, 1); tmpdate.add(Calendar.MONTH, 1); months++; } tmpdate.setTime(startDate.getTime()); tmpdate.add(Calendar.DATE, 1); while (tmpdate.compareTo(endDate) <= 0) { startDate.add(Calendar.DATE, 1); tmpdate.add(Calendar.DATE, 1); days++; } return new long[]{days, months, years}; } 

TL;博士

 Period.between( LocalDate.of( 2017 , Month.JANUARY , 23 ) , LocalDate.of( 2017 , Month.MARCH , 27 ) ) 

呼叫:

 .getYears() .getMonths() .getDays() 

避免遗留日期时间类

您正在使用麻烦的旧日期时间类,现在是旧的,取而代之的是java.time类。

使用java.time

LocalDate类表示没有时间且没有时区的仅日期值。

时区对于确定日期至关重要。 对于任何给定的时刻,日期在全球范围内因地区而异。 例如, 法国巴黎午夜过后几分钟,在魁北克蒙特利尔的 “昨天”仍然是新的一天。

continent/region的格式指定适当的时区名称 ,例如America/MontrealAfrica/CasablancaPacific/Auckland 。 切勿使用3-4字母缩写,例如ESTIST因为它们不是真正的时区,不是标准化的,甚至不是唯一的(!)。

 ZoneId z = ZoneId.of( "America/Montreal" ); LocalDate today = LocalDate.now( z ); 

today.toString():2017-05-05

对于我们的示例,我们创建另一个LocalDate

 LocalDate earlier = today.minusMonths( 2 ).minusWeeks( 3 ).minusDays( 2 ) ; 

early.toString():2017-02-10

要以年 – 月 – 日的粒度表示未附加到时间轴的时间跨度,请使用Period类。

 Period p = Period.between( earlier , today ) ; int years = p.getYears(); int months = p.getMonths(); int days = p.getDays(); 

请参阅IdeOne.com上的此代码 。

ISO 8601

ISO 8601标准定义了日期时间值的文本表示的格式。 对于年 – 月 – 天的持续时间,模式为PnYnMnDTnHnMnS ,其中P标记开头, T将年 – 月 – 日部分与小时 – 分 – 秒部分分开。

解析/生成字符串时,java.time类在默认情况下使用标准格式。 Period类在其toString方法中生成此特定模式。

 String output = p.toString() ; 

p.toString():P2M25D