您的示例代码有效
我认为你的代码没有问题,因为你的框架(阅读下面的批评)。
此处几乎显示了您的确切代码。两个变化:
- 我将您的格式常量设为局部变量。 (只是为了让这个演示更简单,一段代码可以复制粘贴)
- 我添加了几个调用来获取
Instant,即UTC 中的当前时刻。类似于java.util.Date,但Instant::toString 创建一个显示UTC 的字符串,而不是混淆地应用JVM 的当前时区。因此,您可以更清楚地看到您确实获得了 JVM 当前默认时区的第一时刻。在我运行此代码的情况下,我的 JVM 当前的默认时区是 America/Los_Angeles,目前在夏令时 (DST) 中为 offset-from-UTC 为 -07:00(比 UTC 晚七个小时)。
示例代码。
Date date1 = new Date ();
SimpleDateFormat SD_FORMAT_DAY_MONTH_YEAR = new SimpleDateFormat ( "dd/MM/yyyy" );
String time = SD_FORMAT_DAY_MONTH_YEAR.format ( date1 );
Date date2 = null;
long value;
try {
date2 = SD_FORMAT_DAY_MONTH_YEAR.parse ( time );
value = date2.getTime ();
} catch ( ParseException e ) {
value = 0;
}
System.out.println ( "date1: " + date1 + " date2: " + date2 + " value: " + value + " | instant 1: " + date1.toInstant () + " | instant 2: " + date2.toInstant () );
运行时。
日期 1:2016 年 5 月 5 日星期四 16:55:40 PDT 日期2:2016 年 5 月 5 日星期四 00:00:00 PDT 值:1462431600000 |瞬间 1: 2016-05-05T23:55:40.907Z |瞬间 2:2016-05-05T07:00:00Z
工作太辛苦了
您的问题令人困惑,但您似乎正试图捕捉一天中的第一刻。你走错路了,工作太努力了。
时区
您的代码似乎正在使用 java.util.Date 类。该类代表 UTC 时间线上的一个时刻。
但您并没有在 UTC 中获得一天中的第一刻。当您解析该仅日期字符串以生成新的 java.util.Date(日期 加上 时间值,尽管名称具有误导性),您的 JVM 的当前默认时区将被隐式应用。将时区无形地注入到流程中非常令人困惑。
相反,您应该有意识地考虑时区,并始终明确时区是您的编码(如下所示)。
java.time
旧的java.util.Date/.Calendar 类已被证明设计不佳、混乱且麻烦。它们现在是遗留的,被 Java 8 及更高版本中内置的 java.time 框架所取代。 java.time 的大部分功能是back-ported to Java 6 & 7 和further adapted for Android。
对于没有时间和时区的仅日期值,请使用LocalDate 类。虽然不存储时区,但确定诸如“今天”之类的日期需要时区。如果省略,则应用您的 JVM 当前的默认时区(请注意,该默认值可能会在运行时随时更改)。
ZoneId zoneId = ZoneId.of( "America/Montreal" );
LocalDate today = LocalDate.now( zoneId );
你似乎想要一天的第一刻。不要假设那一刻的时间是00:00:00.0。虽然通常是正确的,但在某些时区,诸如夏令时之类的异常情况可能会转移到另一个时间。让 java.time 确定正确的时间。调用 [atStartOfDay][2] 会在第一时间生成适合指定时区的 ZonedDateTime。
ZonedDateTime zdt = today.atStartOfDay( zoneId );
我强烈建议不要将处理日期时间值用作计数来自-epoch。这就像使用 Unicode 代码点的整数数组,而不是使用与字符串相关的类来处理文本。但如果你坚持,你可以转换。但是要注意数据丢失,因为 java.time 类具有更精细的纳秒分辨率,而您要求的是毫秒(避免将日期时间处理为从纪元开始计数的众多原因之一)。首先提取Instant,UTC时间轴上的时刻,分辨率为纳秒。
Instant instant = zdt.toInstant();
long millisecondsFromEpoch = instant.toEpochMilli(); // WARNING: Possible data loss (going from nanoseconds to milliseconds).
UTC
如果您确实想要 UTC 时间的第一刻,那也很容易。
您可以使用常量ZoneOffset.UTC 将UTC 指定为时区。 (该常量恰好在ZoneOffset 中,它是ZoneId 的子类。)
ZonedDateTime zdt = today.atStartOfDay( ZoneOffset.UTC );
但这可能不是最合适的路线。时区是offset-from-UTC加上一组异常规则,例如Daylight Saving Time (DST)。根据定义,UTC 没有此类异常。所以更合适的是OffsetDateTime 而不是ZonedDateTime。
OffsetTime ot = OffsetTime.of( 0 , 0 , 0 , 0 , ZoneOffset.UTC );
OffsetDateTime odt = today.atTime( ot );