java Android 中的 TimeZone 和 TimeUnit 以及 SimpleDateFormat

java TimeZone and TimeUnit and SimpleDateFormat in Android

https://gist.github.com/anonymous/e14bbbb89dd8636f1237c73dc8878b3f

我在这段代码中遇到了一个错误,它导致最后一个 switch 语句(第 298 - 307 行)return 为当天的默认值和第二天的 case 0,当我的模拟器时区设置为 GMT+0 线的另一侧,而不是数据集的来源。 (即北京等亚洲地区的系统时间和亚特兰大等东部时区的数据集)

我如何更新它以考虑其他时区的系统检查从 GMT+0 线另一侧的区域提供的数据?

如果您相信 JVM 的时区设置反映了用户的时区,那么这里是获取该时区中从今天到指定日期的天数的现代且正确的方法:

private static String getDayName(Context context, long dateInMillis) {
    ZoneId zone = ZoneId.systemDefault();
    LocalDate providedDate = Instant.ofEpochMilli(dateInMillis)
            .atZone(zone)
            .toLocalDate();
    LocalDate today = LocalDate.now(zone);

    int daysAfterToday = (int) ChronoUnit.DAYS.between(today, providedDate);

    switch (daysAfterToday) {
        case 0:
            return context.getString(R.string.today);
        case 1:
            return context.getString(R.string.tomorrow );

        default:
            return providedDate.getDayOfWeek()
                        .getDisplayName(TextStyle.FULL, 
                                        Locale.getDefault(Locale.Category.FORMAT));
    }
}

我说“如果您相信 JVM 的时区设置反映了用户的时区”,因为时区设置可能会被程序的其他部分或同一 JVM 中的其他程序 运行 更改。如果你更了解用户的时区,你当然应该运用你的知识,例如:

    ZoneId zone = ZoneId.of("America/Cordoba");

我更愿意插入一个检查 daysAfterToday 是区间 0 到 6。在从 long 转换为 int 之前。

我正在使用并热烈推荐 java.time,现代 Java 日期和时间 API。它比过时的 TimeZone class 和您使用的臭名昭著的麻烦 SimpleDateFormat 要好得多。

问题:我的 API 等级可以使用 java.time 吗?

是的,java.time 在新旧 Android 设备上都能很好地工作。

  • 在 Java 8 和更高版本以及新的 Android 设备上(据我所知,来自 API 26 级)新的 API 出现 built-in.
  • 在 Java 6 和 7 中获取 ThreeTen Backport,新的 classes 的 backport(ThreeTen 用于 JSR 310,其中首次描述了现代 API)。
  • 在(较旧的)Android 上,使用 ThreeTen Backport 的 Android 版本。它叫做 ThreeTenABP。确保从包 org.threeten.bp 和子包中导入日期和时间 classes。

链接