【问题标题】:Remaining days to a date is not showing correctly日期的剩余天数未正确显示
【发布时间】:2018-09-12 22:19:04
【问题描述】:

好的,所以我创建了一个函数来显示距离未来某个日期的天数...在天数超过 9 天之前它是正确的.. 如果超过它似乎显示一个随机数天...请在下面查看我的代码:

   public String daysTillExpire() {
        String daysLeft = "";
        int position = 0 ;
        String inputDateString = UIDM.get(position).date;
        Calendar calCurr = Calendar.getInstance();
        Calendar day = Calendar.getInstance();


        try {
            day.setTime(new SimpleDateFormat("dd-MM-yyyy").parse(inputDateString));

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

            if (day.after(calCurr)) {

                String noumberOfDays = "Days left: " + (day.get(Calendar.DAY_OF_MONTH) - (calCurr.get(Calendar.DAY_OF_MONTH)));

                daysLeft = UIDM.get(position).date + "\n(" + noumberOfDays+")" ;

            }

            else if (day.before(calCurr)) {
                daysLeft = "Key Expired";
            return daysLeft; }
        return daysLeft;
    }

UIDM 是一个包含信息的数据模型...String inputDateString = UIDM.get(position).date; 返回值01-10-2018 23:59

【问题讨论】:

  • 什么是“UIDM”?
  • UIDM 是一个包含信息的数据模型... 'String inputDateString = UIDM.get(position).date;返回值为 '01-10-2018 23:59'
  • 顺便考虑一下扔掉长期过时且臭名昭著的麻烦SimpleDateFormat和朋友,并将ThreeTenABP添加到您的Android项目中,以便使用java.time,现代Java日期和时间API .使用起来感觉好多了。
  • 好的,谢谢推荐,我去研究一下,
  • 仅供参考,java.util.Datejava.util.Calendarjava.text.SimpleDateFormat 等麻烦的旧日期时间类现在已被 java.time 类所取代。大多数 java.time 功能在 ThreeTen-Backport 项目中被反向移植到 Java 6 和 Java 7。在ThreeTenABP 项目中进一步适用于早期的Android。见How to use ThreeTenABP…

标签: android date java-time date-difference android-date


【解决方案1】:

java.time

java.time 是现代 Java 日期和时间 API,具有计算两个日期之间的天数的方法。所以不要费心自己做这个计算。这很容易出错。

    DateTimeFormatter dateFormatter = DateTimeFormatter.ofPattern("dd-MM-uuuu H:mm");
    String inputDateString = "01-10-2018 23:59";
    LocalDate today = LocalDate.now(ZoneId.of("Pacific/Auckland"));
    LocalDate expiration = LocalDate.parse(inputDateString, dateFormatter);
    if (expiration.isAfter(today)) {
        String numberOfDays = "Days left: " + ChronoUnit.DAYS.between(today, expiration);
        System.out.println(numberOfDays);
    }

刚刚运行这个 sn-p(已经在新西兰 9 月 13 日)我得到了这个输出:

剩余天数:18

如果不是太平洋/奥克兰,请替换正确的时区。

LaVepe 的回答已经很好且正确地解释了你的代码出了什么问题,所以我不再重复了。

您使用的日期和时间类 — CalendarSimpleDateFormat — 早已过时,而且设计总是很糟糕。有一种方法可以让Calendar 计算天数,一次计算 1 天,但它不太适合。 SimpleDateFormat 因其给许多程序员带来的麻烦而臭名昭著。我建议您完全避免使用这些类并改用 java.time。

问题:我可以在 Android 上使用 java.time 吗?

是的,java.time 在较旧和较新的 Android 设备上运行良好。它只需要至少 Java 6

  • 在 Java 8 及更高版本以及更新的 Android 设备上(据我所知,从 API 级别 26 开始),现代 API 是内置的。
  • 在 Java 6 和 7 中,获取 ThreeTen Backport,即新类的后向端口(对于 JSR 310,ThreeTen;请参阅底部的链接)。
  • 在(较旧的)Android 上使用 ThreeTen Backport 的 Android 版本。它被称为 ThreeTenABP。并确保从 org.threeten.bp 导入日期和时间类以及子包。

链接

【讨论】:

    【解决方案2】:

    请注意,Calendar.DAY_OF_MONTH 返回的日期介于 1 和 31 之间

    所以它会计算两天(1到31之间的数字)之间的差异,就好像它们在同一个月一样

    我建议宁愿使用时间戳,然后将结果从毫秒转换为天数,如下所示:

    long oneDay = 24 * 60 * 60 * 1000;  // in milliseconds
    long diff = day.getTime().getTime() - calCurr.getTime().getTime();
    long numberOfDays = diff / oneDay;
    

    然后您可以将其更改为 StringLong.toString(numberOfDays)

    【讨论】:

    • 完美运行...非常感谢您解释 Calendar.DAY_OF_MONTH 的工作原理 - 非常感谢。
    • 很好的解释。您建议的解决方案是低级的。我更喜欢使用库方法来计算差异。
    • 此答案不正确。天总是 24 小时。它们可以是 23、23.5、24、25 或许多其他小时数。
    • @BasilBourque 是对的。如果您以冬季日期和夏季日期之间的天数为单位测量增量,那么建议的代码将失效。
    【解决方案3】:

    试试这个方法

    /**
             *  
             * @param token
             * @param date1 present date
             * @param date2 future date 
             * @return diff
             */
            public float dateDiff(String token,Date date1,Date date2){
    
                float diff=0;
                //different date might have different offset
                Calendar cal1=Calendar.getInstance(); 
                Calendar cal2=Calendar.getInstance();
                cal1.setTime(date1);          
                long ldate1 = date1.getTime() + cal1.get(Calendar.ZONE_OFFSET) + cal1.get(Calendar.DST_OFFSET);
    
                if(date2==null)
                    cal2.setTime(new Date());
                else
                    cal2.setTime(date2);
                long ldate2 = date2.getTime() + cal2.get(Calendar.ZONE_OFFSET) + cal2.get(Calendar.DST_OFFSET);
    
                // Use integer calculation, truncate the decimals
                int hr1   = (int)(ldate1/3600000); //60*60*1000
                int hr2   = (int)(ldate2/3600000);
    
                int days1 = hr1/24;
                int days2 = hr2/24;
                int dateDiff  = days2 - days1;
                int yearDiff  = cal2.get(Calendar.YEAR) - cal1.get(Calendar.YEAR); 
                float monthDiff = yearDiff * 12 + cal2.get(Calendar.MONTH) - cal1.get(Calendar.MONTH);
                System.out.println("monthDiff 1" +monthDiff);
                System.out.println(" days:  ;;;;222  "+dateDiff);
                float fbm = dateDiff ; 
    
                fbm = (float) MasterLibraryFunction.doubRound(fbm /30,2) ;
    
                    if(token.equals("d"))
                {
                    diff=dateDiff;
                    System.out.println(" days:  ;;;;  "+dateDiff);
                }
                else if(token.equals("m"))
                {
                    //diff= monthDiff;
                    diff =fbm;
                    System.out.println(" diff ---------->:  ;;;;  "+fbm);
    
                }
    
        /*******day wise diff *******/      
    
    
                return diff;
            }
    
    
    
    /**
         * @category Decimal point round
         * @param  val
         * @param  places
         * @return Rounded Value to given place
         */
        public static double doubRound(double val, int places) {
            long factor = (long)Math.pow(10,places);
            val = val * factor;
            long tmp = Math.round(val);
            return (double)tmp / factor;
        }
    

    【讨论】:

      【解决方案4】:

      要获得两天之间的间隔天数,您可以这样做:

      public long daysTillExpire() {
      
          SimpleDateFormat sdf = new SimpleDateFormat("dd-MM-yyyy");
          String dateInString = "01-10-2018 23:59";
          Date date = null;
          try {
              date = sdf.parse(dateInString);
          } catch (ParseException e) {
              e.printStackTrace();
          }
      
          Calendar expiredCalendar = Calendar.getInstance();
          expiredCalendar.setTime(date);
      
          long msDiff = expiredCalendar.getTimeInMillis() - Calendar.getInstance().getTimeInMillis();
          long daysDiff = TimeUnit.MILLISECONDS.toDays(msDiff); 
      
          return daysDiff;
      }
      

      以上功能测试成功,根据您的需求修改。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2010-11-13
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多