tl;博士
java.time.Duration
.between( now , tomorrowStart )
.toMillis()
java.time
Java 8 及更高版本带有内置的java.time 框架。这些新类取代了与 Java 捆绑在一起的旧日期时间类 (java.util.Date/.Calendar)。也取代了由同一个人开发的 Joda-Time。大部分 java.time 功能都向后移植到 Java 6 和 7,并进一步适应了 Android(见下文)。
时区对于确定日期至关重要。对于任何给定的时刻,日期在全球范围内因区域而异。例如,Paris France 中午夜后几分钟是新的一天,而 Montréal Québec 中仍然是“昨天”。
以continent/region 的格式指定proper time zone name,例如America/Montreal、Africa/Casablanca 或Pacific/Auckland。切勿使用 3-4 个字母的缩写,例如 EST 或 IST,因为它们不是真正的时区,没有标准化,甚至不是唯一的(!)。
ZoneId z = ZoneId.of( "America/Montreal" );
ZonedDateTime now = ZonedDateTime.now( z );
我们想要获取到第二天第一刻的毫秒数,但不包括。
我们必须通过LocalDate 课程才能在一天的第一时间获得。所以在这里我们从ZonedDateTime 开始得到LocalDate,然后得到另一个ZonedDateTime。关键是在LocalDate 上调用atStartOfDay。
LocalDate tomorrow = now.toLocalDate().plusDays(1);
ZonedDateTime tomorrowStart = tomorrow.atStartOfDay( z );
请注意,我们不会在 00:00:00 对一天中的时间进行硬编码。由于诸如夏令时 (DST) 之类的异常情况,一天可能会从另一个时间开始,例如 01:00:00。让 java.time 确定第一个时刻。
现在我们可以计算经过的时间。在 java.time 中,我们使用 Duration 类。 java.time 框架具有更精细的纳秒分辨率,而不是 java.util.Date 和 Joda-Time 使用的更粗略的毫秒。但是Duration 包含一个方便的getMillis 方法,正如问题所要求的那样。
Duration duration = Duration.between( now , tomorrowStart );
long millisecondsUntilTomorrow = duration.toMillis();
看到这个code run live at IdeOne.com。
now.toString(): 2017-05-02T12:13:59.379-04:00[美国/蒙特利尔]
tomorrowStart.toString(): 2017-05-03T00:00-04:00[美国/蒙特利尔]
毫秒到明天:42360621
关于java.time
java.time 框架内置于 Java 8 及更高版本中。这些类取代了麻烦的旧 legacy 日期时间类,例如 java.util.Date、Calendar 和 SimpleDateFormat。
Joda-Time 项目现在位于maintenance mode,建议迁移到java.time 类。
要了解更多信息,请参阅Oracle Tutorial。并在 Stack Overflow 上搜索许多示例和解释。规格为JSR 310。
您可以直接与您的数据库交换 java.time 对象。使用符合JDBC 4.2 或更高版本的JDBC driver。不需要字符串,不需要java.sql.* 类。
从哪里获取 java.time 类?
乔达时间
更新:Joda-Time 项目现在位于maintenance mode,团队建议迁移到java.time 类。为了历史起见,我保留此部分完整,但建议使用上面讨论的 java.time 和 ThreeTenABP。
在 Android 中,您应该使用 Joda-Time 库而不是臭名昭著的麻烦 Java.util.Date/.Calendar 类。
Joda-Time 提供milliseconds-of-day command。但我们这里真的不需要。
相反,我们只需要一个Duration 对象来表示直到第二天第一刻的时间跨度。
时区对于确定“明天”何时开始至关重要。通常最好指定而不是隐式依赖 JVM 当前的默认时区,该时区可以随时更改。或者,如果您真的想要 JVM 的默认值,请通过调用 DateTimeZone.getDefault 明确要求,以使您的代码自记录。
可能是双线。
DateTime now = DateTime.now( DateTimeZone.forID( "America/Montreal" ) );
long milliSecondsUntilTomorrow = new Duration( now , now.plusDays( 1 ).withTimeAtStartOfDay() ).getMillis();
让我们把它分开。
DateTimeZone zone = DateTimeZone.forID( "America/Montreal" ); // Or, DateTimeZone.getDefault()
DateTime now = DateTime.now( zone );
DateTime tomorrow = now.plusDays( 1 ).withTimeAtStartOfDay(); // FYI the day does not *always* start at 00:00:00.0 time.
Duration untilTomorrow = new Duration( now , tomorrow );
long millisecondsUntilTomorrow = untilTomorrow.getMillis();
转储到控制台。
System.out.println( "From now : " + now + " until tomorrow : " + tomorrow + " is " + millisecondsUntilTomorrow + " ms." );
运行时。
从现在:2015-09-20T19:45:43.432-04:00 到明天:2015-09-21T00:00:00.000-04:00 是 15256568 毫秒。