wake-up-neo.com

Wie bekomme ich ein Datum ohne Uhrzeit in Java?

Fortsetzung von Stack Overflow frage Java-Programm zum Abrufen des aktuellen Datums ohne Zeitstempel:

Was ist der effizienteste Weg, um ein Date-Objekt ohne Zeit zu erhalten? Gibt es einen anderen Weg als diese beiden?

// 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();

Update:

  1. Ich wusste von Joda-Time ; Ich versuche nur, eine zusätzliche Bibliothek für eine so einfache Aufgabe (ich denke) zu vermeiden. Basierend auf den bisherigen Antworten scheint Joda-Time jedoch äußerst beliebt zu sein, so dass ich darüber nachdenken könnte.

  2. Mit effizient meine ich, dass ich die Erstellung temporärer Objekte String, wie sie von method 1 verwendet wird, vermeiden möchte, während method 2 wie ein Hack statt einer Lösung erscheint.

194
Rosdi Kasim

Haben Sie unbedingt haben, um Java.util.Date zu verwenden? Ich würde gründlich empfehlen, stattdessen Joda Time oder das Java.time-Paket von Java 8 zu verwenden. Während Datum und Kalender immer einen bestimmten Zeitpunkt in der Zeit ohne ein Konzept wie "nur ein Datum" darstellen, hat Joda Time Do einen Typ, der dies darstellt (LocalDate). Ihr Code wird viel klarer, wenn Sie Typen verwenden können, die das darstellen, was Sie tatsächlich tun möchten.

Es gibt viele andere Gründe, Joda Time oder Java.time anstelle der integrierten Java.util-Typen zu verwenden - sie sind im Allgemeinen weitaus bessere APIs. Sie können jederzeit an den Grenzen Ihres eigenen Codes nach/von einem Java.util.Date konvertieren, wenn Sie möchten, z. für die Datenbankinteraktion.

96
Jon Skeet

Hier habe ich das heutige Datum mit 00:00:00 eingestellt:

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

Date today = new Date();

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

Sie können die Datei DateUtils.truncate aus der Apache Commons-Bibliothek verwenden.

Beispiel: 

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

Gibt es einen anderen Weg als diese beiden?

Ja da ist. 

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

Java.time

Java 8 und höher wird mit dem neuen Java.time-Paket Built-In geliefert. Siehe Tutorial . Ein Großteil der Java.time-Funktionalität wird in ThreeTen-Backport auf Java 6 & 7 zurückportiert und weiter auf Android in ThreeTenABP angepasst.

Ähnlich wie Joda-Time bietet Java.time eine LocalDate -Klasse an, die einen Datumswert ohne Uhrzeit und ohne Zeitzone darstellt.

Beachten Sie, dass Zeitzone ist kritisch, um ein bestimmtes Datum zu bestimmen. In Paris zum Beispiel um Mitternacht ist das Datum in Montréal noch "gestern". 

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

Standardmäßig verwendet Java.time den Standard ISO 8601 , um eine Zeichenfolgendarstellung eines Datums oder Datums/Zeitwerts zu erstellen. (Eine weitere Ähnlichkeit mit Joda-Time.) Rufen Sie einfach toString() auf, um Text wie 2015-05-21 zu generieren.

String output = today.toString() ; 

Über Java.time

Das Java.time - Framework ist in Java 8 und höher integriert. Diese Klassen ersetzen die lästigen alten Legacy Date-Time-Klassen wie Java.util.Date , Calendar , & SimpleDateFormat .

Das Joda-Time -Projekt, jetzt im Wartungsmodus , empfiehlt die Migration zu den Java.time -Klassen.

Weitere Informationen finden Sie im Oracle Tutorial . In Stack Overflow finden Sie viele Beispiele und Erklärungen. Spezifikation ist JSR 310 .

Wo erhalten Sie die Java.time-Klassen? 

  • Java SE 8 , Java SE 9 und später
    • Eingebaut. 
    • Teil der Standard-Java-API mit einer mitgelieferten Implementierung.
    • Java 9 fügt einige kleinere Funktionen und Korrekturen hinzu.
  • Java SE 6 und Java SE 7
    • Ein Großteil der Java.time-Funktionalität wird in ThreeTen-Backport auf Java 6 & 7 zurückportiert.
  • Android
    • Spätere Versionen von Android enthalten Implementierungen der Java.time-Klassen.
    • Bei früheren Android-Versionen passt das ThreeTenABP -Projekt ThreeTen-Backport (oben erwähnt) an. See Wie verwende ich ThreeTenABP… .

Das Projekt ThreeTen-Extra erweitert Java.time um zusätzliche Klassen. Dieses Projekt ist ein Testfeld für mögliche zukünftige Erweiterungen von Java.time. Hier finden Sie einige nützliche Klassen, wie zum Beispiel Interval , YearWeek , YearQuarter und more .

31
Basil Bourque

Die Standardantwort auf diese Fragen lautet Joda Time . Die API ist besser und wenn Sie die Formatierer und Parser verwenden, können Sie den nicht intuitiven Mangel an Thread-Sicherheit von SimpleDateFormat vermeiden. 

Mit Joda können Sie einfach Folgendes tun:

LocalDate d = new LocalDate();

Update :: Mit Java 8 kann dies mit erreicht werden 

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

Der einfachste Weg:

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

Es ist nicht sinnvoll, über ein Datum ohne Zeitstempel in Bezug auf die Date-Routinen in der Standard-Java-Laufzeit zu sprechen, da es im Wesentlichen auf eine bestimmte Millisekunde und kein Datum abgebildet wird. Diese Millisekunde hat an sich eine Tageszeit, die sie anfällig für Zeitzonenprobleme wie die Sommerzeit und andere Kalendereinstellungen macht. Siehe Warum ergibt das Subtrahieren dieser beiden Male (1927) ein seltsames Ergebnis? für ein interessantes Beispiel.

Wenn Sie mit Datumsangaben anstelle von Millisekunden arbeiten möchten, müssen Sie etwas anderes verwenden. Für Java 8 gibt es eine Reihe neuer Methoden, die genau das bieten, wonach Sie fragen. Für Java 7 und frühere Verwendung http://www.joda.org/joda-time/

Wenn Sie nur das Datum wie "JJJJ-MM-TT" sehen möchten, ohne all die anderen Störungen, z. "Do 21 Mai 12:08:18 EDT 2015" verwenden Sie dann einfach Java.sql.Date. In diesem Beispiel wird das aktuelle Datum abgerufen:

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

Auch Java.sql.Date ist eine Unterklasse von Java.util.Date.

3
BigMac66

Dies ist eine einfache Möglichkeit, dies zu tun:

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

Nun, soweit ich weiß, gibt es keinen einfacheren Weg, wenn Sie nur das Standard-JDK verwenden.

Sie können diese Logik in method2 natürlich in eine statische Funktion in einer Hilfsklasse einfügen, wie done hier in der toBeginningOfTheDay-Methode

Dann können Sie die zweite Methode auf folgende Weise verkürzen:

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

Oder, wenn Sie den aktuellen Tag wirklich so oft in diesem Format benötigen, können Sie ihn einfach mit einer anderen statischen Hilfsmethode zusammenfassen und so zu einem Einzeiler machen.

3
Enduriel

Auf jeden Fall nicht der richtigste Weg, aber wenn Sie nur eine schnelle Lösung benötigen, um das Datum ohne Uhrzeit zu erhalten, und Sie keine Drittanbieter-Bibliothek verwenden möchten, sollten Sie dies tun

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

Ich brauchte das Datum nur zu visuellen Zwecken und konnte Joda nicht verwenden, also machte ich einen Teil.

3
Bamz

Wenn Sie nur das aktuelle Datum ohne Uhrzeit benötigen, ist eine weitere Option:

DateTime.now().withTimeAtStartOfDay()
2
user3037726

Verwenden Sie LocalDate.now() und konvertieren Sie sie wie folgt in Date:

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

Wenn Sie den Datumsteil nur zum Echo benötigen, dann

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

Check out Veyder-Zeit . Es ist eine einfache und effiziente Alternative zu Java.util und Joda-time. Es verfügt über eine intuitive API und Klassen, die Datumsangaben ohne Zeitstempel darstellen.

1
lonerook

Hier ist eine saubere Lösung ohne Konvertierung in Zeichenfolge und zurück. Außerdem wird die Zeit nicht mehrmals neu berechnet, wenn Sie jede Komponente der Zeit auf Null zurücksetzen. Es verwendet auch % (Modulus) anstelle von dividieren gefolgt von multiplizieren, um die doppelte Operation zu vermeiden.

Es erfordert keine Abhängigkeiten von Drittanbietern und ERGIBT DIE ZEITZONE DES übergebenen Kalenderobjekts. Diese Funktion gibt den Zeitpunkt um 12 Uhr in der Zeitzone des Datums (Kalender) zurück, das Sie übergeben.

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

Der direkteste Weg, der die riesige TimeZone Database von Java voll ausnutzt und richtig ist:

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

Was ist damit?

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

Sie können Joda-Zeit verwenden.

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

und du rufst an mit:

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

Ich habe das gerade für meine App gemacht:

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)
    );
}

Android-API-Ebene 1, keine externe Bibliothek . Sie berücksichtigt Tageslicht und Standardzeitzone. Keine String-Manipulation. Ich denke, dieser Weg ist CPU-effizienter als der Ihre, aber ich habe keine Tests gemacht.

0
Elloco

Verwenden Sie Fremdbibliotheken möglichst nicht. Ich weiß, dass dieser Weg schon erwähnt wurde, aber hier ist ein schöner sauberer Weg:

  /*
    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;
}

Nicht GregorianCalendar zu verwenden ist vielleicht eine Option!

0
hehe