【问题标题】:Android Calendar.getTime().getTime() always returning -1 dayAndroid Calendar.getTime().getTime() 总是返回 -1 天
【发布时间】:2024-04-23 03:10:01
【问题描述】:

我通过提供时区然后将日、月和年设置为日历来创建日历实例。但是当我试图以毫秒为单位获取时间时,它总是以毫秒为单位返回 dateTime -1 天

这是我设置日历的方式。

DatePickerDialog datePickerDialog = new DatePickerDialog(Objects.requireNonNull(getContext()), R.style.DialogTheme, (view, year, month, dayOfMonth) -> {
        Calendar calendar = new DateUtils().getCountryCalendar();
        calendar.set(Calendar.YEAR, year);
        calendar.set(Calendar.MONTH, (month));
        calendar.set(Calendar.DAY_OF_MONTH, dayOfMonth);
        calendar.set(Calendar.HOUR_OF_DAY, 0);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);
        calendar.set(Calendar.MILLISECOND, 0);
        long selectedDate = calendar.getTime().getTime();
    }, mYear, mMonth, mDay);

我设置但它返回我 selectedDate1624986000000 这是 Tue Jun 29 2021 22:30:00

这里是 getCountryCalendar() 方法。

如果我选择 6 月 30 日,那么它应该以毫秒为单位返回 6 月 30 日。我不知道为什么会这样。任何建议表示赞赏。

public Calendar getCountryCalendar() {

    return Calendar.getInstance(TimeZone.getTimeZone("Asia/Bangkok"));
}

【问题讨论】:

  • UTC+7 时区的午夜仍然是 UTC
  • 我建议你不要使用Calendar。该课程设计不良且早已过时。而是使用LocalDateInstant 和来自java.time, the modern Java date and time API 的其他类。
  • 不存在 6 月 30 日,以毫秒为单位。毫秒值定义了一个时间点,在那个时间点是地球上不同时区的两天,有时是三天。

标签: android date datetime calendar timezone


【解决方案1】:

tl;博士

LocalDate
.of( y , m , d )
.atStartOfDay( ZoneId.of( "Asia/Bangkok" ) )
.toInstant()
.toEpochMilli() 

java.time

现代解决方案使用 java.time 类,该类在几年前取代了旧的日期时间类,例如 Calendar

建立您的仅日期值。

LocalDate ld = LocalDate.of( y , m , d ) ;

显然,您希望在特定时区看到该日期当天的第一刻。不要硬编码时间 00:00:00.0。在某些时区的某些日期,该时间可能不存在。让 java.time 确定一天中的第一个时刻。

ZoneId z = ZoneId.of( "Asia/Bangkok" ) ;
ZonedDateTime zdt = ld.atStartOfDay( z ) ;

显然,您希望将其转换为从 1970 年第一刻的纪元参考开始的毫秒数,如 UTC 所示。 Instant 类代表 UTC 中的时刻。

long millis = zdt.toInstant().toEpochMilli() ;

【讨论】:

    【解决方案2】:

    时间戳1624986000000 确实是Jun 30, 00:00:00 Asia/Bangkok 时区。你甚至可以检查它here

    另一方面,科尔卡塔和科伦坡时区将此时间戳呈现为Jun 29 2021 22:30:00

    由于您尚未共享将时间戳转换为 22:30:00 的代码,因此我假设您没有使用正确的时区(而是Asia/Colcata,或Asia/Colombo,或其他匹配 GMT +05:30)

    【讨论】: