代码之家  ›  专栏  ›  技术社区  ›  Bridger Burt

有没有更好的方法来消除日历日期?

  •  1
  • Bridger Burt  · 技术社区  · 7 年前

    我想看看是否有更好的方法可以获得与以下代码相同的结果:

    Calendar date = Calendar.getInstance();
    date.setTimeInMillis(System.currentTimeMillis());
    date.set(Calendar.HOUR_OF_DAY, 0);
    date.set(Calendar.MINUTE, 0);
    date.set(Calendar.SECOND, 0);
    date.set(Calendar.MILLISECOND, 0);
    

    我用这个来比较两个日期之间的天数差异。我目前正在为目标API 24编写代码,对使用Joda Time完成如此简单的任务不感兴趣。

    我提出了以下函数,但我很想知道是否有一种更简单的方法,也许是内置的,可以将日期归零,或者是一种完全不同的方法来计算两个日期之间的天数。

    private long getFlatDateInMillis() {
        Calendar currentDate = Calendar.getInstance();
        currentDate.setTimeInMillis(System.currentTimeMillis());
        currentDate.set(Calendar.HOUR_OF_DAY, 0);
        currentDate.set(Calendar.MINUTE, 0);
        currentDate.set(Calendar.SECOND, 0);
        currentDate.set(Calendar.MILLISECOND, 0);
    
        return currentDate.getTimeInMillis();
    }
    

    这样,我可以快速使用:

    Calendar date = getFlatDateInMillis();
    

    我只是想确保我没有遗漏任何更简单、已经预定义的内容。

    非常感谢。

    3 回复  |  直到 7 年前
        1
  •  2
  •   Basil Bourque    7 年前

    正确的方法是使用 java.time.LocalDate 班它只存储日期,不存储时间,并且 now() 静态方法,返回当前日期。

    LocalDate today = LocalDate.now();
    

    如果你看的是Android,这是在API级别26添加的,但是还有其他方法可以在Android中使用“新样式”日期类,例如 ThreeTen-Backport 图书馆

        2
  •  0
  •   Basil Bourque    7 年前

    tl;博士

    ChronoUnit.DAYS.between(                    // Calculate elapsed time between a pair of `LocalDate` date-only objects. Returns a total number of elapsed days.
        ( (GregorianCalendar) myJavaUtilCal )   // Cast your legacy `java.util.Calendar` object to the subclass `java.util.GregorianCalendar`, also legacy. 
            .toZonedDateTime()                  // Convert from legacy `GregorianCalendar` to modern `ZonedDateTime` class.
            .toLocalDate()  ,                   // Extract the date-only value, a `LocalDate`, lacking time-of-day and lacking time zone.
        otherLocalDate                          // Compare to some other `LocalDate` object.
    )                                           // Returns a `long` number of days. Uses Half-Open approach where the beginning is *inclusive* while the ending is *exclusive*. 
    

    详细信息

    这个 Answer by Kareem 是正确的。这里还有一些想法。

    有没有更好的方法来消除日历日期?

    是的,有一个更好的方法:不要。

    • 试图清除日期+时间类型上的时间是错误的方法;改为使用仅日期类型( LocalDate )。
    • 不要使用麻烦的旧遗留类,例如 Calendar ,则, Date ,则, SimpleDateFormat 因为它们现在被 Java语言时间 课程。

    两个日期之间的天数差

    首先转换您的旧版 日历 反对现代主义 ZonedDateTime 班要转换,请调用添加到旧类的新方法。

    GregorianCalendar myGregCal = (GregorianCalendar) myJavaUtilCal ; // Cast from superclass to subclass. 
    ZonedDateTime zdt = myGregCal.toZonedDateTime() ; // Convert from legacy class to modern class.
    

    提取仅日期值。

    LocalDate ld = zdt.toLocalDate() ;  // Extract date-only object from date-time object.
    

    以天为单位计算运行时间

    long days = ChronoUnit.DAYS.between( ld , otherLd ) ;
    

    或将经过的时间表示为 Period

    Period p = Period.between( ld , otherLd ) ;
    

    关于 Java语言时间

    这个 java.time 框架内置于Java 8及更高版本中。这些课程取代了烦人的旧课程 legacy 日期时间类,如 java.util.Date ,则, Calendar ,& SimpleDateFormat

    这个 Joda-Time 项目,现在处于 maintenance mode ,建议迁移到 java.time 课程。

    要了解更多信息,请参阅 Oracle Tutorial 。并搜索堆栈溢出以获得许多示例和解释。规格为 JSR 310

    您可以交换 Java语言时间 对象直接与数据库连接。使用 JDBC driver 符合 JDBC 4.2 或更高版本。不需要字符串,不需要 java.sql.* 课程。

    从何处获取java。时间课程?

    这个 ThreeTen-Extra project扩展了java。额外上课的时间。该项目是java未来可能添加内容的试验场。时间您可以在这里找到一些有用的类,例如 Interval ,则, YearWeek ,则, YearQuarter more

        3
  •  0
  •   Bridger Burt    7 年前

    编辑: 多亏了Basil和Kareem,我更新了以下代码(因此,更简单):

    添加到gradle。构建:

    compile 'com.jakewharton.threetenabp:threetenabp:1.0.5'
    

    然后,在我的活动中,等等,

    AndroidThreeTen.init(this);
    
    LocalDate today = LocalDate.now();
    LocalDate anotherDay = LocalDate.of(2019, 3, 25);
    long dayDifference = ChronoUnit.DAYS.between(today, anotherDay); //dayDifference = 365
    

    值得注意的是,日历引用的月份从0索引开始,而LocalDate引用的月份从1索引开始。