从 java.util.Date 获取月份数的快速方法

Fast way to get month number from java.util.Date

我的 Android 应用程序中有一个 recyclerview 有很多日期。为了对数据进行排序并在按月+年分组的项目之间插入分隔符,我使用以下函数:

private fun monthFromDate(date: Date): Int {
    val calendar = Calendar.getInstance()
    calendar.time = date
    return calendar.get(Calendar.MONTH)
}

private fun yearFromDate(date: Date): Int {
    val calendar = Calendar.getInstance()
    calendar.time = date
    return calendar.get(Calendar.YEAR)
}

我认为总是调用 Calendar.getInstance() 是个坏主意。我也不想引入局部变量。 (顺便说一下,date.month date.year 等所有方法都被 弃用

问题: 我有两个 util.java.Date 个实例。如果月份和年份都相等,则让它们相等。我怎样才能以快速和最佳的方式实现这种乐趣?

Date.getMonth() 虽然弃用也很好。 Java 保持向后兼容性。

如果使用 Java 8,您可以对 Calendar.getInstance().get(Calendar.MONTH) 版本与新 LocalDate.ofEpochDay(new Date().getTime()).getMonthValue()

版本进行一些基准测试

不是很清楚,为什么 Calendar.getInstance() 是次优的。但是,根据您的要求,像这样编码如何:

private fun getYearMonth(date: Date): Int {
    val calendar = Calendar.getInstance()
    calendar.time = date
    return calendar.get(Calendar.YEAR) * 100 + calendar.get(Calendar.MONTH) 
}

让您可以访问单个整数中的 yearMonth,例如 201711

java.time

already mentioned Java 8 as an option. Even on Android Java 7 I believe it’s worth considering using JSR-310, the modern Java date and time API also known as java.time 完成您的任务。它与 Java 8 一起出现,但你也可以使用它。它通常更好用。它包括一个 class YearMonth 来表示年和月,正是您所需要的,这使您无需使用两个函数并为这两个方法调用中的每一个实例化一个 Calendar 对象.所以我想向您展示进行这种转换的正确方法。

很抱歉我不会写Kotlin代码。您将不得不使用 Java 代码,我相信您会适应。 Java代码是:

private ZoneId zone = ZoneId.of("Europe/Moscow");

private YearMonth yearMonthFromDate(Date date) {
    ZonedDateTime dateTime = date.toInstant().atZone(zone);
    return YearMonth.from(dateTime);
}

如果您不想要,请输入您想要的时区 Europe/Moscow。

现在你已经到了,如果你沿着这条路走下去,你可能还想考虑你是否想要 Date 对象在你的应用程序中,或者你更喜欢来自 JSR 的 classes -310。 DateCalendar class 被认为早已过时。

性能

在我的 Mac 我 运行 100 000 Date 个对象上通过上述方法在 37 毫秒内完成。它在一般的 Android 设备上可能不一样,但我不相信你需要担心转换的速度有多快。一般的经验法则是,在您在现实环境中看到问题之前,您不应该担心它。如果不确定,请尽早在真实环境中进行测试。

用于 Android

要在 Android 上使用 JSR-310,您需要有 ThreeTenABP(ABP for Android backport)。 .

中对这一切进行了非常详尽的解释