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.
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());
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?
- Java SE 8 , Java SE 9 , Java SE 10 , et plus tard
- intégré.
- fait partie de L'API Java standard avec une implémentation groupée.
- Java 9 ajoute fonctionnalités mineures et corrections.
- Java SE 6 et Java SE 7
- une grande partie de la java.la fonctionnalité time est rétroportée à Java 6 & 7 dans ThreeTen-Backport .
- Android
- versions ultérieures de l'implémentation du paquet Android de la java.temps des classes.
- Pour plus tôt Android (<26 ans), le ThreeTenABP "1519340920 projet" s'adapte ThreeTen-Backport (mentionné ci-dessus). Voir comment utiliser ThreeTenABP... .
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.
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);
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;
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
);
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()));