如何正确计算2个日期之间的实际月数?

我遵循方法getDiffDateMap计算2个日期之间的差异,并返回分别代表毫秒,秒,分钟,小时,天,月和年的整数Map

 public static Map getDiffDateMap(String dateA, String dateB) { Calendar cal = Calendar.getInstance(); Map out = new LinkedHashMap(); long timeInMillA = 0; long timeInMillB = 0; SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); Date convertedDateA; Date convertedDateB; try { convertedDateA = dateFormat.parse(dateA); cal.setTime(convertedDateA); timeInMillA = cal.getTimeInMillis(); convertedDateB = dateFormat.parse(dateB); cal.setTime(convertedDateB); timeInMillB = cal.getTimeInMillis(); } catch (ParseException e) { e.printStackTrace(); } long mili = timeInMillB - timeInMillA; long sec = mili/1000; long min = sec/60; long hour = min/60; long day = hour/24; long week = day/7; long month = day/31; // ???? long year = month/12; out.put(7, mili + ""); out.put(6, sec + ""); out.put(5, min + ""); out.put(4, hour + ""); out.put(3, day + ""); out.put(2, week + ""); out.put(1, month + ""); out.put(0, year + ""); return out; } 

我的问题是从实际日数计算月份:

 long month = day/31; // or 30 

例如:

 Map out = getDiffInMillsec("2012-9-01 20:9:01", "2012-10-01 20:10:01"); System.out.println(Arrays.asList(out)); 

我得到输出: [{7=2592060000, 6=2592060, 5=43201, 4=720, 3=30, 2=4, 1=0, 0=0}]其中1是月计数和它的0.因为差异只有30天。 我需要添加什么流才能解决这个问题? 有什么建议么?

我遵循方法getDiffDateMap计算2个日期之间的差异,并返回分别代表毫秒,秒,分钟,小时,天,月和年的整数映射。

不要重新发明轮子:)

Joda Time有代码可以完成所有这些以及更多。 例如:

 LocalDateTime start = ...; LocalDateTime end = ...; Period difference = new Period(start, end, PeriodType.yearMonthDayTime()); int months = difference.getMonths(); // etc 

请注意,当您将差异转换为毫秒数时,您无法达到月数 – 因为月数将取决于开始/结束日期。 (30天可能是也可能不是一个月,例如…)

我强烈建议您在整个Java代码中使用Joda Time,而不是java.util.* 。 它是一个更好的API,并且希望很少 – 如果你需要编写自己的日期/时间处理代码。

我建议使用JodaTime#Months

它具有如下function:

  static Months monthsBetween(ReadableInstant start, ReadableInstant end) 

创建一个月份,表示两个指定日期时间之间的整月数。

  static Months monthsBetween(ReadablePartial start, ReadablePartial end) 

创建一个月份,表示两个指定的部分日期时间之间的整月数。

我只想在Jon Skeet的帮助下总结我们之前谈过的所有内容,这里是一个答案,我使用了JodaTimenew Period JodaTime date值:

 import org.joda.time.LocalDateTime; import org.joda.time.Period; import org.joda.time.PeriodType; .... public static Map getDateTimeDiffMap(String dateA, String dateB) { Calendar cal = Calendar.getInstance(); Map out = new LinkedHashMap(); long timeInMillA = 0; long timeInMillB = 0; SimpleDateFormat dateFormat = new SimpleDateFormat(DATE_FORMAT); Date convertedDateA; Date convertedDateB; try { convertedDateA = dateFormat.parse(dateA); cal.setTime(convertedDateA); timeInMillA = cal.getTimeInMillis(); convertedDateB = dateFormat.parse(dateB); cal.setTime(convertedDateB); timeInMillB = cal.getTimeInMillis(); } catch (ParseException e) { e.printStackTrace(); } LocalDateTime startA = new LocalDateTime(timeInMillA); LocalDateTime startB = new LocalDateTime(timeInMillB); Period difference = new Period(startA, startB, PeriodType.days()); int day = difference.getDays(); difference = new Period(startA, startB, PeriodType.months()); int month = difference.getMonths(); difference = new Period(startA, startB, PeriodType.years()); int year = difference.getYears(); difference = new Period(startA, startB, PeriodType.weeks()); int week = difference.getWeeks(); difference = new Period(startA, startB, PeriodType.hours()); int hour = difference.getHours(); difference = new Period(startA, startB, PeriodType.minutes()); long min = difference.getMinutes(); difference = new Period(startA, startB, PeriodType.seconds()); long sec = difference.getSeconds(); //difference = new Period(startA, startB, PeriodType.millis()); long mili = timeInMillB - timeInMillA; out.put(7, mili + ""); out.put(6, sec + ""); out.put(5, min + ""); out.put(4, hour + ""); out.put(3, day + ""); out.put(2, week + ""); out.put(1, month + ""); out.put(0, year + ""); return out; } 

例如,对于“01-09-2012 20:9:01”,“01-10-2012 20:9:01”,我得到输出:

 year=0; month = 1; day=30; hour=720; ... 
  try { String user = request.getParameter("uname"); out.println(user); String pass = request.getParameter("pass"); out.println(pass); java.sql.Date sqlDate = new java.sql.Date(new java.util.Date().getTime()); Class.forName( "com.mysql.jdbc.Driver" ); Connection conn = DriverManager.getConnection( "jdbc:mysql://localhost:3306/trans","root","root" ) ; Statement st = conn.createStatement(); String sql = "insert into purch (cd,cust,dateof) values('" + user + "','" + pass + "', '" + sqlDate + "')"; st.executeUpdate(sql); Date date = new Date(); String modifiedDate= new SimpleDateFormat("-MM-").format(date); String dd = modifiedDate.toString(); String da = "ai"; out.println(dd); PreparedStatement statement = conn.prepareStatement("select * from purch where dateof LIKE ? and cd = ?"); statement.setString(1,"%" + dd + "%"); statement.setString(2,"" + da + ""); ResultSet rs = statement.executeQuery(); if(rs != null) { while(rs.next()) { out.println(rs.getString("cd")); out.println(rs.getString("cust")); out.println(rs.getString("dateof")); } } }catch(Exception e) { System.out.println(e.toString()); }