是否有更好的方法将日历日期归零?

时间:2018-03-19 01:12:38

标签: java android date calendar

我正在寻找一种更好的方法来获得与以下代码相同的结果:

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 个答案:

答案 0 :(得分:2)

执行此操作的正确方法是使用java.time.LocalDate类。它只存储日期而不是时间,它有一个now()静态方法,它返回当天。

LocalDate today = LocalDate.now();

如果您正在查看Android,则会在API级别26添加,但是还有其他方法可以在Android中使用“新样式”日期类,例如ThreeTen-Backport库。

答案 1 :(得分:0)

编辑:感谢Basil和Kareem,我已经更新了以下代码(所以,更容易):

添加到gradle.build:

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

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

答案 2 :(得分:0)

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)。
  • 并且不要使用麻烦的旧遗留类,例如CalendarDateSimpleDateFormat,因为它们现在已被 java.time 类取代
  

两个日期之间的天数差异

首先将旧版Calendar对象转换为现代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.time

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

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

要了解详情,请参阅Oracle Tutorial。并搜索Stack Overflow以获取许多示例和解释。规范是JSR 310

您可以直接与数据库交换 java.time 对象。使用符合JDBC driver或更高版本的JDBC 4.2。不需要字符串,不需要java.sql.*类。

从哪里获取java.time类?

ThreeTen-Extra项目使用其他类扩展java.time。该项目是未来可能添加到java.time的试验场。您可以在此处找到一些有用的课程,例如IntervalYearWeekYearQuartermore