Java 到午夜还有几毫秒

Java 到午夜还有几毫秒,java,android,date,milliseconds,Java,Android,Date,Milliseconds,我正在创建一个Android小部件,我想在每晚午夜更新它。我使用的是AlarmManager,我需要找出从当前时间到午夜还有多少毫秒。这是我的密码: AlarmManager mAlarmManager = (AlarmManager)context.getSystemService(android.content.Context.ALARM_SERVICE); mAlarmManager.set(AlarmManager.ELAPSED_REALTIME, millisecondsUntilM

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

AlarmManager mAlarmManager = (AlarmManager)context.getSystemService(android.content.Context.ALARM_SERVICE);
mAlarmManager.set(AlarmManager.ELAPSED_REALTIME, millisecondsUntilMidnight, mSrvcPendingingIntent);
我如何计算到午夜还有多少毫秒


提前感谢。

使用日历计算:

        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());
请尝试以下操作:

Calendar c = Calendar.getInstance();
long now = c.getTimeInMillis();
c.add(Calendar.DATE, 1);
c.set(Calendar.HOUR_OF_DAY, 0);
c.set(Calendar.MINUTE, 0);
c.set(Calendar.SECOND, 0);
c.set(Calendar.MILLISECOND, 0);

long millisecondsUntilMidnight = c.getTimeInMillis() - now;

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

long MILLIS_IN_DAY = 86400000;

long currentTime = System.currentTimeInMillis();

long millisTillNow = currentTime % MILLIS_IN_DAY;

long millisecondsUntilMidnight = MILLIS_IN_DAY - millisTillNow;
您可以使用而不是
AlarmManager.REALTIME
,只需将日历设置为您想要的时间:

// Create a calendar for midnight
Calendar todayMidnight = Calendar.getInstance();
todayMidnight.add(Calendar.DATE, 1);
todayMidnight.set(Calendar.HOUR_OF_DAY, 0);
todayMidnight.set(Calendar.MINUTE, 0);
todayMidnight.set(Calendar.SECOND, 0);

// Create an alarm going off at midnight
mAlarmManager.set(
   AlarmManager.RTC, 
   todayMidnight.getTimeInMillis(), 
   mSrvcPendingingIntent
);

使用以下方法,无需担心设置月的第天

    long msInDay = 86400000;
    Calendar c = Calendar.getInstance();
    c.set(Calendar.HOUR_OF_DAY, 0);
    c.set(Calendar.MINUTE, 0);
    c.set(Calendar.SECOND, 0);
    c.set(Calendar.MILLISECOND, 0);

    System.out.print(msInDay - (System.currentTimeMillis() - c.getTimeInMillis()));
tl;博士
java.time.Duration
.之间(现在,明天开始)
.toMillis()
java.time Java8及更高版本附带了内置的框架。这些新类取代了与java捆绑在一起的旧日期时间类(java.util.date/.Calendar)。也取代了由同一个人开发的Joda Time。大部分java.time功能都被向后移植到Java6和Java7,并进一步适应Android(见下文)

时区对于确定日期至关重要。在任何一个特定的时刻,世界各地的日期都因地区而异。例如,中午夜后几分钟是新的一天,而中仍然是“昨天”

大陆/地区
的格式指定,例如,或
太平洋/奥克兰
。切勿使用3-4个字母的缩写,如
EST
IST
,因为它们不是真正的时区,也不是标准化的,甚至不是唯一的(!)

我们想要得到运行到(但不包括)第二天第一刻的毫秒数

我们必须通过
LocalDate
课程才能在一天中的第一个时刻获得。因此,我们从一个
ZonedDateTime
开始,得到一个
LocalDate
,然后得到另一个
ZonedDateTime
。该键正在调用
LocalDate

LocalDate tomorrow = now.toLocalDate().plusDays(1);
ZonedDateTime tomorrowStart = tomorrow.atStartOfDay( z );
请注意,我们不会在00:00:00硬编码一天中的某个时间。由于夏令时(DST)等异常情况,一天可能会在其他时间开始,如01:00:00。让java.time确定第一个时刻

现在我们可以计算经过的时间。在java.time中,我们使用类。java.time框架具有更精细的纳秒分辨率,而不是java.util.Date和Joda time使用的更粗糙的毫秒。但是,根据问题的要求,
Duration
包含了一个简便的方法

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

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

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

毫秒太阳倾斜明天:42360621


关于java.time 该框架内置于Java8及更高版本中。这些类取代了麻烦的旧日期时间类,例如,&

该项目现已启动,建议迁移到类

要了解更多信息,请参阅。并搜索堆栈溢出以获得许多示例和解释。规格是

您可以直接与数据库交换java.time对象。使用兼容的或更高版本。不需要字符串,也不需要
java.sql.*

从哪里获得java.time类

  • 然后
  • 内置的
  • 标准JavaAPI的一部分,带有捆绑实现
  • Java9添加了一些次要功能和修复
  • 大部分java.time功能都在中向后移植到Java6和Java7
  • 更高版本的Android捆绑包实现了java.time类

  • 对于早期的Android(这可能会有所帮助,在你的例子中,只需将其翻转过来,哼。我不认为这涉及现实(空闲秒等)。(c.getTimeInMillis-now)将为负值?这将计算到最后午夜的时间。你必须增加一天(见我的答案)。我编辑了我的答案(增加一天)。感谢您的警告。文档显示“SystemClock.elapsedRealtime()+60*1000”可将AlarmManager.elapsedRealtime的闹钟设置为一分钟。因此,它不应该是“SystemClock.elapsedRealtime()+毫秒直至午夜”在你的例子中?你应该确保使用Calendar.HOUR OF_DAY而不是Calendar.HOUR,因为Calendar.HOUR是基于12小时的时钟。根据你运行代码的时间,你的午夜计算可能是错误的。我通过观察发现了这一点。已设置为当前日期和时间,因此
    c.setTime(现在)
    是不必要的。您还可以使用来比较日历值。您的解决方案是否需要onReceive方法中的唤醒锁定方法?这是:PowerManager pm=(PowerManager)context.getSystemService(context.POWER\u SERVICE);PowerManager.WakeLock wl=pm.newWakeLock(PowerManager.PARTIAL\u wake\u lock,“任意/任意标记”);//获取锁wl.Acquire();Log.d(“报警管理器中的小部件”,“接下来将是静态方法”);//释放锁wl.Release();这将在月的最后一天失败,您应该使用add(Calendar.DATE,1)不是第二天_MONTH@GregEnnis不,不会。日历实现对添加`(您可以检查源代码)中的日期、月中的日、年中的日和周中的日执行完全相同的操作。您好,您的解决方案是否需要onReceive方法中的唤醒锁方法?这是:PowerManager pm=(PowerManager)context.getSystemService(context.POWER\u SERVICE);PowerManager.WakeLock wl=pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK,“which/any标记”);//获取锁wl.Acquire();Log.d(“小部件”,“在报警管理器中。接下来将使用静态方法”);//从文档中释放锁wl.Release():“只要报警接收器的onReceive()方法正在执行,报警管理器就会保持CPU唤醒锁”。因此,您不需要自己处理唤醒锁。您是如何做到的?我可以提供一个代码片段吗?我假设所有情况下都是类似的。我是如何做到的?我感觉创建自己的方法可能会更好地为您服务
    Duration duration = Duration.between( now , tomorrowStart );
    long millisecondsUntilTomorrow = duration.toMillis();
    
    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." );