首页 > 解决方案 > Date.getTime() 返回前一天

问题描述

我正在用dd-MM-yyyy格式解析日期并以秒为单位返回(除以 1000)。当我将其转换为 Unix 时间戳时,问题就出现了,因为它将这一秒转换为前一天。我将用我的代码和一个例子来解释:

private fun String.toTimestamp(): String {
    val dateFormat = SimpleDateFormat("dd-MM-yyyy", Locale.getDefault())
    return (dateFormat.parse(this).time / 1000).toString
}

如果日期是01/02/2019(2019 年 2 月 2 日),则此方法返回1548975600. 如果您将其转换为日期(我正在使用页面),它将返回01/31/2019 @ 11:00pm (UTC). 我试过添加小时、分钟和秒,甚至添加时区,但它总是返回前一天。

另一个例子 :13-02-2019>>155001240002/12/2019 @ 11:00pm (UTC)

日期来自 a DatePicker,但如果我以下一种方式创建它,它会返回正确的日期:

(Date().time / 1000).toString()

我已经尝试过使用西班牙语和英语的系统语言,并将其更改LocaleLocale.ENGLISHLocale("es", "ES")结果是相同的。

有什么建议么?

标签: androiddatekotlindatepickersimpledateformat

解决方案


java.time 和 ThreeTenABP

在 Java 语法中:

private static final DateTimeFormatter dateFormatter
        = DateTimeFormatter.ofPattern("dd-MM-uuuu");

public static final String toTimestamp(String dateString) {
    long epochSecond = LocalDate.parse(dateString, dateFormatter)
            .atStartOfDay(ZoneOffset.UTC)
            .toEpochSecond();
    return String.valueOf(epochSecond);
}

让我们试一试:

    System.out.println(toTimestamp("13-02-2019"));

1550016000

在您链接到的Epoch Unix 时间戳转换器上检查此值:

2019 年 2 月 13 日上午 12:00(UTC)

SimpleDateFormat是出了名的麻烦,并且Date已经过时了。相反,我使用 java.time,现代 Java 日期和时间 API。这迫使我们明确地给出时区或偏移量。在这种情况下作为预定义常量ZoneOffset.UTC。这反过来又确保我们得到正确的结果,从而解决您的问题。另一个小的优势是它给了我们几秒钟的时间,所以我们不需要看起来很有趣的除以 1000。

我使用的进口是:

import org.threeten.bp.LocalDate;
import org.threeten.bp.ZoneOffset;
import org.threeten.bp.format.DateTimeFormatter;

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

是的,java.time 在较旧和较新的 Android 设备上运行良好。它只需要至少Java 6

  • 在 Java 8 及更高版本以及更新的 Android 设备(从 API 级别 26 开始)中,现代 API 是内置的。在这种情况下,从包中导入java.time(不是org.threeten.bp)。
  • 在 Java 6 和 7 中获得 ThreeTen Backport,现代类的后向端口(ThreeTen 用于 JSR 310;请参阅底部的链接)。
  • 在(较旧的)Android 上使用 ThreeTen Backport 的 Android 版本。它被称为 ThreeTenABP。并确保从org.threeten.bp子包中导入日期和时间类。

链接


推荐阅读