在午夜前获得毫秒tl;博士java.time关于 java.time 城大时间

2022-09-01 06:30:01

我正在创建一个Android小部件,我想每天午夜更新。我正在使用,我需要找出从当前时间到午夜还剩多少毫秒。这是我的代码:AlarmManager

AlarmManager mAlarmManager = (AlarmManager)context.getSystemService(android.content.Context.ALARM_SERVICE);
mAlarmManager.set(AlarmManager.ELAPSED_REALTIME, millisecondsUntilMidnight, mSrvcPendingingIntent);

如何计算离午夜还剩多少毫秒?

提前感谢您。


答案 1

使用日历来计算它:

        Calendar c = Calendar.getInstance();
        c.add(Calendar.DAY_OF_MONTH, 1);
        c.set(Calendar.HOUR_OF_DAY, 0);
        c.set(Calendar.MINUTE, 0);
        c.set(Calendar.SECOND, 0);
        c.set(Calendar.MILLISECOND, 0);
        long howMany = (c.getTimeInMillis()-System.currentTimeMillis());

答案 2

tl;博士

java.time.Duration
.between( now , tomorrowStart )
.toMillis()

java.time

Java 8及更高版本内置了java.time框架。这些新类取代了旧的日期时间类(java.util.Date/。日历)与Java捆绑在一起。也取代了由同一个人开发的Joda-Time。许多java.time功能都向后移植到Java 6和7,并进一步适应Android(见下文)。

时区对于确定日期至关重要。在任何给定的时刻,日期在全球范围内因区域而异。例如,法国巴黎午夜后几分钟是新的一天,而在魁北克蒙特利尔仍然是“昨天”。

以 的格式指定适当的时区名称,例如 美国/蒙特利尔非洲/卡萨布兰卡或 。切勿使用3-4个字母的缩写,例如或因为它们不是真正的时区,不是标准化的,甚至不是唯一的(!)。continent/regionPacific/AucklandESTIST

ZoneId z = ZoneId.of( "America/Montreal" );
ZonedDateTime now = ZonedDateTime.now( z );

我们希望将运行到(但不包括)第二天第一个时刻的毫秒数。

我们必须通过课程才能在一天的第一刻得到。所以在这里,我们从 a 开始得到一个 ,然后得到另一个 。关键是在StartOfDay上调用。LocalDateZonedDateTimeLocalDateZonedDateTimeLocalDate

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 使用的较粗糙的毫秒。但包括一个方便的getMillis方法,正如问题所要求的。Duration

Duration duration = Duration.between( now , tomorrowStart );
long millisecondsUntilTomorrow = duration.toMillis();

请参阅此代码在 IdeOne.com 实时运行

now.toString(): 2017-05-02T12:13:59.379-04:00[美国/蒙特利尔]

明天开始.toString(): 2017-05-03T00:00-04:00[美国/蒙特利尔]

毫秒结束午夜:42360621


关于 java.time

java.time 框架内置于 Java 8 及更高版本中。这些类取代了麻烦的旧日期时间类,如java.util.DateCalendarSimpleDateFormat

Joda-Time 项目现在处于维护模式,建议迁移到 java.time 类。

要了解更多信息,请参阅 Oracle 教程。搜索 Stack Overflow 以获取许多示例和解释。规格是JSR 310

您可以直接与数据库交换 java.time 对象。使用符合 JDBC 4.2 或更高版本的 JDBC 驱动程序。不需要字符串,不需要类。java.sql.*

从哪里获取 java.time 类?


城大时间

更新:Joda-Time项目现在处于维护模式,团队建议迁移到java.time类。为了历史起见,我保留了这一部分,但建议使用java.time和ThreeTenABP,如上所述。

在Android中,你应该使用Joda-Time库,而不是臭名昭着的麻烦的Java.util.Date/。日历类。

Joda-Time 提供一毫秒的每日命令。但我们在这里并不需要它。

相反,我们只需要一个 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毫秒。