为什么Calendar.getTimeInMillis()返回负值?

时间:2019-08-24 08:23:17

标签: java android calendar

我正在阅读textview的日期,我想知道上午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,因为我认为它可能通过强制转换为整数而产生溢出。

结果:

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

3 个答案:

答案 0 :(得分:4)

从倒数第二个屏幕上看到的,您设置的年份是0019,而不是2019年。由于getTimeInMillis是相对于纪元时间(1970年1月1日)设置的,因此您会得到一个负数

答案 1 :(得分:1)

您使事情复杂化了。

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);

我在欧洲/哥本哈根时区的计算机上的输出是:

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

您尝试使用的Calendar类的设计很差,而且已经过时了。您不应该使用它。对于日期,请使用现代Java日期和时间API java.time中的LocalDate

不要以您的方式解析字符串。 DateTimeFormatter类是为此目的而内置的,因此将其工作留给它。这也使您可以更好地验证字符串。格式模式字符串中的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反向端口,这是现代类的反向端口(JSR 310的ThreeTen;请参见底部的链接)。
  • 在(较旧的)Android上,使用Android版本的ThreeTen Backport。叫做ThreeTenABP。并确保您使用子包从org.threeten.bp导入日期和时间类。

链接

答案 2 :(得分:0)

我将建议此解决方法:

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

    日期d =新日期(timestampLong);
    日历ActuallDate = Calendar.getInstance();
    ActuallDate.setTime(d);

相关问题