Obtenga milisegundos hasta la medianoche

Estoy creando un widget de Android que quiero actualizar cada noche a medianoche. Estoy usando un AlarmManager y necesito saber cuántos milisegundos quedan de la hora actual hasta la medianoche. Aquí está mi código:

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

¿Cómo puedo calcular cuántos milisegundos quedan hasta la medianoche?

Gracias de antemano.

Utilice un calendario para calcularlo:

  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()); 

Tl dr

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

Java.time

Java 8 y versiones posteriores vienen con el marco java.time incorporado. Estas nuevas clases suplantan las viejas clases de fecha y hora (java.util.Date/.Calendar) incluidas en Java. También suplanta Joda-Time, desarrollado por la misma gente. Gran parte de la funcionalidad de java.time está retro-portada a Java 6 y 7, y adaptada además a Android (ver más abajo).

Una zona horaria es crucial para determinar una fecha. Para cualquier momento dado, la fecha varía alrededor del globo por la zona. Por ejemplo, unos pocos minutos después de la medianoche en París Francia es un nuevo día, mientras que todavía "ayer" en Montreal Quebec .

Especifique un nombre de zona horaria adecuado en el formato de continent/region , como America/Montreal , Africa/Casablanca o Pacific/Auckland . Nunca utilice la abreviatura de 3-4 letras como EST o IST ya que no son zonas horarias verdaderas, no están estandarizadas y ni siquiera son únicas (!).

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

Queremos obtener el número de milisegundos en ejecución hasta, pero sin incluir, el primer momento del día siguiente.

Debemos pasar por la clase LocalDate para llegar al primer momento de un día. Así que aquí empezamos con un ZonedDateTime para obtener una LocalDate , y después de eso obtener otro ZonedDateTime . La clave está llamando atStartOfDay en LocalDate .

 LocalDate tomorrow = now.toLocalDate().plusDays(1); ZonedDateTime tomorrowStart = tomorrow.atStartOfDay( z ); 

Tenga en cuenta que no codificamos una hora del día a las 00:00:00. Debido a anomalías como el horario de verano (DST), el día puede comenzar en otro momento, como 01:00:00. Deje que java.time determine el primer momento.

Ahora podemos calcular el tiempo transcurrido. En java.time usamos la clase Duration . El marco java.time tiene una resolución más fina de nanosegundos en lugar de los milisegundos más gruesos utilizados por java.util.Date y Joda-Time. Pero Duration incluye un práctico método getMillis , como la Cuestión solicitada.

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

Vea este código en directo en IdeOne.com .

Now.toString (): 2017-05-02T12: 13: 59.379-04: 00 [América / Montreal]

TomorrowStart.toString (): 2017-05-03T00: 00-04: 00 [América / Montreal]

MillisecondsUntilTomorrow: 42360621


Acerca de java.time

El framework java.time está integrado en Java 8 y posterior. Estas clases suplantan las viejas clases de fecha-hora heredadas , como java.util.Date , Calendar y SimpleDateFormat .

El proyecto Joda-Time , ahora en modo de mantenimiento , recomienda la migración a las clases java.time .

Para obtener más información, consulte el Tutorial de Oracle . Y busca Stack Overflow para muchos ejemplos y explicaciones. La especificación es JSR 310 .

Dónde obtener las clases java.time?

  • Java SE 8 , Java SE 9 y posterior
    • Incorporado.
    • Parte de la API Java estándar con una implementación integrada.
    • Java 9 agrega algunas características y correcciones menores.
  • Java SE 6 y Java SE 7
    • Gran parte de la funcionalidad de java.time se retroporta a Java 6 & 7 en ThreeTen-Backport .
  • Androide
    • El proyecto ThreeTenABP adapta específicamente a ThreeTen-Backport (mencionado anteriormente) para Android.
    • Consulte Cómo utilizar ThreeTenABP ….

Joda-Time

ACTUALIZACIÓN: El proyecto Joda-Time está ahora en modo de mantenimiento , con el equipo recomendando la migración a las clases java.time . Dejo esta sección intacta por el bien de la historia, pero recomiendo usar java.time y ThreeTenABP como se mencionó anteriormente.

En Android deberías usar la biblioteca Joda-Time en lugar de las clases Java.util.Date/.Calendar.

Joda-Time ofrece un comando de milisegundos de día . Pero en realidad no lo necesitamos aquí.

En su lugar sólo necesitamos un objeto de Duration para representar el lapso de tiempo hasta el primer momento del día siguiente.

La zona horaria es crítica aquí para determinar cuándo comienza "mañana". Generalmente es mejor especificar que depender implícitamente de la zona horaria actual predeterminada de la JVM que puede cambiar en cualquier momento. O si realmente desea el valor predeterminado de la JVM, pídalo explícitamente con la llamada a DateTimeZone.getDefault para que el código se auto-documente.

Podría ser un dos-línea.

 DateTime now = DateTime.now( DateTimeZone.forID( "America/Montreal" ) ); long milliSecondsUntilTomorrow = new Duration( now , now.plusDays( 1 ).withTimeAtStartOfDay() ).getMillis(); 

Tomemos eso aparte.

 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(); 

Descarga en la consola.

 System.out.println( "From now : " + now + " until tomorrow : " + tomorrow + " is " + millisecondsUntilTomorrow + " ms." ); 

Cuando se ejecuta.

A partir de ahora: 2015-09-20T19: 45: 43.432-04: 00 hasta mañana: 2015-09-21T00: 00: 00.000-04: 00 es 15256568 ms.

Pruebe lo siguiente:

 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); 

¿Funcionaría esto?

 long MILLIS_IN_DAY = 86400000; long currentTime = System.currentTimeInMillis(); long millisTillNow = currentTime % MILLIS_IN_DAY; long millisecondsUntilMidnight = MILLIS_IN_DAY - millisTillNow; 

Puede utilizar AlarmManager.RTC lugar de AlarmManager.ELAPSED_REALTIME , y simplemente establecer un calendario a la hora que desee:

 // 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 ); 

Usando la siguiente manera, no hay necesidad de preocuparse por establecer DAY_OF_MONTH.

  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())); 
  • Interacción entre Java y Android
  • ¿Cómo puedo enviar un campo de texto en la solicitud POST que carga un blob en Blobstore y lo recupero en el controlador de carga del blob?
  • Cifrado entre Android y C #
  • Node.js Hmac SHA256 base64 de cadena
  • Combinando varios sensores Android con clases de ayuda
  • Grupo de usuarios en firebase
  • TabWidget parpadea cuando el teclado oculta android
  • Android: forma estándar de hacer correr un hilo cada segundo
  • Destruye la notificación de primer plano cuando el servicio se mata
  • Android: Alternativa de temporizador / retraso
  • Android @Inject y anotaciones de @InjectView significado
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.