Android Date.getTime() 在原始日期基础上加一天

Android Date.getTime() adds one day to original Date

所以我有一个日历,我需要设置一个特定的日期..

    Date date = TKDateUtils.parseDate("Jun 02, 2016 05:10:30 pm");

    Calendar next = Calendar.getInstance();
    next.setTime(date);

我在这里记录它们以查看输出:

    Log.i("MainActivity", date.toString());
    Log.i("MainActivity", date.getTime() + "");

输出:

    06-02 20:21:29.245 1915-1915/com.cyscorpions.timekeeper I/MainActivity: Thu Jun 02 17:10:30 EDT 2016
    06-02 20:21:29.245 1915-1915/com.cyscorpions.timekeeper I/MainActivity: 1464901830000

所以我将 getTime 从毫秒转换为日期,这是输出:

因此 Date 设置为 June 2, 2016 17:10:30getTime() 设置为该日期之后的确切日期。 我是不是做错了什么?

这是我解析日期的方式:

public static Date parseDate(@NonNull String dateString) {
    try {
        mDateFormat = new SimpleDateFormat("MMM dd, yyyy h:mm:ss a");
        return mDateFormat.parse(dateString);
    } catch (ParseException e) {
        e.printStackTrace();
    }
    return null;
}

问题一直在 Genymotion's TimeZone 上。它设置为与我所在位置不同的时区。

指定时区

两个不同的 JVM,每个都有自己的(不同的)当前默认时区。每个在解析字符串期间都使用自己当前的默认时区来解释输入数据的含义。

解决方案:始终指定 desired/expected 时区。

JVM当前的默认时区可以通过多种方式初始化。 JVM 内任何应用程序的任何线程中的任何代码都可以在运行时 期间 更改当前默认时区。所以永远不要依赖时区的这种外部性。

指定一个proper time zone name,格式为continent/region。切勿使用 3-4 个字母的缩写,例如 EDTISTCST 等。这些不是真正的时区,没有标准化,也不是唯一的(!)。

指定语言环境

同样适用于 Locale,用于解析日期和月份的名称,确定逗号与句点等。 JVM 的当前默认值 Locale 不受您的控制。因此,始终指定适合输入数据上下文的 desired/expected Locale

java.time

您使用的是旧的日期时间类,已被证明设计不佳、令人困惑且麻烦。避开它们。

java.time classes are built into Java 8 and later. Much of their functionality has been back-ported to Java 6 & 7 in the ThreeTen-Backport project, and further adapted to Android in the ThreeTenABP 项目。

java.time 类 是非常成功的 Joda-Time 库的继承者,这两个项目都由同一个人 Stephen Colbourne 领导。 java.time 类 取代了与 Java.

的最早版本捆绑在一起的臭名昭著的旧日期时间 类
ZoneId zoneId = ZoneId.of( "America/Montreal" );
Locale locale = Locale.CANADA_FRENCH ;
DateTimeFormatter formatter = DateTimeFormatter.ofPattern( "MMM dd, yyyy h:mm:ss a" );
formatter = formatter.withLocale( locale );
formatter = formatter.withZone( zoneId );

ZonedDateTime zdt = ZonedDateTime.parse( input , formatter );

我们经常希望使用 UTC 中的值。为此,使用 Instant,UTC 时间轴上的一个时刻,分辨率为纳秒。

Instant instant = zdt.toInstant();

转换

如果您必须拥有其中一种旧类型,请使用添加到旧日期时间 类 的新方法来转换 to/from java.time.

java.util.Date utilDate = java.util.Date.from( instant );
java.util.Calendar utilCal = java.util.GregorianCalendar.from( zdt );