Comment puis-je obtenir le nombre de millisecondes depuis minuit pour le courant?

125

Remarque, je ne veux PAS de millis d'époque. Je veux le nombre de millisecondes actuellement sur l'horloge.

Donc, par exemple, j'ai ce bout de code.

Date date2 = new Date(); 
Long time2 = (long) (((((date2.getHours() * 60) + date2.getMinutes())* 60 ) + date2.getSeconds()) * 1000);

Existe-t-il un moyen d'obtenir des millisecondes avec la date? Y a-t-il une autre façon de faire cela?

Remarque: System.currentTimeMillis() me donne des millis d'époque ce qui n'est pas ce que je recherche.

Lemonio
la source
2
Vous voulez dire "millisecondes dans la seconde", donc la valeur est toujours dans l'intervalle [0, 999], n'est-ce pas? @thinksteep a lu la dernière phrase.
Matt Ball
@Lemonio Donner un exemple rendrait votre question plus claire.
Basil Bourque
FYI, les anciennes classes de date-heure gênantes telles que java.util.Datemaintenant héritées , supplantées par les classes java.time .
Basil Bourque
FYI, les anciennes classes de date-heure gênantes telles que java.util.Datemaintenant héritées , supplantées par les classes java.time . Voir le didacticiel d'Oracle .
Basil Bourque
1
@ChrisNeve JEP 150 approuvé par Brian Goetz , JSR 310 adopté à l'unanimité , un article technique publié par Oracle, et remplacement de l'ancien tutoriel Oracle date-heure par un nouveau tutoriel java.time .
Basil Bourque

Réponses:

198

Tu veux dire?

long millis = System.currentTimeMillis() % 1000;

BTW Windows n'autorise pas le voyage dans le temps jusqu'en 1969

C:\> date
Enter the new date: (dd-mm-yy) 2/8/1969
The system cannot accept the date entered.
Peter Lawrey
la source
8
Notez que si vous remontez dans le temps avant l'époque Unix, cela donnera une valeur négative alors que l'utilisation c.get(Calendar.MILLISECOND)ne devrait pas. Pensez toujours aux valises d'angle!
Jon Skeet
et si quelqu'un définit un fuseau horaire qui n'est pas sur la deuxième frontière ou ajoute une milliseconde bissextile, cela se brise. =))
Markus Mikkolainen
35
Java ne prend pas en charge les voyages dans le temps.
R. Martinho Fernandes
1
@MarkusMikkolainen: Non, System.currentTimeMillis()n'est pas affecté par les fuseaux horaires.
Jon Skeet
1
@PeterLawrey: Eh bien, cela pourrait ou non. Cela dépend de la mise en œuvre. Extrait de la documentation pour Date: "Une seconde est représentée par un entier compris entre 0 et 61; les valeurs 60 et 61 n'apparaissent que pendant les secondes intercalaires et même dans ce cas uniquement dans les implémentations Java qui suivent correctement les secondes intercalaires. En raison de la manière dont le saut secondes sont actuellement introduites, il est extrêmement improbable que deux secondes intercalaires se produisent dans la même minute, mais cette spécification suit les conventions de date et d'heure pour ISO C. "
Jon Skeet
25

Utiliser le calendrier

Calendar.getInstance().get(Calendar.MILLISECOND);

ou

Calendar c=Calendar.getInstance();
c.setTime(new Date()); /* whatever*/
//c.setTimeZone(...); if necessary
c.get(Calendar.MILLISECOND);

En pratique, je pense que cela équivaudra presque toujours à System.currentTimeMillis ()% 1000; à moins que quelqu'un ait des millisecondes bissextiles ou qu'un calendrier soit défini avec une époque et non sur une seconde frontière.

Markus Mikkolainen
la source
Le calendrier est déjà l'heure actuelle par défaut, et il n'y a pas de s à MILLISECOND.
kgautron
17
Calendar.getInstance().get(Calendar.MILLISECOND);
kgautron
la source
14

tl; dr

Vous demandez la fraction de seconde de l'heure actuelle en nombre de millisecondes ( sans compter à partir de l'époque).

Instant.now()                               // Get current moment in UTC, then…
       .get( ChronoField.MILLI_OF_SECOND )  // interrogate a `TemporalField`.

2017-04-25T03: 01: 14.113Z → 113

  1. Obtenez la fraction de seconde en nanosecondes (milliards).
  2. Divisez par mille pour tronquer en millisecondes (milliers).

Voir ce code exécuté en direct sur IdeOne.com .

Utilisation de java.time

La manière moderne est d'utiliser les classes java.time.

Capturez le moment actuel en UTC.

Instant.now()

Utilisez la Instant.getméthode pour rechercher la valeur de a TemporalField. Dans notre cas, ce que TemporalFieldnous voulons est ChronoField.MILLI_OF_SECOND.

int millis = Instant.now().get( ChronoField.MILLI_OF_SECOND ) ;  // Get current moment in UTC, then interrogate a `TemporalField`.

Ou faites le calcul vous-même.

Il est plus probable que vous le demandiez pour un fuseau horaire spécifique. La fraction de seconde est probablement la même qu'avec Instantmais il y a tellement d'anomalies avec les fuseaux horaires, j'hésite à faire cette hypothèse.

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

Interrogez pendant la fraction de seconde. La question demandait des millisecondes , mais les classes java.time utilisent une résolution plus fine de nanosecondes . Cela signifie que le nombre de nanosecondes va de 0 à 999 999 999.

long nanosFractionOfSecond = zdt.getNano();

Si vous voulez vraiment des millisecondes, tronquez les données les plus fines en les divisant par un million. Par exemple, une demi-seconde équivaut à 500 000 000 nanosecondes et également à 500 millisecondes.

long millis = ( nanosFractionOfSecond / 1_000_000L ) ;  // Truncate nanoseconds to milliseconds, by a factor of one million.

À propos de java.time

Le framework java.time est intégré à Java 8 et versions ultérieures. Ces classes supplantent les anciens gênants hérités des classes date-heure tels que java.util.Date, Calendar, et SimpleDateFormat.

Le projet Joda-Time , désormais en mode maintenance , conseille la migration vers les classes java.time .

Pour en savoir plus, consultez le didacticiel Oracle . Et recherchez Stack Overflow pour de nombreux exemples et explications. La spécification est JSR 310 .

Où obtenir les classes java.time?

Le projet ThreeTen-Extra étend java.time avec des classes supplémentaires. Ce projet est un terrain d'essai pour d'éventuels futurs ajouts à java.time. Vous trouverez peut - être des classes utiles ici, comme Interval, YearWeek, YearQuarteret plus .

Basil Bourque
la source
13

J'ai essayé quelques-uns ci-dessus mais ils semblent réinitialiser @ 1000

Celui-ci fonctionne définitivement et devrait également prendre en compte l'année

long millisStart = Calendar.getInstance().getTimeInMillis();

puis faites de même pour l'heure de la fin si nécessaire.

Assistant de haut calibre
la source
1
Répondre à la mauvaise question. C'est le millis de l'époque actuelle, pas la partie millis du temps actuel.
Sean Van Gorder
5
  1. long timeNow = System.currentTimeMillis();
  2. System.out.println(new Date(timeNow));

Ven 04 avril 14:27:05 PDT 2014

omarflorez
la source
3

Joda-Time

Je pense que vous pouvez utiliser Joda-Time pour ce faire. Jetez un œil à la DateTimeclasse et à sa getMillisOfSecondméthode. Quelque chose comme

int ms = new DateTime().getMillisOfSecond() ;
RNJ
la source
Erreur de compilation: " getMillis()a un accès protégé"; besoin d'utiliser à la get()place. Notez également que cela new DateTime(new Date())équivaut à écrire simplement new DateTime().
Jonik
La méthode millisOfSecondaccède à un objet et l'appel ultérieur à getextrait une primitive intde cet objet. Vous pouvez réduire les deux appels en utilisant la méthode getter de commodité, getMillisOfSecond. Joda-Time suit ce modèle pour plusieurs de ses propriétés.
Basil Bourque
1
Pour info, le projet Joda-Time est maintenant en mode maintenance , l'équipe conseillant la migration vers les classes java.time .
Basil Bourque
0

Dans Java 8, vous pouvez simplement faire

ZonedDateTime.now().toInstant().toEpochMilli()

renvoie: le nombre de millisecondes depuis l'époque de 1970-01-01T00: 00: 00Z

Aniket Thakur
la source
1
[A] Ce n'est pas ce que demandait la question. Dit expressément qu'ils ne veulent pas de compte de millisecondes depuis la date de référence de l'époque. [B] Vous pouvez raccourcir cela en supprimant le ZonedDateTime:Instant.now().toEpochMilli()
Basil Bourque
0

J'ai fait le test en utilisant java 8 Peu importe l'ordre que le constructeur prend toujours 0 millisecondes et le concat entre 26 et 33 millisecondes sous et itération d'une concaténation de 1000

J'espère que cela aidera à l'essayer avec votre idée

public void count() {

        String result = "";

        StringBuilder builder = new StringBuilder();

        long millis1 = System.currentTimeMillis(),
            millis2;

        for (int i = 0; i < 1000; i++) {
            builder.append("hello world this is the concat vs builder test enjoy");
        }

        millis2 = System.currentTimeMillis();

        System.out.println("Diff: " + (millis2 - millis1));

        millis1 = System.currentTimeMillis();

        for (int i = 0; i < 1000; i++) {
            result += "hello world this is the concat vs builder test enjoy";
        }

        millis2 = System.currentTimeMillis();

        System.out.println("Diff: " + (millis2 - millis1));
    }
Aldo Infanzon
la source
0

Java 8:

LocalDateTime toDate = LocalDateTime.now();
LocalDateTime fromDate = LocalDateTime.of(toDate.getYear(), toDate.getMonth(), 
toDate.getDayOfMonth(), 0, 0, 0);
long millis = ChronoUnit.MILLIS.between(fromDate, toDate);
Efren Villamagua
la source
1
Ne fonctionne pas dans certains fuseaux horaires. Dans certaines zones, à certaines dates, la journée peut ne pas commencer à 00h00. Et la journée peut ne pas durer 24 heures, ajouter ou sauter quelques heures ou minutes. La LocalDateTimeclasse ne peut pas représenter un moment, sans aucun concept de fuseau horaire ou de décalage par rapport à UTC, et ne peut donc pas suivre ces problèmes de fuseau horaire.
Basil Bourque le
0

Vous pouvez utiliser la classe java.util.Calendar pour obtenir l'heure en millisecondes. Exemple:

Calendar cal = Calendar.getInstance();
int milliSec = cal.get(Calendar.MILLISECOND);
// print milliSec

java.util.Date date = cal.getTime();
System.out.println("Output: " +  new SimpleDateFormat("yyyy/MM/dd-HH:mm:ss:SSS").format(date));
Rajat
la source