ZonedDateTime 到早期 Android 中 Java 8 之前的日期

Man*_* Wa 9 java android date zoneddatetime

我正在尝试替换该ZonedDateTime.toInstant方法,因为它仅在适用于 Android 的 API 26 之后可用。
但是我的应用程序应该支持 API 19。
我想将 ZonedDateTime 转换为 Date 以便我可以执行以下操作:

final Calendar calendar = Calendar.getInstance();
calendar.setTime(new Date());
final long millis = calendar.getTimeInMillis();
Run Code Online (Sandbox Code Playgroud)

我想实现如下:
我想计算当前日期和另一个日期之间的差异,以秒、分钟、小时为单位,......最高可能的单位获胜,所以我会得到例如5 days ago结果。

Bas*_*que 9

tl;博士

对于 26之前的 Android,使用ThreeTen-ABP库。

避免遗留的日期时间类

旧的日期时间课程,例如CalendarDate可怕的,真的,可怕的可悲的课程。它们充满了糟糕的设计决策和黑客,由不了解日期时间处理的人构建。避开它们。随着 JSR 310 的采用,它们完全被java.time类所取代——实际上,有很多原因。

避免这些遗留类。仅使用java.time类。

ThreeTen-Backport

对于 Java 6 和 Java 7,大部分java.time功能都在ThreeTen-Backport项目中向后移植。

三十-ABP

ThreeTen-ABP项目中,该后向移植进一步适用于早期的 Android (<26) 。

我敦促您将此库添加到您的项目中,这样您就可以避免使用悲剧性的遗留类。

转换

如果您需要与尚未更新为java.time 的旧代码进行交互,请在旧代码和现代代码之间来回转换。

在 Java 8 及更高版本中,通过调用在旧类上找到的 newto…from…方法进行转换。

在后向端口中,使用to…org.threeten.bp.DateTimeUtils类中找到的转换方法进行转换。

已用时间

您的问题涉及计算经过时间。

要计算年、月和日,请使用Period

要计算天数(与日历无关的 24 小时时间块)、小时、分钟、秒和小数秒,请使用Duration.

搜索堆栈溢出以获取更多信息。这些类已经介绍了很多次。


关于java.time

java.time框架是建立在Java 8和更高版本。这些类取代了麻烦的旧的遗留日期时间类,例如java.util.Date, Calendar, & SimpleDateFormat

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

现在处于维护模式Joda-Time项目建议迁移到java.time类。

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

从哪里获得 java.time 类?

在此处输入图片说明


Rom*_*ppa 9

您只需通过以下 gradle 配置即可启用“支持较新的 Java 语言 API”:

<!-- Copyright 2019 Google LLC.
SPDX-License-Identifier: Apache-2.0 -->

android {
  defaultConfig {
    //Only required when setting minSdkVersion to 20 or lower
    multiDexEnabled true
  }

  compileOptions {
    // Flag to enable support for the new language APIs
    coreLibraryDesugaringEnabled true
    // Sets Java compatibility to Java 8
    sourceCompatibility JavaVersion.VERSION_1_8
    targetCompatibility JavaVersion.VERSION_1_8
  }
}

dependencies {
  // Dependency with the implementation code for the APIs
  coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:1.0.5'
}
Run Code Online (Sandbox Code Playgroud)

来源:https ://medium.com/androiddevelopers/support-for-newer-java-language-apis-bca79fc8ef65


Man*_* Wa 1

解决方案(ThreeTen-Backport 库):
它工作得很好,我已经在 KitKat 模拟器上尝试过了。

private static final ChronoUnit[] chronoUnits = {ChronoUnit.YEARS, ChronoUnit.MONTHS, ChronoUnit.DAYS, ChronoUnit.HOURS, ChronoUnit.MINUTES, ChronoUnit.SECONDS};
private static final Map<ChronoUnit, Integer> chronoUnitPluralIdMap = new HashMap<ChronoUnit, Integer>() {{
    put(ChronoUnit.YEARS, R.plurals.chrono_unit_years_ago);
    put(ChronoUnit.MONTHS, R.plurals.chrono_unit_months_ago);
    put(ChronoUnit.DAYS, R.plurals.chrono_unit_days_ago);
    put(ChronoUnit.HOURS, R.plurals.chrono_unit_hours_ago);
    put(ChronoUnit.MINUTES, R.plurals.chrono_unit_minutes_ago);
    put(ChronoUnit.SECONDS, R.plurals.chrono_unit_seconds_ago);
}};

public static String getTimeStringUntilNowFromUTC(Context context, String utcDate) {
    Instant now = Instant.now(Clock.systemUTC());
    Instant then = Instant.parse(utcDate);
    for (ChronoUnit chronoUnit : chronoUnits) {
        if (then.isSupported(chronoUnit)) {
            long units = chronoUnit.between(then, now);
            if (units > 0) {
                //noinspection ConstantConditions
                return context.getResources().getQuantityString(chronoUnitPluralIdMap.get(chronoUnit), (int)units, (int)units);
            }
        }
    }
    return "-";
}

public static String getTimeBetweenTwoDates(Context context, String date1, String date2) {
    Instant date1Instant = Instant.parse(date1);
    Instant date2Instant = Instant.parse(date2);
    final long seconds = ChronoUnit.SECONDS.between(date1Instant, date2Instant);
    return getMinutesSecondsString(context, seconds);
}
Run Code Online (Sandbox Code Playgroud)