Obtenir le composant Heure d'une Date ou d'un calendrier Java


Existe-t-il un moyen simple ou élégant de saisir uniquement l'heure de la journée (heures/minutes/secondes/millisecondes) d'une date Java (ou d'un calendrier, cela n'a vraiment pas d'importance pour moi)? Je cherche un bon moyen de considérer séparément la date (année/mois/jour) et l'heure de la journée, mais pour autant que je sache, je suis coincé avec l'accès à chaque champ séparément.

Je sais que je pourrais écrire ma propre méthode pour saisir individuellement les champs qui m'intéressent, mais je le ferais comme une méthode utilitaire statique, ce qui est laid. De plus, je sais que les objets Date et Calendar ont une précision de la milliseconde, mais je ne vois pas de moyen d'accéder au composant millisecondes dans les deux cas.


Edit: {[12] } Je n'étais pas clair à ce sujet: utiliser l'un des Date:: getTime () ou Calendar::getTimeInMillis ne m'est pas terriblement utile, car ceux-ci renvoient le nombre de millisecondes depuis l'époque (représentée par cette Date ou ce calendrier), ce qui ne sépare pas réellement le heure du jour du reste de information.

La réponse de@Jherico est la chose la plus proche, je pense, mais c'est certainement quelque chose que je devrais encore rouler dans une méthode que j'écris moi-même. Ce n'est pas exactement ce que je vais faire, car il comprend toujours des heures, des minutes et des secondes dans la valeur de milliseconde retournée - bien que je puisse probablement le faire fonctionner à mes fins.

Je pense toujours à chaque composant comme séparé, bien que bien sûr, ils ne le soient pas. Vous pouvez écrire un temps comme le nombre de millisecondes depuis un date de référence arbitraire, ou vous pouvez écrire exactement la même heure que year/month/day hours:minutes:seconds.milliseconds.

Ce n'est pas à des fins d'affichage. Je sais comment utiliser un DateFormat pour faire de jolies chaînes date.


Edit 2: Ma question initiale est née d'un petit ensemble de fonctions utilitaires que je me suis retrouvé à écrire - par exemple:

  • Vérifier si deux Date s représentent une date-heure le même jour;
  • Vérifier si une date est dans une plage spécifiée par deux autres dates, mais parfois en vérifiant inclusivement, et parfois non, en fonction de la composante temps.

Joda Time a-t-il ce type de fonctionnalité?


Edit 3: La question de @Jon concernant ma deuxième exigence, juste pour clarifier: La deuxième exigence est le résultat de l'utilisation de mes Dates pour représenter parfois des jours entiers-où la composante temps n'a pas d'importance du tout - et représente parfois une date-heure (qui est, IMO, le mot le plus précis pour quelque chose qui contient year/month/day et hours:minutes:seconds:...).

Lorsqu'une Date représente un jour entier, ses parties temporelles sont nulles (par exemple, le "composant temporel" de la Date est minuit) mais la sémantique dicte que la vérification de la plage est effectuée inclusivement à la date de fin. Parce que je laisse juste ce contrôle à Jour:: before et Date:: after, je dois ajouter 1 jour à la date de fin - d'où le boîtier spécial pour quand le composant heure d'une Date est nul.

J'espère que cela n'a pas rendu les choses moins claires.

Author: Matt Ball, 2009-09-01

10 answers

D'accord, je sais que c'est une réponse prévisible, mais... utilisez Joda Time . Cela a des représentations distinctes pour "une date", "un instant", "une heure de la journée", etc. C'est une API plus riche et généralement plus saine que les classes intégrées, IMO.

Si c'est le seulement bit de manipulation de date/heure qui vous intéresse, cela peut être exagéré... mais si vous utilisez l'API date/heure intégrée pour quelque chose d'important, je recommanderais fortement de vous en éloigner pour Joda dès que vous le pouvez.

En aparté, vous devriez considérer le fuseau horaire qui vous intéresse. A Calendar a un fuseau horaire associé, mais pas a Date (il représente juste un instant dans le temps, mesuré en millisecondes à partir de l'époque Unix).

 11
Author: Jon Skeet, 2009-09-01 16:15:56

Extraire la partie de temps de la journée devrait être une question d'obtenir le nombre de millisecondes restant lorsque vous divisez par le nombre de millisecondes par jour.

long MILLIS_PER_DAY = 24 * 60 * 60 * 1000;
Date now = Calendar.getInstance().getTime();
long timePortion = now.getTime() % MILLIS_PER_DAY;

Alternativement, envisagez d'utiliser joda-time, une bibliothèque de temps plus complète.

 8
Author: Jherico, 2009-09-01 16:19:15

Pour répondre à une partie de celui-ci, l'accès au composant milliseconde se fait comme ceci:

long mill = Calendar.getInstance().getTime();

Je ne sais pas ce que vous voulez faire avec les détails, mais vous pouvez utiliser java.texte.Classe SimpleDateFormat si c'est pour la sortie de texte.

 2
Author: PHeath, 2009-09-01 16:09:16

Vous pouvez appeler la fonction getTimeInMillis() sur un objet Calendar pour obtenir le temps en millisecondes. Vous pouvez appeler get (Calendrier.MILLISECONDE) sur un objet calendrier pour obtenir les millisecondes de la seconde. Si vous souhaitez afficher l'heure d'un objet Date ou Calendrier, utilisez la classe DateFormat. Exemple: DateFormat.getTimeInstance().format(maintenant). Il existe également une classe SimpleDateFormat que vous pouvez utiliser.

 1
Author: Dan Polites, 2009-09-01 16:12:28

Pour obtenir juste l'heure en utilisant Joda-Time, utilisez la classe org.joda.time.LocalTimecomme décrit dans cette question, Joda-Time, Time without date.

Comme pour comparer les dates uniquement tout en ignorant efficacement le temps, dans Joda-Time, appelez la méthode withTimeAtStartOfDay() sur chaque instance DateTime pour définir une valeur de temps identique. Voici un exemple de code utilisant Joda-Time 2.3, similaire à ce que j'ai posté sur une autre réponse aujourd'hui.

    // © 2013 Basil Bourque. This source code may be used freely forever by anyone taking full responsibility for doing so.

    // Joda-Time - The popular alternative to Sun/Oracle's notoriously bad date, time, and calendar classes bundled with Java 7 and earlier.
    // http://www.joda.org/joda-time/

    // Joda-Time will become outmoded by the JSR 310 Date and Time API introduced in Java 8.
    // JSR 310 was inspired by Joda-Time but is not directly based on it.
    // http://jcp.org/en/jsr/detail?id=310

    // By default, Joda-Time produces strings in the standard ISO 8601 format.
    // https://en.wikipedia.org/wiki/ISO_8601

    // Capture one moment in time.
    org.joda.time.DateTime now = new org.joda.time.DateTime();
    System.out.println("Now: " + now);

    // Calculate approximately same time yesterday.
    org.joda.time.DateTime yesterday = now.minusDays(1);
    System.out.println("Yesterday: " + yesterday);

    // Compare dates. A DateTime includes time (hence the name).
    // So effectively eliminate the time by setting to start of day.
    Boolean isTodaySameDateAsYesterday = now.withTimeAtStartOfDay().isEqual(yesterday.withTimeAtStartOfDay());
    System.out.println("Is today same date as yesterday: " + isTodaySameDateAsYesterday);

    org.joda.time.DateTime halloweenInUnitedStates = new org.joda.time.DateTime(2013, 10, 31, 0, 0);
    Boolean isFirstMomentSameDateAsHalloween = now.withTimeAtStartOfDay().isEqual(halloweenInUnitedStates.withTimeAtStartOfDay());
    System.out.println("Is now the same date as Halloween in the US: " + isFirstMomentSameDateAsHalloween);
 1
Author: Basil Bourque, 2017-05-23 11:54:33

Si tout ce qui vous préoccupe est de l'obtenir dans une chaîne pour l'afficher ou l'enregistrer, créez simplement un SimpleDateFormat qui affiche uniquement la partie temporelle, comme new SimpleDateFormat("HH:mm:ss"). La date est toujours dans l'objet Date, bien sûr, mais vous vous en fichez.

Si vous voulez faire de l'arithmétique dessus, comme prendre deux objets Date et trouver combien de secondes d'intervalle ils sont tout en ignorant la partie date, de sorte que "2009-09-01 11:00:00" moins "1941-12-07 09:00:00" équivaut à 2 heures, alors je pensez que vous devez utiliser une solution comme celle de Jherico: obtenez le temps long et prenez-le module 1 jour.

 0
Author: Jay, 2009-09-01 16:27:28

Pourquoi voulez-vous les séparer? Si vous voulez faire de l'arithmétique avec la partie temps, vous aurez rapidement des ennuis. Si vous sortez 23h59 et ajoutez une minute, maintenant que votre heure et votre jour sont séparés, vous vous êtes foutu yourself vous aurez une heure invalide et une date incorrecte.

Si vous souhaitez simplement les afficher, l'application de différents formats de date simples devrait vous donner exactement ce que vous voulez.

Si vous voulez manipuler la date, je vous suggère d'obtenir le long valeurs et base tout de cela. À tout moment, vous pouvez prendre autant de temps et appliquer un format pour obtenir les minutes/heures/secondes à afficher assez facilement.

Mais je suis juste un peu préoccupé par le concept de manipulation du jour et de l'heure séparément, semble ouvrir une boîte de vers. (Sans même mentionner les problèmes de fuseau horaire!).

Je suis assez sûr que c'est pourquoi Java n'a pas un moyen facile de le faire.

 0
Author: Bill K, 2009-09-01 16:28:44

Trouvez ci-dessous une solution qui utilise Joda Time et prend en charge les fuseaux horaires. Ainsi, vous obtiendrez la date et l'heure (dans currentDate et currentTime) dans le fuseau horaire actuellement configuré dans la JVM.

Veuillez noter que le temps Joda ne prend pas en charge les secondes intercalaires . Ainsi, vous pouvez être à environ 26 ou 27 secondes de la valeur réelle. Cela ne sera probablement résolu que dans les 50 prochaines années, lorsque l'erreur accumulée sera plus proche de 1 min et que les gens commenceront à s'en soucier.

Voir aussi: https://en.wikipedia.org/wiki/Leap_second

/**
 * This class splits the current date/time (now!) and an informed date/time into their components:
 * <lu>
 *     <li>schedulable: if the informed date/time is in the present (now!) or in future.</li>
 *     <li>informedDate: the date (only) part of the informed date/time</li>
 *     <li>informedTime: the time (only) part of the informed date/time</li>
 *     <li>currentDate: the date (only) part of the current date/time (now!)</li>
 *     <li>currentTime: the time (only) part of the current date/time (now!)</li>
 * </lu>
 */
public class ScheduleDateTime {
    public final boolean schedulable;
    public final long millis;
    public final java.util.Date informedDate;
    public final java.util.Date informedTime;
    public final java.util.Date currentDate;
    public final java.util.Date currentTime;

    public ScheduleDateTime(long millis) {
        final long now = System.currentTimeMillis();
        this.schedulable = (millis > -1L) && (millis >= now);

        final TimeZoneUtils tz = new TimeZoneUtils();

        final java.util.Date          dmillis   = new java.util.Date( (millis > -1L) ? millis : now );
        final java.time.ZonedDateTime zdtmillis = java.time.ZonedDateTime.ofInstant(dmillis.toInstant(), java.time.ZoneId.systemDefault());
        final java.util.Date          zdmillis  = java.util.Date.from(tz.tzdate(zdtmillis));
        final java.util.Date          ztmillis  = new java.util.Date(tz.tztime(zdtmillis));

        final java.util.Date          dnow   = new java.util.Date(now);
        final java.time.ZonedDateTime zdtnow = java.time.ZonedDateTime.ofInstant(dnow.toInstant(), java.time.ZoneId.systemDefault());
        final java.util.Date          zdnow  = java.util.Date.from(tz.tzdate(zdtnow));
        final java.util.Date          ztnow  = new java.util.Date(tz.tztime(zdtnow));

        this.millis       = millis;
        this.informedDate = zdmillis;
        this.informedTime = ztmillis;
        this.currentDate  = zdnow;
        this.currentTime  = ztnow;
    }
}



public class TimeZoneUtils {

    public java.time.Instant tzdate() {
        final java.time.ZonedDateTime zdtime = java.time.ZonedDateTime.now();
        return tzdate(zdtime);
    }
    public java.time.Instant tzdate(java.time.ZonedDateTime zdtime) {
        final java.time.ZonedDateTime zddate = zdtime.truncatedTo(java.time.temporal.ChronoUnit.DAYS);
        final java.time.Instant instant = zddate.toInstant();
        return instant;
    }

    public long tztime() {
        final java.time.ZonedDateTime zdtime = java.time.ZonedDateTime.now();
        return tztime(zdtime);
     }
    public long tztime(java.time.ZonedDateTime zdtime) {
        final java.time.ZonedDateTime zddate = zdtime.truncatedTo(java.time.temporal.ChronoUnit.DAYS);
        final long millis = zddate.until(zdtime, java.time.temporal.ChronoUnit.MILLIS);
        return millis;
    }
}
 0
Author: Richard Gomes, 2015-07-10 12:22:55

Tl; dr

LocalTime lt = myUtilDate.toInstant().atZone( ZoneId.of( "America/Montreal" ) ).toLocalTime() ;

Éviter les anciennes classes date-heure

Vous utilisez d'anciennes classes date-heure héritées. Ils sont gênants et déroutants; évitez-les.

Utilisez plutôt java.les classes de temps. Ceux-ci supplantent les anciennes classes ainsi que la bibliothèque Joda-Time.

Convertir

Convertir vos java.util.Date pour une Instant.

Le Instant la classe représente un moment dans le scénario de UTC, avec une résolution de nanosecondes.

Instant instant = myUtilDate.toInstant();

Fuseau horaire

Appliquer un fuseau horaire. Le fuseau horaire est crucial. Pour un moment donné, la date varie dans le monde entier par zone. Par exemple, quelques minutes après minuit à Paris France est un nouveau jour tout en étant "hier" à Montréal Québec.

Appliquer un ZoneId pour obtenir un ZonedDateTime objet.

ZoneId z = ZoneId.of( "America/Montreal" );
ZonedDateTime zdt = instant.atZone( z );

Local… types de

Le LocalDate classe représente une valeur de date uniquement sans heure et sans heure zone. De même, le LocalTime représente une heure de la journée sans date et sans fuseau horaire. Vous pouvez penser que ces deux composants avec un ZoneId forment une ZonedDateTime. Vous pouvez les extraire d'un ZonedDateTime.

LocalDate ld = zdt.toLocalDate();
LocalTime lt = zdt.toLocalTime();

Chaînes

Si votre objectif est simplement de générer des chaînes pour la présentation à l'utilisateur, pas besoin des types Local…. Au lieu de cela, utilisez DateTimeFormatter pour générer des chaînes représentant uniquement la partie date ou la partie heure. Cette classe est assez intelligent pour localiser automatiquement lors de la génération de la chaîne.

Spécifiez un Locale déterminer (a) le langage humain utilisé pour traduire le nom du jour, le nom du mois, etc., et (b) les normes culturelles pour décider de questions telles que l'abréviation, la majuscule, la ponctuation, etc.

Locale l = Locale.CANADA_FRENCH ;  // Or Locale.US, Locale.ITALY, etc.

DateTimeFormatter fDate = DateTimeFormatter.ofLocalizedDate( FormatStyle.MEDIUM ).withLocale( locale );
String outputDate = zdt.format( fDate );

DateTimeFormatter fTime = DateTimeFormatter.ofLocalizedTime( FormatStyle.MEDIUM ).withLocale( locale );
String outputTime = zdt.format( fTime );

À propos de java.temps

Le java.time framework est intégré à Java 8 et versions ultérieures. Ces classes supplantent l'ancienne date-heure gênante les classes telles que java.util.Date, .Calendar, & java.text.SimpleDateFormat.

Le projet Joda-Time, maintenant en mode maintenance, conseille la migration vers java.temps.

Pour en savoir plus, consultez le tutoriel Oracle. Et rechercher Stack Overflow pour de nombreux exemples et explications.

Une grande partie du java.la fonctionnalité time est rétroportée vers Java 6 & 7 dans ThreeTen-Backport et adaptée à Android dans ThreeTenABP (voir Comment utilisation...).

Le projet ThreeTen-Extra étend java.temps avec des cours supplémentaires. Ce projet est un terrain d'essai pour d'éventuels ajouts futurs à java.temps.

 0
Author: Basil Bourque, 2017-05-23 12:34:15

Utilisation de l'API de calendrier -

Solution de 1-

Calendar c = Calendar.getInstance();
String timeComp = c.get(Calendar.HOUR_OF_DAY)+":"+c.get(Calendar.MINUTE)+":"+c.get(Calendar.SECOND)+":"+c.get(Calendar.MILLISECOND);
System.out.println(timeComp);  

Sortie - 13:24:54:212

Solution de 2-

SimpleDateFormat time_format = new SimpleDateFormat("HH:mm:ss.SSS");
String timeComp = time_format.format(Calendar.getInstance().getTime());

Sortie - 15:57:25.518

 0
Author: Dev911, 2018-01-31 10:27:53