【问题标题】:Java method to find difference between 2 date objects in years, months and daysJava方法来查找年,月和日2个日期对象之间的差异
【发布时间】:2012-10-26 09:52:38
【问题描述】:

我有一个开始日期和结束日期。两个日期之间的持续时间应采用年、月和日的形式。我是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);
    }

}

【问题讨论】:

标签: java


【解决方案1】:
 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()));
    }

【讨论】:

  • 添加解释会很好。
  • 不错的答案。它给出了年、月和日的差异,说明了天何时超过一个月边界,或月份何时超过一年边界。如果您想说“X 将在 1 年 2 个月 19 天后到期”,这很有用
  • 感谢这节省了我的时间。来自我的 +1。
【解决方案2】:

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

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";
}

【讨论】:

  • 非常感谢。有没有办法在不使用 joda 或毫秒方法的情况下获得持续时间?在某些语言环境中,毫秒可能无法提供准确的持续时间。因此我不想使用它。您能否对我用来提供准确持续时间的代码进行修改。
  • @user1776304 如果需要在指定的区域设置中执行转换,可以使用:Interval(long startInstant, long endInstant, DateTimeZone zone)。我建议您应该使用 joda 方法来修复您的代码,请参阅我更新的答案。
  • 即使修复后输出也是 o 年、12 个月、1 天。请帮忙。谢谢。
  • @Vidya 可能,您运行的代码与发布的代码不同,因为我刚刚测试并且正在打印:1 年,0 个月,2 天
  • 是的,抱歉,我正在调试一个不同的代码,其中 oldDate 是 2012/08/31,newDate 是 2013/08/29。持续时间显示错误。天数有所不同。
【解决方案3】:

tl;博士

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

呼叫:

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

避免使用旧的日期时间类

您正在使用麻烦的旧日期时间类,现在是遗留的,被 java.time 类所取代。

使用 java.time

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

时区对于确定日期至关重要。对于任何给定的时刻,日期在全球范围内因区域而异。例如,Paris France 中午夜过后几分钟是新的一天,而 Montréal Québec 中仍然是“昨天”。

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

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

tod​​ay.toString(): 2017-05-05

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

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

earlier.toString(): 2017-02-10

要以年-月-日为粒度表示与时间轴无关的时间跨度,请使用 Period 类。

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

this code run live at IdeOne.com

ISO 8601

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

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

String output = p.toString() ;

p.toString(): P2M25D

【讨论】:

    【解决方案4】:

    假设您有Date date1, date2,并且它们在date1&gt;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(...);
    

    【讨论】:

    • 我认为在代码行 3 中,您的意思是 new Date(diff) 而不是 new Date(time)... 但您的答案似乎是正确的... +1
    • 嗯,不错的答案,但getTime() 方法以毫秒而不是秒为单位返回时间。
    • 我对此表示赞成,并在我的应用程序中使用,但必须从结果年份中减去 1970,因为 getTime() 给出了 Unix 时间,即自 1970 年 1 月 1 日开始以来的毫秒数,如果我没记错的话
    【解决方案5】:
        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 + "");
    

    【讨论】:

      【解决方案6】:
      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};
      }
      

      【讨论】:

      • 你能解释一下解决方案吗?
      • 功能会给你岁差。即年+月+日=差异
      • 函数将为您提供年份、月份和日期之和的日期之间的差异。即年+月+日=差异
      【解决方案7】:

      你可以简单地计算两个日期之间的差异毫秒并除以秒、分钟、小时、天和月

      假设你想获得年份之间的差异,试试这个,

      public int findDiff(Date fromDate, Date toDate) {
      
          if(fromDate == null || toDate == null) {
              return -1;
          }
      
          long diff = toDate.getTime() - fromDate.getTime();
      
          int diffInYears = (int) (diff / (60 * 60 * 1000 * 24 * 30.41666666 * 12));
          return diffInYears;
      }
      

      假设您希望月份之间的差异从分隔符中删除 12(表示月份)。同样你可以得到天,小时,分钟..

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2014-04-07
        • 1970-01-01
        • 1970-01-01
        • 2022-10-02
        • 2014-08-07
        • 2021-03-11
        • 1970-01-01
        • 2013-07-17
        相关资源
        最近更新 更多