为什么 Calendar.getTimeInMillis() returns 是负值?

Why does Calendar.getTimeInMillis() returns negative value?

我正在读取文本视图的日期,我想知道凌晨 00:00 的 unix 时间。

与 API 23.

一起工作

以下是我实现它的方法:

String sDate = mainBinding.tvTakeTimeCurrentShownDateDateFormat.getText().toString();
      Calendar actuallDate = Calendar.getInstance();

    Log.d(TAG, "oc_bt_TakeTime_lastDate: " + sDate.substring(6,8)+ " " + Integer.parseInt(sDate.substring(6,8)));
    Log.d(TAG, "oc_bt_TakeTime_lastDate: "+ sDate.substring(3,5) + " " + Integer.parseInt(sDate.substring(3,5)));
    Log.d(TAG, "oc_bt_TakeTime_lastDate: " + sDate.substring(0,2) + " " + Integer.parseInt(sDate.substring(0,2)));

      actuallDate.clear();
      actuallDate.set(Integer.parseInt(sDate.substring(6,8)), (Integer.parseInt(sDate.substring(3,5))-1), Integer.parseInt(sDate.substring(0,2)), 0, 0 ,0);

    Log.d(TAG, "oc_bt_TakeTime_lastDate: " + actuallDate.get(Calendar.DAY_OF_MONTH)+actuallDate.get(Calendar.MONTH)+actuallDate.get(Calendar.YEAR));

    Log.d(TAG, "oc_bt_TakeTime_lastDate: " + String.valueOf(actuallDate.getTimeInMillis()));

我将其转换为 long,因为我认为转换为 int 可能会产生溢出。

结果:

oc_bt_TakeTime_lastDate: 19 19
oc_bt_TakeTime_lastDate: 08 8
oc_bt_TakeTime_lastDate: 24 24
oc_bt_TakeTime_lastDate: 24719
oc_bt_TakeTime_lastDate: -61547472000000

正如您在倒数第二个显示屏上看到的那样,您设置的是 0019 年,而不是 2019 年。由于 getTimeInMillis 是根据纪元时间(1970 年 1 月 1 日)设置的,您会得到一个负数。

我会建议此解决方法:

  1. 使用当前时间戳创建日期对象
  2. 使用该对象设置您的日历对象

    日期 d = 新日期(timestampLong);
    日历实际日期 = Calendar.getInstance();
    actuallDate.setTime(d);

你把事情搞得太复杂了。

java.time 和 ThreeTenABP

我无法从你的问题中准确地读出你的字符串的样子。对于这个答案,我假设 24.08.19。如果您无法根据您的真实字符串调整答案,请在评论中回复。

    DateTimeFormatter dateFormatter = DateTimeFormatter.ofPattern("dd.MM.uu");
    String sDate = "24.08.19";
    LocalDate actualDate = LocalDate.parse(sDate, dateFormatter);
    System.out.println("Actual date: " + actualDate);
    long epochMilli = actualDate.atStartOfDay(ZoneId.systemDefault())
            .toInstant()
            .toEpochMilli();
    System.out.println("Milliseconds since the epoch: " + epochMilli);

我的计算机在 Europe/Copenhagen 时区的输出是:

Actual date: 2019-08-24
Milliseconds since the epoch: 1566597600000

您尝试使用的 Calendar class 设计不佳且早已过时。你不应该使用它。对于日期,使用 java.time 中的 LocalDate,现代 Java 日期和时间 API。

不要像以前那样手动解析字符串。 DateTimeFormatter class 已为此目的而内置,因此请将工作留给它。这也可以让您更好地验证字符串。格式模式字符串中的 uuyy 会将像 19 这样的两位数年份解析为 2000 到 2099 之间的年份。

你的代码出了什么问题?

jmart 是正确的:您将年份设置为公历 19 年。那是2000年前的事了。由于计算毫秒的时间点是 1970 年,因此您一定会得到一个负数。如您所见,使用格式化程序进行解析可以为您解决这个问题。

问题:我可以在 Android API 23 级上使用 java.time 吗?

是的,java.time 在新旧 Android 设备上都能很好地工作。它只需要至少 Java 6.

  • 在 Java 8 和更高版本以及较新的 Android 设备(从 API 级别 26)中内置现代 API。
  • 在 Java 6 和 7 中获取 ThreeTen Backport,现代 classes 的 backport(ThreeTen 用于 JSR 310;请参阅底部的链接)。
  • 在(较旧的)Android 使用 ThreeTen Backport 的 Android 版本。它叫做 ThreeTenABP。并确保使用子包从 org.threeten.bp 导入日期和时间 classes。

链接