【问题标题】:unable to get difference of days between two dates in java无法在java中获得两个日期之间的天数
【发布时间】:2012-01-13 06:45:04
【问题描述】:

我想计算两个日期之间的天数差。当日期的年份没有改变时,我的代码工作正常,但是当我计算两个日期之间的差异时:(13/01/2012 到 13/12/2011),它给出了一个负值。当我计算今天日期和未来日期之间的差异时,它也会给出错误的差异值。请帮我。先感谢您。这是我的代码:

//getting values from text box
String fromtext = from.getText().toString();
String totext = to.getText().toString();
//sdf if a simple date formatter
SimpleDateFormat sdf = new SimpleDateFormat("MM/dd/yyyy");
Date fromdate = (Date) sdf.parse(fromtext);
Date todate = (Date) sdf.parse(totext);

Calendar fromcal = Calendar.getInstance();
Calendar tocal = Calendar.getInstance();


    fromcal.setTime(fromdate);
    tocal.setTime(todate);// setting to date


    int reportDays=(int)(todate.getTime()-fromdate.getTime())/(3600*24*1000);

请告诉我计算天数差异的最佳方法是什么。

【问题讨论】:

标签: java date calendar days


【解决方案1】:

日期输入:13/01/2012, 13/12/2011

格式似乎是dd/MM/yyyy,而您使用了错误的格式(即MM/dd/yyyy

【讨论】:

  • 对不起,输入错误。但是每当我给出正确的格式时,它都会返回负值.......
【解决方案2】:

tl;博士

ChronoUnit.DAYS.between(
    LocalDate.parse( "13/01/2012" , DateTimeFormatter.ofPattern( "dd/MM/uuuu" ) ) ,
    LocalDate.parse( "13/12/2011" , DateTimeFormatter.ofPattern( "dd/MM/uuuu" ) )
)

使用 java.time

现代 java.time 类取代了麻烦的旧日期时间类,例如 DateCalendar,变得更加容易。

(13/01/2012 to 13/12/2011),

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

DateTimeFormatter f = DateTimeFormatter.ofPattern( "dd/MM/uuuu" );
LocalDate start = LocalDate.parse( "13/01/2012" , f );
LocalDate stop = LocalDate.parse( "13/12/2011" , f );

使用ChronoUnit 计算经过的天数。

long days = ChronoUnit.DAYS.between( start , stop );

当然,当时间回到过去时,天数是负数。请注意您的停止日期如何早于您的开始日期。

时区对于确定日期至关重要。对于任何给定的时刻,日期在全球范围内因区域而异。例如,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 );

您可以再次使用ChronoUnit 来计算未来的天数。

long days = ChronoUnit.DAYS.between( today , today.plusMonths( 7 ) );

关于java.time

java.time 框架内置于 Java 8 及更高版本中。这些类取代了麻烦的旧 legacy 日期时间类,例如 java.util.DateCalendarSimpleDateFormat

Joda-Time 项目现在位于maintenance mode,建议迁移到java.time 类。

要了解更多信息,请参阅Oracle Tutorial。并在 Stack Overflow 上搜索许多示例和解释。规格为JSR 310

从哪里获得 java.time 类?

ThreeTen-Extra 项目通过附加类扩展了 java.time。该项目是未来可能添加到 java.time 的试验场。您可以在这里找到一些有用的类,例如IntervalYearWeekYearQuartermore

【讨论】:

    【解决方案3】:

    除了已经提到的格式问题之外,您可能还会遇到溢出。 试试这个:

    int reportDays=(int)((todate.getTime()-fromdate.getTime())/(3600*24*1000));
    

    【讨论】:

    • 正是我做错了什么。现在工作正常。非常感谢......:)
    【解决方案4】:

    【讨论】:

      【解决方案5】:

      使用 joda time 是最简单的方法。

      【讨论】:

        【解决方案6】:

        检查此代码:

        import java.util.Calendar;
        
        public class DateDifferent{  
          public static void main(String[] args){
          Calendar calendar1 = Calendar.getInstance();
          Calendar calendar2 = Calendar.getInstance();
          calendar1.set(2007, 01, 10);
          calendar2.set(2007, 07, 01);
          long milliseconds1 = calendar1.getTimeInMillis();
          long milliseconds2 = calendar2.getTimeInMillis();
          long diff = milliseconds2 - milliseconds1;
          long diffSeconds = diff / 1000;
          long diffMinutes = diff / (60 * 1000);
          long diffHours = diff / (60 * 60 * 1000);
          long diffDays = diff / (24 * 60 * 60 * 1000);
          System.out.println("\nThe Date Different Example");
          System.out.println("Time in milliseconds: " + diff + " milliseconds.");
          System.out.println("Time in seconds: " + diffSeconds + " seconds.");
          System.out.println("Time in minutes: " + diffMinutes + " minutes.");
          System.out.println("Time in hours: " + diffHours + " hours.");
          System.out.println("Time in days: " + diffDays + " days.");
          }
        }
        

        【讨论】:

          【解决方案7】:

          这是我为此目的编写的一个简单的小类:

          import java.text.DateFormat;
          import java.text.ParseException;
          import java.text.SimpleDateFormat;
          import java.util.Date;
          
          public class DifferenceInDays
          {
              public int dateOffset(String incomingDate) throws ParseException
              {
                  // parse dates
                  DateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
                  Date date = (Date) formatter.parse(incomingDate);
          
                  // convert to milliseconds
                  long millisecs = date.getTime();
          
                  // convert to days
                  int offsetInDays = (int) Math.abs(millisecs / (1000 * 60 * 60 * 24));
                  return offsetInDays;
              }
          }
          

          它使用绝对值方法处理负偏移量。

          【讨论】:

            【解决方案8】:

            如果您在具有夏令时的语言环境中尝试此操作,并且开始日期和结束日期在夏令时更改之前和之后,则结果可能会相差 1 天。这是因为DateCalendar 使用时区。

            如果您只打算处理 1900 年到 2100 年之间的日期,可以通过一个简单的计算来计算自 1900 年以来的天数:

            public static int daysSince1900(Date date) {
                Calendar c = new GregorianCalendar();
                c.setTime(date);
            
                int year = c.get(Calendar.YEAR);
                if (year < 1900 || year > 2099) {
                    throw new IllegalArgumentException("daysSince1900 - Date must be between 1900 and 2099");
                }
                year -= 1900;
                int month = c.get(Calendar.MONTH) + 1;
                int days = c.get(Calendar.DAY_OF_MONTH);
            
                if (month < 3) {
                    month += 12;
                    year--;
                }
                int yearDays = (int) (year * 365.25);
                int monthDays = (int) ((month + 1) * 30.61);
            
                return (yearDays + monthDays + days - 63);
            }
            

            因此,要获得两个日期之间的天数差异,您需要计算它们自 1900 年以来的天数并计算差异。我们的 daysBetween 方法如下所示:

            public static Integer getDaysBetween(Date date1, Date date2) {
                if (date1 == null || date2 == null) {
                    return null;
                }
            
                int days1 = daysSince1900(date1);
                int days2 = daysSince1900(date2);
            
                if (days1 < days2) {
                    return days2 - days1;
                } else {
                    return days1 - days2;
                }
            }
            

            不要问我这个计算是从哪里来的,因为我们从 90 年代初就开始使用它。

            【讨论】:

              【解决方案9】:

              我会这样做!

              package javaapplication2;
              //@author Ibrahim Yesilay
              import java.text.ParseException;
              import java.text.SimpleDateFormat;
              import java.util.Date;
              import java.util.Scanner;
              public class JavaApplication2 {  
              
              
                  public static void main(String[] args) throws ParseException {
              
              
              
                  Scanner scan = new Scanner(System.in);        
                      System.out.println("First dates Day :");
                      int d = scan.nextInt();
                      System.out.println("First dates Mounth :");
                      int m = scan.nextInt();
                      System.out.println("First dates Year :");
                      int y = scan.nextInt();
                      String date;
                      date = Integer.toString(d) + "/" + Integer.toString(m) + "/" + Integer.toString(y);  
                      SimpleDateFormat dateFormat = new SimpleDateFormat("dd/MM/yyyy");
                      Date firstdate = null;
                      firstdate = dateFormat.parse(date);
                      System.out.println(dateFormat.format(firstdate)); 
              
                      System.out.println("Second dates Day :");
                      d = scan.nextInt();
                      System.out.println("Second dates Month :");
                      m = scan.nextInt();
                      System.out.println("Second dates Year :");
                      y = scan.nextInt();
                      date = Integer.toString(d) + "/" + Integer.toString(m) + "/" + Integer.toString(y);  
                      Date seconddate = null;
                      seconddate = dateFormat.parse(date);
                      System.out.println(dateFormat.format(seconddate)); 
              
                      if (seconddate.getTime() > firstdate.getTime()) {
                          long sonuc = (long)(seconddate.getTime()- firstdate.getTime())/(3600*24*1000);
                          System.out.println("" + sonuc);
                      } else if (firstdate.getTime() > seconddate.getTime()) {
                          long sonuc = (long)(firstdate.getTime()- seconddate.getTime())/(3600*24*1000);
                          System.out.println("" + sonuc);
                      } else {
                          System.out.println("The dates are equal!");
                      }
              
                  }   
              }
              

              【讨论】:

              • 这些糟糕的日期时间类在几年前被 JSR 310 采用后的 java.time 类所取代。建议在 2019 年使用它们是糟糕的建议。
              • 永远不要像这样手动计算日期和时间。它太复杂了,并不总是能给出正确的结果。改为使用经过验证的库类。也不要使用SimpleDateFormatDate。这些课程设计不佳且早已过时。而是使用来自java.time, the modern Java date and time APILocalDateDateTimeFormatter
              猜你喜欢
              • 1970-01-01
              • 2014-10-07
              • 1970-01-01
              • 1970-01-01
              • 2022-12-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多