¿Cómo convertir currentTimeMillis a una fecha en Java?

140

Tengo milisegundos en cierto archivo de registro generado en el servidor, también conozco la configuración regional desde donde se generó el archivo de registro, mi problema es convertir milisegundos a la fecha en el formato especificado. El procesamiento de ese registro está ocurriendo en el servidor ubicado en una zona horaria diferente. Mientras que la conversión al programa "SimpleDateFormat" toma la fecha de la máquina ya que la fecha formateada no representa la hora correcta del servidor. ¿Hay alguna manera de manejar esto con elegancia?

long yourmilliseconds = 1322018752992l;
        //1322018752992-Nov 22, 2011 9:25:52 PM 

SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss,SSS",Locale.US);

GregorianCalendar calendar = new GregorianCalendar(TimeZone.getTimeZone("US/Central"));
calendar.setTimeInMillis(yourmilliseconds);

System.out.println("GregorianCalendar -"+sdf.format(calendar.getTime()));

DateTime jodaTime = new DateTime(yourmilliseconds, 
                    DateTimeZone.forTimeZone(TimeZone.getTimeZone("US/Central")));
DateTimeFormatter parser1 = DateTimeFormat.forPattern("yyyy-MM-dd HH:mm:ss,SSS");

System.out.println("jodaTime "+parser1.print(jodaTime));

Salida:

Gregorian Calendar -2011-11-23 08:55:52,992
jodaTime 2011-11-22 21:25:52,992
Amit
fuente
No confunda Locale con zona horaria. Totalmente separado La configuración regional determina el idioma humano para el nombre de los meses y días, y las normas culturales, como el orden de las partes, como el mes, el día, etc. Una zona horaria está desviada de UTC más reglas para manejar anomalías como el horario de verano.
Basil Bourque
¿Era el problema que el número de milisegundos era un recuento no desde 1970-01-01T00: 00: 00Z sino desde otro momento?
Basil Bourque
Para su información, tanto las clases terribles pasados de fecha y hora ( GregorianCalendar, SimpleDateFormat, etc.) y la excelente biblioteca Joda-Time están sustituidas por las modernas java.time clases.
Basil Bourque

Respuestas:

115
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(timeStamp);

int mYear = calendar.get(Calendar.YEAR);
int mMonth = calendar.get(Calendar.MONTH);
int mDay = calendar.get(Calendar.DAY_OF_MONTH);
Faisal Ashraf
fuente
Tuve que configurar el Calendario como final para que funcione. final Calendar calendar = Calendar.getInstance();
Victor Augusto el
44
Los objetos de calendario generalmente se consideran bastante grandes, por lo que deben evitarse cuando sea posible. Un objeto Date será mejor suponiendo que tenga la funcionalidad que necesita. "Fecha fecha = nueva Fecha (millis);" proporcionado en la otra respuesta por el usuario AVD será la mejor ruta :)
Dick Lucas
1
De alguna manera, porque 1515436200000l, me estoy poniendo calendar.get(Calendar.MONTH))como 0!
Sajib Acharya
Para su información, las antiguas clases de fecha y hora terriblemente problemáticas como java.util.Date, java.util.Calendary java.text.SimpleDateFormatahora son heredadas , suplantadas por las clases java.time integradas en Java 8 y posteriores. Ver Tutorial de Oracle .
Basil Bourque
2
@SajibAcharya Tenga en cuenta que las instancias para Calendar.MONTH comienzan en 0; necesita agregar uno para obtener el mes "real" tal como lo conocemos. Ejemplo: 0 = enero, 1 = febrero, 2 = marzo, etc.
shagberg
256

Puede usar java.util.Dateclass y luego usar SimpleDateFormatpara formatear el Date.

Date date=new Date(millis);

Podemos usar el paquete java.time (tutorial): API DateTime introducidas en Java SE 8

var instance = java.time.Instant.ofEpochMilli(millis);
var localDateTime = java.time.LocalDateTime
                        .ofInstant(instance, java.time.ZoneId.of("Asia/Kolkata"));
var zonedDateTime = java.time.ZonedDateTime
                            .ofInstant(instance,java.time.ZoneId.of("Asia/Kolkata"));

// Format the date

var formatter = java.time.format.DateTimeFormatter.ofPattern("u-M-d hh:mm:ss a O");
var string = zonedDateTime.format(formatter);
Adatapost
fuente
2
Mucho más eficiente.
Chad Bingham
2
No No todos los métodos de java.util.Datese deprecian. (Se han mejorado las API de fecha y hora en los JDK8 java.time)
adatapost
1
@RafaelZeffa, el constructor '' 'Fecha (fecha larga)' '' no está en desuso
Gugelhupf
El objeto Date se proporciona por compatibilidad con versiones anteriores. Mejor usar el calendario como se sugirió anteriormente.
Ton Snoei
2
Para su información, las antiguas clases de fecha y hora terriblemente problemáticas como java.util.Date, java.util.Calendary java.text.SimpleDateFormatahora son heredadas , suplantadas por las clases java.time integradas en Java 8 y posteriores. Ver Tutorial de Oracle .
Basil Bourque
24

tl; dr

Instant.ofEpochMilli( 1_322_018_752_992L )     // Parse count of milliseconds-since-start-of-1970-UTC into an `Instant`.
       .atZone( ZoneId.of( "Africa/Tunis" ) )  // Assign a time zone to the `Instant` to produce a `ZonedDateTime` object.

Detalles

Las otras respuestas usan clases pasadas de moda o incorrectas.

Evite las antiguas clases de fecha y hora, como java.util.Date/.Calendar. Han demostrado ser pobremente diseñados, confusos y problemáticos.

java.time

El framework java.time viene integrado en Java 8 y versiones posteriores. Gran parte de la funcionalidad es compatible con Java 6 y 7 y se adapta aún más a Android . Hecho por algunas de las mismas personas que habían hecho Joda-Time .

Un Instantes un momento en la línea de tiempo en UTC con una resolución de nanosegundos . Su época es el primer momento de 1970 en UTC.

Suponiendo que sus datos de entrada son un recuento de milisegundos desde 1970-01-01T00: 00: 00Z (no está claro en la pregunta), entonces podemos instanciar fácilmente un Instant.

Instant instant = Instant.ofEpochMilli( 1_322_018_752_992L );

instant.toString (): 2011-11-23T03: 25: 52.992Z

El Zen esa norma ISO 8601 cadena con formato es la abreviatura de Zuluy significa UTC .

Aplique una zona horaria utilizando un nombre de zona horaria adecuado para obtener a ZonedDateTime.

ZoneId zoneId = ZoneId.of( "Asia/Kolkata" ) ;
ZonedDateTime zdt = instant.atZone( zoneId );

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

Asia/Kolkata zona horaria ?

Supongo que su zona horaria de India afecta su código. Vemos aquí que ajustarse a la Asia/Kolkatazona horaria representa la misma hora del día que informa, 08:55que es cinco horas y media antes de nuestro valor UTC 03:25.

2011-11-23T08: 55: 52.992 + 05: 30 [Asia / Kolkata]

Zona predeterminada

Puede aplicar la zona horaria predeterminada actual de la JVM. Tenga en cuenta que el valor predeterminado puede cambiar en cualquier momento durante el tiempo de ejecución . Cualquier código en cualquier subproceso de cualquier aplicación dentro de la JVM puede cambiar el valor predeterminado actual. Si es importante, solicite al usuario su zona horaria deseada / esperada.

ZoneId zoneId = ZoneId.systemDefault();
ZonedDateTime zdt = ZonedDateTime.ofInstant( instant , zoneId );

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 .

Con un controlador JDBC que cumpla con JDBC 4.2 o posterior, puede intercambiar objetos java.time directamente con su base de datos. No necesita cadenas ni clases java.sql. *.

¿Dónde obtener las clases java.time?

  • Java SE 8 , Java SE 9 y posterior
    • Incorporado.
    • Parte de la API Java estándar con una implementación integrada.
    • Java 9 agrega algunas características menores y correcciones.
  • Java SE 6 y Java SE 7
    • Gran parte de la funcionalidad java.time se transfiere a Java 6 y 7 en ThreeTen-Backport .
  • Androide
    • Versiones posteriores de las implementaciones de paquetes de Android de las clases java.time.
    • Para principios de Android, el ThreeTenABP proyecto se adapta ThreeTen-Backport (mencionado anteriormente). Ver Cómo utilizar ThreeTenABP ... .

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
¿Sería fácil convertir el Instant que recomienda arriba a la zona horaria local que es la predeterminada en un dispositivo (por ejemplo, un teléfono inteligente)?
AJW
1
@AJW Sí. Llamar ZoneId.systemDefault(). Vea la nueva sección agregada al final de mi respuesta.
Basil Bourque
Excelente, lo intentaré.
AJW
14

La forma más fácil de hacer esto es usar la clase Joda DateTime y especificar tanto la marca de tiempo en milisegundos como la DateTimeZone que desee.

Recomiendo evitar las clases Java Date y Calendar incorporadas; son terribles.

Cameron Skinner
fuente
GorgianCalender no funcionó ... por cualquier razón, tomó la zona horaria predeterminada del sistema. Joda funcionó perfectamente.
Amit
Avíseme mirando el código de muestra si podemos hacer algo diferente con Gregorian
Amit el
1
Para su información, el proyecto Joda-Time ahora está en modo de mantenimiento , y aconseja la migración a las clases java.time . Ver Tutorial de Oracle .
Basil Bourque
13

Si el valor de milis es el número de milis desde el 1 de enero de 1970 GMT, como es estándar para la JVM, entonces eso es independiente de la zona horaria. Si desea formatearlo con una zona horaria específica, simplemente puede convertirlo en un objeto GregorianCalendar y establecer la zona horaria. Después de eso hay numerosas formas de formatearlo.

Cuenta
fuente
1
Este es el código de muestra con GregorianCalendar y Joda, obtengo resultados correctos con Joda pero no con Gregorian GregorianCalendar calendar = new GregorianCalendar (TimeZone.getTimeZone ("US / Central")); calendar.setTimeInMillis (yourmilliseconds); DateTime jodaTime = new DateTime (yourmilliseconds, DateTimeZone.forTimeZone (TimeZone.getTimeZone ("US / Central"))); DateTimeFormatter parser1 = DateTimeFormat.forPattern ("aaaa-MM-dd HH: mm: ss, SSS");
Amit
Establecer la zona horaria en el objeto de calendario no funcionó, pero establecerlo en el objeto formateador de fecha sí funcionó.
Bill
¿Qué es DateTime y DateTimeFormatter?
SweetWisher ツ
11

Mi solución

public class CalendarUtils {

    public static String dateFormat = "dd-MM-yyyy hh:mm";
    private static SimpleDateFormat simpleDateFormat = new SimpleDateFormat(dateFormat);

    public static String ConvertMilliSecondsToFormattedDate(String milliSeconds){
        Calendar calendar = Calendar.getInstance();
        calendar.setTimeInMillis(Long.parseLong(milliSeconds));
        return simpleDateFormat.format(calendar.getTime());
    }
}
Siddarth Kanted
fuente
6

Lo hago así:

static String formatDate(long dateInMillis) {
    Date date = new Date(dateInMillis);
    return DateFormat.getDateInstance().format(date);
}

También se puede usar getDateInstance(int style)con los siguientes parámetros:

DateFormat.SHORT

DateFormat.MEDIUM

DateFormat.LONG

DateFormat.FULL

DateFormat.DEFAULT

Yogesh Umesh Vaity
fuente
5

La manera más fácil:

private String millisToDate(long millis){

    return DateFormat.getDateInstance(DateFormat.SHORT).format(millis);
    //You can use DateFormat.LONG instead of SHORT

}
Joaquin Iurchuk
fuente
2

A continuación se muestra mi solución para obtener la fecha de milisegundos a formato de fecha. Tienes que usar Joda Library para ejecutar este código.

import java.util.GregorianCalendar;
import java.util.TimeZone;

import org.joda.time.DateTime;
import org.joda.time.DateTimeZone;
import org.joda.time.format.DateTimeFormat;
import org.joda.time.format.DateTimeFormatter;

public class time {

    public static void main(String args[]){

        String str = "1431601084000";
        long geTime= Long.parseLong(str);
        GregorianCalendar calendar = new GregorianCalendar(TimeZone.getTimeZone("US/Central"));
        calendar.setTimeInMillis(geTime);
        DateTime jodaTime = new DateTime(geTime, 
               DateTimeZone.forTimeZone(TimeZone.getTimeZone("US/Central")));
        DateTimeFormatter parser1 = DateTimeFormat.forPattern("yyyy-MM-dd");
        System.out.println("Get Time : "+parser1.print(jodaTime));

   }
}
Archit
fuente
1

Puedes probar java.time api;

        Instant date = Instant.ofEpochMilli(1549362600000l);
        LocalDateTime utc = LocalDateTime.ofInstant(date, ZoneOffset.UTC);
Narendar Reddy M
fuente