web-dev-qa-db-fra.com

Comment obtenir une date sans heure en Java?

Suite de la question de débordement de pile PROGRAMME JAVA POUR OBTENIR LA DATE ACTUELLE SANS HORODATAGE:

Quel est le moyen le plus efficace d’obtenir un objet Date sans l’heure? Y a-t-il un autre moyen que ces deux?

// Method 1
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
Date dateWithoutTime = sdf.parse(sdf.format(new Date()));

// Method 2
Calendar cal = Calendar.getInstance();
cal.set(Calendar.HOUR_OF_DAY, 0);
cal.set(Calendar.MINUTE, 0);
cal.set(Calendar.SECOND, 0);
cal.set(Calendar.MILLISECOND, 0);
dateWithoutTime = cal.getTime();

Mettre à jour:

  1. Je connaissais (Joda-Time } _; J'essaie simplement d'éviter une bibliothèque supplémentaire pour une tâche aussi simple (je pense). Mais sur la base des réponses obtenues jusqu'à présent, Joda-Time semble extrêmement populaire, je pourrais donc l'examiner.

  2. Par efficace, je veux dire que je veux éviter la création d'objet temporaire String telle qu'utilisée par method 1, pendant ce temps method 2 semble être un hack plutôt qu'une solution.

194
Rosdi Kasim

Êtes-vous absolument (avez} _ à utiliser Java.util.Date? Je recommanderais complètement d'utiliser plutôt/ Joda Time ou le paquetage Java.time de Java 8 à la place. En particulier, alors que Date et Calendrier toujours représentent un instant particulier dans le temps, sans notion telle que "juste une date", Joda Time fait a un type représentant ceci (LocalDate). Votre code sera beaucoup plus clair si vous pouvez utiliser des types représentant ce que vous essayez réellement de faire.

Il existe de très nombreuses autres raisons d'utiliser Joda Time ou Java.time au lieu des types Java.util intégrés - ce sont généralement des API bien supérieures. Vous pouvez toujours convertir vers/depuis un Java.util.Date aux limites de votre propre code si vous en avez besoin, par exemple. pour l'interaction de base de données.

96
Jon Skeet

Voici ce que j’utilisais pour obtenir la date du jour avec l’heure réglée sur 00:00:00:

DateFormat formatter = new SimpleDateFormat("dd/MM/yyyy");

Date today = new Date();

Date todayWithZeroTime = formatter.parse(formatter.format(today));
53
Shobbi

Vous pouvez utiliser le DateUtils.truncate de la bibliothèque Apache Commons.

Exemple: 

DateUtils.truncate(new Date(), Java.util.Calendar.DAY_OF_MONTH)
47
JoGo

Y a-t-il un autre moyen que ces deux?

Oui il y a. 

LocalDate.now( 
    ZoneId.of( "Pacific/Auckland" ) 
)

Java.time

Java 8 et les versions ultérieures intègrent le nouveau package Java.time intégré. Voir Didacticiel . Une grande partie de la fonctionnalité Java.time est rétroportée vers Java 6 et 7 sous ThreeTen-Backport , puis adaptée à Android sous ThreeTenABP .

Semblable à Joda-Time , Java.time offre une classe LocalDate représentant une valeur de date uniquement sans heure et sans fuseau horaire.

Notez que fuseau horaire est essentiel pour déterminer une date particulière. Sur le coup de minuit à Paris, par exemple, la date est toujours «hier» à Montréal. 

LocalDate today = LocalDate.now( ZoneId.of( "America/Montreal" ) ) ;

Par défaut, Java.time utilise la norme ISO 8601 pour générer une représentation sous forme de chaîne d'une date ou d'une valeur date-heure. (Une autre similitude avec Joda-Time.) Il suffit donc d'appeler toString() pour générer un texte tel que 2015-05-21.

String output = today.toString() ; 

À propos de Java.time

Le cadre Java.time est intégré à Java 8 et versions ultérieures. Ces classes supplantent les anciennes classes gênantes héritées _ date-heure telles que Java.util.Date , Calendar _, & SimpleDateFormat .

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

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

Où obtenir les classes Java.time? 

  • Java SE 8 , Java SE 9 et versions ultérieures
    • Intégré. 
    • Une partie de l'API Java standard avec une implémentation fournie.
    • Java 9 ajoute quelques fonctionnalités et corrections mineures.
  • Java SE 6 et Java SE 7
    • Une grande partie de la fonctionnalité Java.time est rétroportée vers Java 6 et 7 dans ThreeTen-Backport .
  • Android
    • Les versions ultérieures d'Android regroupent des implémentations des classes Java.time.
    • Pour les versions antérieures d'Android, le projet ThreeTenABP s'adapte ThreeTen-Backport (mentionné ci-dessus). Voir Comment utiliser ThreeTenABP… .

Le projet ThreeTen-Extra étend Java.time avec des classes supplémentaires. Ce projet est un terrain d’essai pour d’éventuels ajouts à Java.time. Vous pouvez y trouver des classes utiles telles que Interval _, YearWeek , YearQuarter _ et plus _.

31
Basil Bourque

La réponse standard à ces questions est d'utiliser Joda Time . L'API est meilleure et si vous utilisez les formateurs et les analyseurs, vous pouvez éviter le manque non intuitif de sécurité des threads de SimpleDateFormat

Utiliser Joda signifie que vous pouvez simplement faire:

LocalDate d = new LocalDate();

Update :: En utilisant Java 8, ceci peut être réalisé en utilisant 

LocalDate date = LocalDate.now();
20
Brian Agnew

Le moyen le plus simple:

long millisInDay = 60 * 60 * 24 * 1000;
long currentTime = new Date().getTime();
long dateOnly = (currentTime / millisInDay) * millisInDay;
Date clearDate = new Date(dateOnly);
20
Roman

Il n’a aucun sens de parler d’une date sans horodatage en ce qui concerne les routines de date dans le runtime Java standard, puisqu’il correspond essentiellement à une milliseconde spécifique et non à une date. Cette milliseconde est intrinsèquement associée à une heure de la journée, ce qui la rend vulnérable aux problèmes de fuseau horaire tels que l'heure d'été et d'autres ajustements de calendrier. Voir Pourquoi soustraire ces deux fois (en 1927) donne un résultat étrange? pour un exemple intéressant.

Si vous souhaitez utiliser des dates au lieu de millisecondes, vous devez utiliser autre chose. Pour Java 8, il existe un nouvel ensemble de méthodes fournissant exactement ce que vous demandez. Pour Java 7 et les versions antérieures, utilisez http://www.joda.org/joda-time/

6

Si tout ce que vous voulez, c'est voir la date comme "AAAA-MM-JJ" sans tout le fouillis, par exemple. "Jeudi 21 mai 12:08:18 HAE 2015", utilisez simplement Java.sql.Date. Cet exemple obtient la date du jour:

new Java.sql.Date(System.currentTimeMillis());

De plus, Java.sql.Date est une sous-classe de Java.util.Date.

3
BigMac66

C'est un moyen simple de le faire:

Calendar cal = Calendar.getInstance();
SimpleDateFormat dateOnly = new SimpleDateFormat("MM/dd/yyyy");
System.out.println(dateOnly.format(cal.getTime()));
3
Glen

Pour autant que je sache, il n’ya pas de moyen plus simple d’y parvenir si vous n’utilisez que le JDK standard.

Vous pouvez, bien sûr, mettre cette logique dans method2 dans une fonction statique dans une classe d'assistance, comme done ici dans la méthode toBeginningOfTheDay

Ensuite, vous pouvez raccourcir la seconde méthode pour:

Calendar cal = Calendar.getInstance();
Calendars.toBeginningOfTheDay(cal);
dateWithoutTime = cal.getTime();

Ou, si vous avez vraiment besoin du jour actuel dans ce format si souvent, vous pouvez simplement l'envelopper dans une autre méthode d'assistance statique, ce qui en fait un one-liner.

3
Enduriel

Ce n’est certainement pas le moyen le plus correct, mais si vous avez juste besoin d’une solution rapide pour obtenir la date sans heure et que vous ne souhaitez pas utiliser de bibliothèque tierce, faites-le.

    Date db = db.substring(0, 10) + db.substring(23,28);

Je n'avais besoin que de la date à des fins visuelles et je ne pouvais pas utiliser Joda, alors je sous-traitais.

3
Bamz

Si vous avez juste besoin de la date du jour, sans heure, une autre option est:

DateTime.now().withTimeAtStartOfDay()
2
user3037726

Utilisez LocalDate.now() et convertissez-le en Date comme ci-dessous:

Date.from(LocalDate.now().atStartOfDay(ZoneId.systemDefault()).toInstant());
2
Sahil Chhabra
// 09/28/2015
System.out.println(new SimpleDateFormat("MM/dd/yyyy").format(Calendar.getInstance().getTime()));

// Mon Sep 28
System.out.println( new Date().toString().substring(0, 10) );

// 2015-09-28
System.out.println(new Java.sql.Date(System.currentTimeMillis()));

// 2015-09-28
// Java 8
System.out.println( LocalDate.now(ZoneId.of("Europe/Paris")) ); // rest zones id in ZoneId class
2
blueberry0xff

Si vous avez besoin de la partie Date uniquement

Date d = new Date(); 
String dateWithoutTime = d.toString().substring(0, 10);
2
manish_s

Départ heure de Veyder . C'est une alternative simple et efficace à la fois à Java.util et à Joda-time. Il a une API intuitive et des classes qui représentent uniquement les dates, sans horodatage.

1
lonerook

Voici une solution propre sans conversion en chaîne et retour, et elle ne recalcule pas le temps plusieurs fois lorsque vous réinitialisez chaque composant du temps à zéro. Il utilise également % (module) plutôt que de diviser suivi de multiplier pour éviter la double opération.

Elle ne nécessite aucune dépendance de tiers et respecte le fuseau horaire de l'objet calandre transmis. Cette fonction renvoie le moment à 12 heures dans le fuseau horaire de la date (calendrier) que vous avez indiquée.

public static Calendar date_only(Calendar datetime) {
    final long LENGTH_OF_DAY = 24*60*60*1000;
    long millis = datetime.getTimeInMillis();
    long offset = datetime.getTimeZone().getOffset(millis);
    millis = millis - ((millis + offset) % LENGTH_OF_DAY);
    datetime.setTimeInMillis(millis);
    return datetime;
}
1
Brent Larsen

Le moyen le plus direct qui utilise pleinement l’énorme base de données TimeZone de Java est correct:

long currentTime = new Date().getTime();
long dateOnly = currentTime + TimeZone.getDefault().getOffset(currentTime);
1
TomWolk

Et ça?

public static Date formatStrictDate(int year, int month, int dayOfMonth) {
    Calendar calendar = Calendar.getInstance();
    calendar.set(year, month, dayOfMonth, 0, 0, 0);
    calendar.set(Calendar.MILLISECOND, 0);
    return calendar.getTime();
}
0
vitiello.antonio

Vous pouvez utiliser le temps Joda.

private Date dateWitoutTime(Date date){
 return new LocalDate(date).toDate()
}

et vous appelez avec:

Date date = new Date();
System.out.println("With Time = " + dateWitoutTime(date) + "/n  Without time = " + date);
0
Jesús Sánchez

Je viens de faire cela pour mon application:

public static Date getDatePart(Date dateTime) {
    TimeZone tz = TimeZone.getDefault();
    long rawOffset=tz.getRawOffset();
    long dst=(tz.inDaylightTime(dateTime)?tz.getDSTSavings():0);
    long dt=dateTime.getTime()+rawOffset+dst; // add offseet and dst to dateTime
    long modDt=dt % (60*60*24*1000) ;

    return new Date( dt
                    - modDt // substract the rest of the division by a day in milliseconds
                    - rawOffset // substract the time offset (Paris = GMT +1h for example)
                    - dst // If dayLight, substract hours (Paris = +1h in dayLight)
    );
}

API Android niveau 1, pas de bibliothèque externe . Il respecte la lumière du jour et le fuseau horaire par défaut. Pas de manipulation de chaîne donc je pense que cette méthode est plus efficace en termes de CPU que le vôtre mais je n'ai fait aucun test.

0
Elloco

Préférez ne pas utiliser les bibliothèques tierces autant que possible. Je sais que cette méthode est mentionnée auparavant, mais voici une méthode propre et agréable:

  /*
    Return values:
    -1:    Date1 < Date2
     0:    Date1 == Date2
     1:    Date1 > Date2

    -2:    Error
*/
public int compareDates(Date date1, Date date2)
{
    SimpleDateFormat sdf = new SimpleDateFormat("ddMMyyyy");

    try
    {
        date1 = sdf.parse(sdf.format(date1));
        date2 = sdf.parse(sdf.format(date2));
    }
    catch (ParseException e) {
        e.printStackTrace();
        return -2;
    }

    Calendar cal1 = new GregorianCalendar();
    Calendar cal2 = new GregorianCalendar();

    cal1.setTime(date1);
    cal2.setTime(date2);

    if(cal1.equals(cal2))
    {
        return 0;
    }
    else if(cal1.after(cal2))
    {
        return 1;
    }
    else if(cal1.before(cal2))
    {
        return -1;
    }

    return -2;
}

Bien, ne pas utiliser GregorianCalendar est peut-être une option!

0
hehe