Obtener milisegundos hasta la medianoche
Estoy creando un widget de Android que quiero actualizar todas las noches a medianoche. Estoy usando un AlarmManager
y necesito averiguar cuántos milisegundos quedan desde 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.
6 answers
Usa 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());
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-04-14 11:33:45
Tl;dr
Duration.between( now , tomorrowStart )
.toMillis()
Java.time
Java 8 y posterior viene con el java.time framework integrado. Estas nuevas clases suplantan a las antiguas clases de fecha y hora (java.útil.Fecha/.Calendario) incluido con Java. También suplanta a Joda-Time, desarrollado por las mismas personas. Gran parte del java.la funcionalidad de time está retroadaptada a Java 6 y 7, y adaptada a Android (ver más abajo).
Una zona horaria es crucial para determinar una fecha. Para un momento dado, la fecha varía alrededor del mundo por zona. Por ejemplo, unos minutos después de la medianoche en París Francia es un nuevo día mientras que todavía "ayer" en Montreal Québec.
Especificar un apropiado nombre de la zona horaria en el formato continent/region
, tales como America/Montreal
, Africa/Casablanca
, o Pacific/Auckland
. Nunca use la abreviatura de 3-4 letras como EST
o IST
ya que son no zonas horarias verdaderas, no estandarizadas y ni siquiera únicas (!).
ZoneId z = ZoneId.of( "America/Montreal" );
ZonedDateTime now = ZonedDateTime.now( z );
Queremos obtener el número de milisegundos que corren hasta, pero sin incluir, el primer momento del día siguiente.
Debemos pasar por la clase LocalDate
para llegar en el primer momento de un día. Así que aquí comenzamos con un ZonedDateTime
para obtener un LocalDate
, y después de eso obtenemos otro ZonedDateTime
. La clave está llamando atStartOfDay
en el LocalDate
.
LocalDate tomorrow = now.toLocalDate().plusDays(1);
ZonedDateTime tomorrowStart = tomorrow.atStartOfDay( z );
Observe 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. Vamos java.el tiempo determina el primer momento.
Ahora podemos calcular el tiempo transcurrido. En java.tiempo que usamos el Duration
clase. Java.time framework tiene una resolución más fina de nanosegundos en lugar de los milisegundos más gruesos utilizados por ambos Java.útil.Fecha y Joda-Hora. Pero Duration
incluye un práctico getMillis
método, como la Pregunta solicitada.
Duration duration = Duration.between( now , tomorrowStart );
long millisecondsUntilTomorrow = duration.toMillis();
Ver este código ejecutar en vivo en IdeOne.com .
Ahora.toString(): 2017-05-02T12:13:59.379-04: 00[América/Montreal]
Mañana empieza.toString (): 2017-05-03T00:00-04: 00[America/Montreal]
Milisegundos hasta mañana: 42360621
Acerca de java.tiempo
El java.hora el framework está integrado en Java 8 y versiones posteriores. Estas clases suplantan a las problemáticas antiguas legacy clases de fecha y hora como java.util.Date
, Calendar
, & SimpleDateFormat
.
El Joda-Tiempo project, ahora en modo de mantenimiento , aconseja la migración a java .tiempo clases.
Para obtener más información, consulte el Oracle Tutorial. Y desbordamiento de pila de búsqueda para muchos ejemplos y explicaciones. La especificación es JSR 310.
Puede intercambiar java.time objetos directamente con su base de datos. Utilice un controlador JDBC compatible con JDBC 4.2 o posterior. No hay necesidad de cadenas, no hay necesidad de clases java.sql.*
.
Dónde obtener java.clases de tiempo?
-
Java SE 8, Java SE 9, Java SE 10, y más tarde
- Incorporado.
- Parte de la API estándar de Java con una implementación incluida.
- Java 9 añade algunas características menores y correcciones.
-
Java SE 6 y Java SE 7
- Gran parte de java.la funcionalidad de tiempo se vuelve a portar a Java 6 y 7 en ThreeTen-Backport.
-
Android
- Versiones posteriores de implementaciones de Android bundle de java .tiempo clases.
- Para Android anterior (ThreeTenABP el proyecto se adapta ThreeTen-Backport (antes mencionado). Véase Cómo usar ThreeTenABP....
Joda-Tiempo
ACTUALIZACIÓN: El proyecto Joda-Time está ahora en modo de mantenimiento , con el equipo asesorando la migración a la java.tiempo clases. Dejo esta sección intacta por el bien de la historia, pero recomiendo usar java.time and ThreeTenABP as discussed arriba.
En Android deberías usar la biblioteca Joda-Time en lugar de la notoriamente problemática Java.útil.Fecha/.Clases de calendario.
Joda-Time ofrece un comando milisegundos del día. Pero realmente no necesitamos eso aquí.
En su lugar, solo necesitamos un Duration
objeto 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 mejor a especificar que confiar implícitamente en la zona horaria predeterminada actual de la JVM que puede cambiar en cualquier momento. O si realmente desea el valor predeterminado de la JVM, pídalo explícitamente con call to DateTimeZone.getDefault
para hacer que su código se documente automáticamente.
Podría ser de dos líneas.
DateTime now = DateTime.now( DateTimeZone.forID( "America/Montreal" ) );
long milliSecondsUntilTomorrow = new Duration( now , now.plusDays( 1 ).withTimeAtStartOfDay() ).getMillis();
Vamos a desmontar eso.
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();
Volcar a la consola.
System.out.println( "From now : " + now + " until tomorrow : " + tomorrow + " is " + millisecondsUntilTomorrow + " ms." );
Cuando se ejecuta.
Desde ahora : 2015-09-20T19:45:43.432-04:00 hasta mañana : 2015-09-21T00:00:00.000-04:00 es 15256568 ms.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-07-06 18:39:47
Intente 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);
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-08-16 14:49:13
Funcionaría esto?
long MILLIS_IN_DAY = 86400000;
long currentTime = System.currentTimeInMillis();
long millisTillNow = currentTime % MILLIS_IN_DAY;
long millisecondsUntilMidnight = MILLIS_IN_DAY - millisTillNow;
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-08-16 14:44:31
Usted podría utilizar AlarmManager.RTC
en lugar de AlarmManager.ELAPSED_REALTIME
, y simplemente establezca 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
);
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-06-14 14:55:04
Usando la siguiente manera, no hay necesidad de preocuparse por configurar 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()));
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-09-20 08:19:24