web-dev-qa-db-fra.com

Convertir l'horodatage long au format de date normal

Dans mon application Web, la date et l'heure de certaines activités d'un utilisateur sont stockées (dans une base de données) sous la forme d'un horodatage Long qui, lorsqu'il est affiché à l'utilisateur, doit être converti au format date/heure normal. 

(En fait, ma base de données Cassandra stocke l'horodatage du moment où une colonne a été écrite, sous forme de valeur longue (microsecondes depuis 1970) que je vais utiliser pour connaître l'heure de l'activité de l'utilisateur correspondant)

J'utilise JSF 2.0 (+ primefaces) qui, à mon avis, dispose de convertisseurs utiles pour cette conversion? Ou sinon, comment puis-je, au mieux, réaliser ces conversions? 

17
Rajat Gupta

Laissez-moi vous proposer cette solution. Donc, dans votre haricot géré, faites ceci

public String convertTime(long time){
    Date date = new Date(time);
    Format format = new SimpleDateFormat("yyyy MM dd HH:mm:ss");
    return format.format(date);
}

vous pouvez le faire dans votre page JSF (en supposant que foo est l'objet qui contient votre time)

<h:dataTable value="#{myBean.convertTime(myBean.foo.time)}" />

Si vous avez plusieurs pages qui souhaitent utiliser cette méthode, vous pouvez le placer dans un abstract class et demander à votre bean géré d'étendre ce abstract class

EDIT: heure de retour avec TimeZone

malheureusement, je pense que SimpleDateFormat formatera toujours l'heure en heure locale, nous ne pouvons donc plus utiliser SimpleDateFormat. Donc, pour afficher l'heure dans différents fuseaux horaires, nous pouvons le faire

public String convertTimeWithTimeZome(long time){
    Calendar cal = Calendar.getInstance();
    cal.setTimeZone(TimeZone.getTimeZone("UTC"));
    cal.setTimeInMillis(time);
    return (cal.get(Calendar.YEAR) + " " + (cal.get(Calendar.MONTH) + 1) + " " 
            + cal.get(Calendar.DAY_OF_MONTH) + " " + cal.get(Calendar.HOUR_OF_DAY) + ":"
            + cal.get(Calendar.MINUTE));

}

Une meilleure solution consiste à utiliser JodaTime. À mon avis, cette API est bien meilleure que celle de Calendar (plus légère, plus rapide et plus fonctionnelle). De plus, Calendar.Month de January est 0, ce qui oblige le développeur à ajouter 1 au résultat et vous devez formater le temps vous-même. En utilisant JodaTime, vous pouvez résoudre tout cela. Corrigez-moi si je me trompe, mais je pense que JodaTime est incorporé dans JDK7

55
Thang Pham

Vous ne savez pas si JSF fournit une fonctionnalité intégrée, mais vous pouvez utiliser le constructeur de Java.sql.Date pour convertir un objet de date: http://download.Oracle.com/javase/1.5.0/docs/api/Java/sql/ Date.html # Date (long)

Ensuite, vous devriez pouvoir utiliser les fonctionnalités de niveau supérieur fournies par Java SE et Java EE pour afficher et formater la date extraite. Vous pouvez instancier un Java.util.Calendar et définir explicitement l'heure: http://download.Oracle.com/javase/1.5.0/docs/api/Java/util/Calendar.html#setTime(Java.util.Date)

EDIT: Les composants JSF ne doivent pas prendre en charge la conversion. Votre couche d'accès aux données (couche de persistance) devrait s'en charger. En d'autres termes, vos composants JSF ne doivent pas gérer les attributs de type long, mais uniquement les attributs de type Date ou Calendar.

1
home

Java.time

    ZoneId usersTimeZone = ZoneId.of("Asia/Tashkent");
    Locale usersLocale = Locale.forLanguageTag("ga-IE");
    DateTimeFormatter formatter = DateTimeFormatter.ofLocalizedDateTime(FormatStyle.MEDIUM)
            .withLocale(usersLocale);

    long microsSince1970 = 1_512_345_678_901_234L;
    long secondsSince1970 = TimeUnit.MICROSECONDS.toSeconds(microsSince1970);
    long remainingMicros = microsSince1970 - TimeUnit.SECONDS.toMicros(secondsSince1970);
    ZonedDateTime dateTime = Instant.ofEpochSecond(secondsSince1970, 
                    TimeUnit.MICROSECONDS.toNanos(remainingMicros))
            .atZone(usersTimeZone);
    String dateTimeInUsersFormat = dateTime.format(formatter);
    System.out.println(dateTimeInUsersFormat);

L'extrait ci-dessus imprime:

4 décembre 2017 05:01:18

“Noll” est gaélique pour décembre, votre utilisateur devrait donc être heureux. Sauf que très peu de personnes parlant le gaélique vivent à Tachkent, veuillez donc spécifier vous-même le fuseau horaire et les paramètres régionaux de l'utilisateur.

Je prends au sérieux que votre base de données contient des microsecondes. Si la seconde précision convient, vous pouvez vous passer de remainingMicros et utiliser simplement la fonction one-arg Instant.ofEpochSecond(), ce qui raccourcira le code de quelques lignes. Étant donné que Instant et ZonedDateTime prennent en charge la précision en nanosecondes, j'ai trouvé très correct de conserver la précision complète de votre horodatage. Si votre horodatage était en millisecondes plutôt que microsecondes (ce qui est souvent le cas), vous pouvez simplement utiliser Instant.ofEpochMilli().

Les réponses utilisant Date, Calendar et/ou SimpleDateFormat étaient acceptables lorsque cette question a été posée il y a 7 ans. Aujourd'hui, ces classes sont toutes obsolètes depuis longtemps, et nous avons tellement mieux avec Java.time, l'API de date et heure moderne de Java.

Pour la plupart des utilisations, je vous recommande d'utiliser les formats localisés intégrés comme je le fais dans le code. Vous pouvez essayer de passer SHORT, LONG ou FULL pour le style de format. Vous pouvez même spécifier le style de format de la date et de l’heure séparément en utilisant une méthode surchargée ofLocalizedDateTime. Si un format spécifique est requis (cela a été demandé dans une question en double ), vous pouvez avoir ceci:

    DateTimeFormatter formatter = DateTimeFormatter.ofPattern("HH:mm:ss, dd/MM/uuuu");

En utilisant ce formateur à la place, nous obtenons

05:01:18, 04/12/2017

Link:Tutoriel Oracle: Date Time expliquant comment utiliser Java.time.

1
Ole V.V.

Pour afficher les zéros au début des heures, minutes et secondes, utilisez le code modifié ci-dessous. L'astuce ici est que nous convertissons (ou plus précisément, formalisons) l'entier en chaîne de sorte qu'elle affiche le zéro non significatif le cas échéant: 

public String convertTimeWithTimeZome(long time) {
        Calendar cal = Calendar.getInstance();
        cal.setTimeZone(TimeZone.getTimeZone("UTC"));
        cal.setTimeInMillis(time);
        String curTime = String.format("%02d:%02d:%02d", cal.get(Calendar.HOUR_OF_DAY), cal.get(Calendar.MINUTE), cal.get(Calendar.SECOND));
        return curTime;
    }

Le résultat serait comme: 00:01:30

0
Irfan Raza