¿Cómo puedo obtener el recuento de milisegundos desde la medianoche para la corriente?

125

Tenga en cuenta que NO quiero millis de época. Quiero la cantidad de milisegundos actualmente en el reloj.

Entonces, por ejemplo, tengo este bit de código.

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

¿Hay alguna manera de obtener milisegundos con la fecha? Hay otra manera de hacer esto?

Nota: System.currentTimeMillis() me da millis de época, que no es lo que estoy buscando.

Lemonio
fuente
2
Quiere decir, "milisegundos en el segundo", por lo que el valor siempre está en el intervalo [0, 999], ¿correcto? @thinksteep lee la última oración.
Matt Ball el
@Lemonio Dar un ejemplo aclararía su pregunta.
Basil Bourque
Para su información, las viejas clases problemáticas de fecha y hora, como java.util.Dateahora son heredadas , suplantadas por las clases java.time .
Basil Bourque
Para su información, las viejas clases problemáticas de fecha y hora, como java.util.Dateahora son heredadas , suplantadas por las clases java.time . Ver Tutorial de Oracle .
Basil Bourque
1
@ChrisNeve JEP 150 avalado por Brian Goetz , JSR 310 adoptó por unanimidad , un artículo técnico publicado por Oracle, y el reemplazo del antiguo Tutorial de Oracle de fecha y hora con el nuevo Tutorial de java.time .
Basil Bourque

Respuestas:

198

¿Quieres decir?

long millis = System.currentTimeMillis() % 1000;

Por cierto, Windows no permite el viaje en el tiempo hasta 1969

C:\> date
Enter the new date: (dd-mm-yy) 2/8/1969
The system cannot accept the date entered.
Peter Lawrey
fuente
8
Tenga en cuenta que si viaja en el tiempo antes de la época de Unix, esto le dará un valor negativo mientras que el uso c.get(Calendar.MILLISECOND)no debería. ¡Piensa siempre en los rincones!
Jon Skeet
y si alguien define una zona horaria que no está en el segundo borde o agrega un salto de milisegundo, esto se rompe. =))
Markus Mikkolainen
35
Java no admite viajes en el tiempo.
R. Martinho Fernandes
1
@MarkusMikkolainen: No, System.currentTimeMillis()no se ve afectado por las zonas horarias.
Jon Skeet
1
@PeterLawrey: Bueno, podría o no. Depende de la implementación. De los documentos para Date: "Un segundo está representado por un número entero de 0 a 61; los valores 60 y 61 se producen solo durante los segundos bisiestos e incluso en las implementaciones de Java que realmente rastrean los segundos bisiestos correctamente. Debido a la manera en que el salto actualmente se introducen segundos, es extremadamente improbable que ocurran dos segundos bisiestos en el mismo minuto, pero esta especificación sigue las convenciones de fecha y hora para ISO C. "
Jon Skeet
25

Usar calendario

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

o

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

En la práctica, creo que casi siempre será igual a System.currentTimeMillis ()% 1000; a menos que alguien tenga un salto de milisegundos o algún calendario se defina con una época que no esté en un segundo límite.

Markus Mikkolainen
fuente
El calendario ya es la hora actual por defecto, y no hay s en MILLISECOND.
kgautron
17
Calendar.getInstance().get(Calendar.MILLISECOND);
kgautron
fuente
14

tl; dr

Solicita la fracción de un segundo del tiempo actual como un número de milisegundos ( sin contar desde la época).

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

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

  1. Obtenga el segundo fraccional en nanosegundos (miles de millones).
  2. Divide entre mil para truncar a milisegundos (miles).

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

Usando java.time

La forma moderna es con las clases java.time.

Capture el momento actual en UTC.

Instant.now()

Use el Instant.getmétodo para interrogar el valor de a TemporalField. En nuestro caso, lo TemporalFieldque queremos es ChronoField.MILLI_OF_SECOND.

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

O haz los cálculos tú mismo.

Lo más probable es que esté pidiendo esto para una zona horaria específica. Es probable que la fracción de segundo sea la misma que con Instantpero hay tantas anomalías con las zonas horarias que dudo en hacer esa suposición.

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

Interrogar por el segundo fraccional. La pregunta pedía milisegundos , pero las clases java.time usan una resolución más fina de nanosegundos . Eso significa que el número de nanosegundos variará de 0 a 999,999,999.

long nanosFractionOfSecond = zdt.getNano();

Si realmente quieres milisegundos, trunca los datos más finos dividiéndolos por un millón. Por ejemplo, medio segundo son 500,000,000 nanosegundos y también 500 milisegundos.

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

Sobre java.time

El marco java.time está integrado en Java 8 y versiones posteriores. Estas clases suplantar la vieja problemáticos heredados clases de fecha y hora como java.util.Date, Calendar, y SimpleDateFormat.

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

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

¿Dónde obtener las clases java.time?

El proyecto ThreeTen-Extra extiende java.time con clases adicionales. Este proyecto es un campo de pruebas para posibles adiciones futuras a java.time. Usted puede encontrar algunas clases útiles aquí, como Interval, YearWeek, YearQuarter, y más .

Albahaca Bourque
fuente
13

Intenté algunos de los anteriores, pero parecen reiniciarse @ 1000

Este definitivamente funciona, y también debe tener en cuenta el año

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

y luego haga lo mismo para la hora de finalización si es necesario.

Asistente de alto calibre
fuente
1
Respondiendo la pregunta equivocada. Eso es millis actual de época, no la milis parte del tiempo actual.
Sean Van Gorder
5
  1. long timeNow = System.currentTimeMillis();
  2. System.out.println(new Date(timeNow));

Vie 04 abr 14:27:05 PDT 2014

omarflorez
fuente
3

Joda-Time

Creo que puedes usar Joda-Time para hacer esto. Echa un vistazo a la DateTimeclase y su getMillisOfSecondmétodo. Algo como

int ms = new DateTime().getMillisOfSecond() ;
RNJ
fuente
Error de compilación: " getMillis()tiene acceso protegido"; necesita usar get()en su lugar. También tenga en cuenta que new DateTime(new Date())es equivalente a escribir simplemente new DateTime().
Jonik
El método millisOfSecondaccede a un objeto y la llamada adicional a getextrae una primitiva intde ese objeto. Puede contraer las dos llamadas utilizando el método de obtención de conveniencia, getMillisOfSecond. Joda-Time sigue este patrón para muchas de sus propiedades.
Basil Bourque
1
Para su información, el proyecto Joda-Time ahora está en modo de mantenimiento , y el equipo aconseja migrar a las clases java.time .
Basil Bourque
0

En Java 8 simplemente puedes hacer

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

devuelve: el número de milisegundos desde la época de 1970-01-01T00: 00: 00Z

Aniket Thakur
fuente
1
[A] Esto no es lo que pidió la pregunta. Expresamente dice que no quieren un recuento de milisegundos desde la fecha de referencia de la época. [B] Podrías acortar eso dejando caer el ZonedDateTime:Instant.now().toEpochMilli()
Basil Bourque
0

Hice la prueba usando Java 8 No importará el orden en que el constructor siempre toma 0 milisegundos y el concat entre 26 y 33 milisegundos debajo y la iteración de una concatenación de 1000

Espero que ayude a probarlo con tu ide

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
fuente
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
fuente
1
No funciona en algunas zonas horarias. En algunas zonas, en algunas fechas, el día puede no comenzar a las 00:00:00. Y el día puede no durar 24 horas, puede agregar u omitir algunas horas o minutos. La LocalDateTimeclase no puede representar un momento, sin ningún concepto de zona horaria o desplazamiento desde UTC, y por lo tanto no puede rastrear estos problemas de zona horaria.
Basil Bourque
0

Puede usar la clase java.util.Calendar para obtener tiempo en milisegundos. Ejemplo:

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
fuente