Obtenir millisecondes jusqu'à minuit

je crée un widget Android que je veux mettre à jour tous les soirs à minuit. J'utilise un AlarmManager et j'ai besoin de savoir combien de millisecondes il me reste entre l'heure actuelle et minuit. Voici mon code:

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

Comment puis-je calculer combien de millisecondes restent jusqu'à minuit?

Merci d'avance.

25
demandé sur SZH 2012-08-16 18:36:30

6 réponses

utilisez un calendrier pour le calculer:

        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());
48
répondu Denys Séguret 2014-04-14 11:33:45

tl; dr

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

de java.temps

Java 8 et plus tard vient avec le java.temps cadre intégré. Ces nouvelles classes remplacent les anciennes classes date-heure (java.util.Date./Calendrier) livré avec Java. Aussi supplante Joda-Time, développé par les mêmes personnes. Une grande partie de la java.la fonctionnalité time est rétroportée à Java 6 & 7, puis adaptée à Android (voir ci-dessous).

un temps la zone est cruciale pour déterminer une date. Pour un moment donné, la date varie autour du globe par zone. Par exemple, quelques minutes après minuit dans Paris France est un nouveau jour alors qu'encore "hier" dans Montréal Québec .

spécifier un nom du fuseau horaire approprié dans le format de continent/region , tel que America/Montreal , Africa/Casablanca , ou Pacific/Auckland . N'utilisez jamais l'abréviation de 3-4 lettres comme EST ou IST car ils sont pas vrai fuseaux horaires, non standardisé, et même pas unique(!).

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

nous voulons obtenir le nombre de millisecondes allant jusqu'au premier moment du lendemain, mais sans compter.

nous devons passer par la classe LocalDate pour obtenir au premier moment d'une journée. Donc, nous commençons par un ZonedDateTime pour obtenir un LocalDate , et après cela obtenir un autre ZonedDateTime . La clé est d'appeler atStartOfDay sur le LocalDate .

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

notez que nous ne codons pas un moment de la journée à 00:00:00. En raison d'anomalies telles que L'heure avancée (HNT), la journée peut commencer à une autre heure telle que 01:00:00. Laissez java.le temps détermine le premier moment.

Maintenant, nous pouvons calculer le temps écoulé. Dans Java.temps nous utilisons la classe Duration . Java.time framework a une résolution plus fine de nanosecondes plutôt que les millisecondes plus grossières utilisées par les deux java.util.Date et Joda-Time. Mais Duration comprend une pratique getMillis méthode, comme la Question demandée.

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

voir ce IdeOne.com .

maintenant.toString(): 2017-05-02T12 :13:59.379-04:00[America/Montreal]

tomorrowStart.toString (): 2017-05-03T00: 00-04: 00[America/Montreal]

millisecondsUntilTomorrow: 42360621


à Propos de de java.heure

Le de java.time framework est construit dans Java 8 et plus tard. Ces classes supplantent la vieille "héritage date-heure classes telles que java.util.Date , Calendar , & SimpleDateFormat .

le Joda-Time projet, maintenant en mode maintenance , conseille la migration vers le java.temps des classes.

Pour en savoir plus, voir le Oracle Tutoriel . Et rechercher le débordement de la pile pour de nombreux exemples et explications. La spécification est JSR 310 .

vous pouvez échanger java.temps objets directement avec votre base de données. Utiliser un JDBC driver conforme à JDBC 4.2 ou plus tard. Pas besoin de Chaînes, pas besoin de classes java.sql.* .

où obtenir le java.les classes de temps?


Joda-Time

mise à jour: le projet Joda-Time est maintenant en mode maintenance , avec l'équipe conseillant la migration vers le java.temps des classes. Je laisse cette section intacte pour les pour l'histoire, mais recommandez l'utilisation de java.temps et ThreeTenABP comme discuté ci-dessus.

sur Android vous devriez utiliser la bibliothèque Joda-Time plutôt que le Java notoirement gênant.util.Date./Calendrier des classes.

Joda-Time offre une millisecondes de la journée à la commande . Mais on n'a pas vraiment besoin de ça ici.

à la place Nous avons juste besoin d'un Duration objet pour représenter la période de temps jusqu'au premier moment du jour suivant.

fuseau horaire est critique ici pour déterminer quand "demain" commence. Il est généralement préférable de spécifier que de s'en remettre implicitement au fuseau horaire par défaut de la JVM qui peut changer à tout moment. Ou si vous voulez vraiment la valeur par défaut de la JVM, demandez-le explicitement avec l'appel à DateTimeZone.getDefault pour rendre votre code auto-documentant.

pourrait être un deux-liner.

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

démontons ça.

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

Dump à console.

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

Lors de l'exécuter.

à partir de Maintenant : 2015-09-20T19:45:43.432-04:00 jusqu'à demain : 2015-09-21T00:00:00.000-04:00 est 15256568 ms.

13
répondu Basil Bourque 2018-07-06 18:39:47

essayez ce qui suit:

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);
2
répondu Korhan Ozturk 2012-08-16 14:49:13

est-ce que ça marcherait?

long MILLIS_IN_DAY = 86400000;

long currentTime = System.currentTimeInMillis();

long millisTillNow = currentTime % MILLIS_IN_DAY;

long millisecondsUntilMidnight = MILLIS_IN_DAY - millisTillNow;
0
répondu sgp15 2012-08-16 14:44:31

vous pouvez utiliser AlarmManager.RTC au lieu de AlarmManager.ELAPSED_REALTIME , et juste définir un calendrier à l'heure que vous voulez:

// 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
);
0
répondu nicopico 2013-06-14 14:55:04

en utilisant le chemin suivant, il n'y a pas besoin de se soucier de définir 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()));
0
répondu Youness 2015-09-20 08:19:24