Ich habe ein Java-Date-Objekt, das Datums- und Uhrzeitinformationen enthält. Ich möchte eine Methode schreiben, die die Zeitinformationen abschneidet, die Stunden-Minuten-Sekunden abschneidet, so dass mir nur das Datum übrig ist.
Beispieleingabe:
2008-01-01 13:15:00
Erwartete Ausgabe:
2008-01-01 00:00:00
Hast du einen tipp Ich habe so etwas versucht:
(timestamp / (24 * 60 * 60 * 1000)) * (24 * 60 * 60 * 1000)
ich hatte jedoch Probleme mit der Zeitzone.
Der empfohlene Weg, Datum und Uhrzeit zu manipulieren, besteht in der Verwendung eines Calendar
Objekts:
Calendar cal = Calendar.getInstance(); // locale-specific
cal.setTime(dateObject);
cal.set(Calendar.HOUR_OF_DAY, 0);
cal.set(Calendar.MINUTE, 0);
cal.set(Calendar.SECOND, 0);
cal.set(Calendar.MILLISECOND, 0);
long time = cal.getTimeInMillis();
Haben Sie sich die abgeschnittene Methode DateUtils in Apache Commons Lang angesehen?
Date truncatedDate = DateUtils.truncate(new Date(), Calendar.DATE);
entfernt das Zeitelement.
Hast du Joda angesehen? Es ist eine viel einfachere und intuitivere Art, mit Datum und Uhrzeit zu arbeiten. Zum Beispiel können Sie trivial zwischen (say) LocalDateTime und LocalDate Objekten konvertieren.
z.B. (zur Veranschaulichung der API)
LocalDate date = new LocalDateTime(milliseconds).toLocalDate()
Darüber hinaus werden einige Thread-Sicherheitsprobleme mit Datums-/Uhrzeitformatierern gelöst und es wird dringend empfohlen, mit Datums-/Uhrzeitproblemen in Java zu arbeiten.
Date date = new Date();
Calendar cal = Calendar.getInstance();
cal.setTime(date);
cal.set(Calendar.HOUR_OF_DAY, 0);
cal.set(Calendar.MINUTE, 0);
cal.set(Calendar.SECOND, 0);
cal.set(Calendar.MILLISECOND, 0);
date = cal.getTime();
Nur ein kurzes Update angesichts der Java.time - Klassen, die jetzt in Java 8 und höher integriert sind.
LocalDateTime
hat eine truncatedTo
-Methode, die effektiv anspricht, worüber Sie hier sprechen:
LocalDateTime.now().truncatedTo(ChronoUnit.MINUTES)
Dadurch wird die aktuelle Uhrzeit nur in Minuten ausgedrückt:
2015-03-05T11:47
Sie können eine beliebige ChronoUnit
(oder auch eine beliebige TemporalUnit
) verwenden, um die Kürzung auszuführen.
Mit Joda können Sie leicht das erwartete Datum erhalten.
Seit Version 2.7 (möglicherweise seit einer früheren Version größer als 2.2) wurde toDateMidnight
, wie ein Kommentator feststellt, zugunsten des entsprechenden Namens withTimeAtStartOfDay()
verworfen
DateTime.now().withTimeAtStartOfDay()
möglich.
Vorteil hinzugefügt durch eine schönere API.
Mit älteren Versionen können Sie das tun
new DateTime(new Date()).toDateMidnight().toDate()
Verwenden Sie DateUtils aus Apache mit abgeschnittener Darstellung wie folgt:
DateUtils.truncate(Calendar.getInstance().getTime(), Calendar.DATE);
Für Zeitstempel:
timestamp -= timestamp % (24 * 60 * 60 * 1000)
Ich habe die Kürzung mit der neuen Java8-API vorgenommen. Ich sah mich mit einer seltsamen Sache konfrontiert, aber im Allgemeinen ist es abgeschnitten ...
Instant instant = date.toInstant();
instant = instant.truncatedTo(ChronoUnit.DAYS);
date = Date.from(instant);
Von Java.util.Date JavaDocs:
Die Klasse Date repräsentiert einen bestimmten Zeitpunkt mit einer Millisekundengenauigkeit
und aus den Java.sql.Date-JavaDocs:
Um mit der Definition von SQL DATE übereinzustimmen, müssen die Millisekundenwerte, die von einer Java.sql.Date-Instanz umschlossen werden, "normalisiert" werden, indem die Stunden, Minuten, Sekunden und Millisekunden in der jeweiligen Zeitzone auf Null gesetzt werden, der die Instanz zugeordnet ist .
Daher ist es am besten, Java.sql.Date zu verwenden, wenn Sie den Zeitabschnitt nicht benötigen
Java.util.Date utilDate = new Java.util.Date();
Java.sql.Date sqlDate = new Java.sql.Date(System.currentTimeMillis());
und die Ausgabe ist:
Java.util.Date : Thu Apr 26 16:22:53 PST 2012
Java.sql.Date : 2012-04-26
LocalDateTime.parse( // Lacking an offset or time zone, parse as a `LocalDateTime`. *Not* a specific moment in time.
"2008-01-01 13:15:00".replace( " " , "T" ) // Alter input string to comply with ISO 8601 standard format.
)
.toLocalDate() // Extract a date-only value.
.atStartOfDay( // Do not assume the day starts at 00:00:00. Let class determine start-of-day.
ZoneId.of( "Europe/Paris" ) // Determining a specific start-of-day requires a time zone.
) // Result is a `ZonedDateTime` object. At this point we have a specific moment in time, a point on the timeline.
.toString() // Generate a String in standard ISO 8601 format, wisely extended to append the name of the time zone in square brackets.
2008-01-01T00: 00 + 01: 00 [Europe/Paris]
Um einen String in Ihrem gewünschten Format zu generieren, übergeben Sie ein DateTimeFormatter
.
LocalDateTime.parse( // Lacking an offset or time zone, parse as a `LocalDateTime`. *Not* a specific moment in time.
"2008-01-01 13:15:00".replace( " " , "T" ) // Alter input string to comply with ISO 8601 standard format.
)
.toLocalDate() // Extract a date-only value.
.atStartOfDay( // Do not assume the day starts at 00:00:00. Let class determine start-of-day.
ZoneId.of( "Europe/Paris" ) // Determining a specific start-of-day requires a time zone.
) // Result is a `ZonedDateTime` object. At this point we have a specific moment in time, a point on the timeline.
.format( // Generate a String representing the object’s value.
DateTimeFormatter.ISO_LOCAL_DATE_TIME // Built-in predefined formatter close to what you want.
)
.replace( "T" , " " ) // Replace the standard’s use of a 'T' in the middle with your desired SPACE character.
2008-01-01 00:00:00
Andere Antworten sind korrekt, verwenden jedoch alte Datums-/Uhrzeitklassen, die vom Java.time-Framework veraltet sind.
Das Java.time-Framework ist in Java 8 und höher integriert. Ein Großteil der Java.time-Funktionalität ist auf Java 6 & 7 (- ThreeTen-Backport ) und weiter angepasst an Android ( ThreeTenABP ).
Ändern Sie zuerst die Eingabezeichenfolge, um der kanonischen Version des ISO 8601-Formats zu entsprechen. Die Standardformate ISO 8601 werden in Java.time-Klassen standardmäßig zum Parsen/Generieren von Zeichenfolgen verwendet, die Datums-/Zeitwerte darstellen. Wir müssen diesen SPACE in der Mitte durch einen T
ersetzen.
String input = "2008-01-01 13:15:00".replace( " " , "T" ); // → 2008-01-01T13:15:00
Jetzt können wir es als LocalDateTime
analysieren, wobei "Lokal" keine bestimmte Lokalität bedeutet. In der Eingabe fehlen Offset-von-UTC oder Zeitzoneninformationen.
LocalDateTime ldt = LocalDateTime.parse( input );
ldt.toString ()… 2008-01-01T13: 15: 00
Wenn Ihnen Uhrzeit und Zeitzone egal sind, konvertieren Sie in ein LocalDate
.
LocalDate ld = ldt.toLocalDate();
ld.toString ()… 2008-01-01
Wenn Sie stattdessen die Uhrzeit auf den ersten Moment des Tages einstellen möchten, verwenden Sie eine ZonedDateTime
-Klasse und konvertieren Sie sie in ein LocalDate
-Objekt, um dessen aufzurufen atStartOfDay
Methode. Seien Sie sich bewusst, dass der erste Moment möglicherweise nicht die Zeit ist 00:00:00
wegen Sommerzeit oder anderen Anomalien.
Die Zeitzone ist von entscheidender Bedeutung, da das Datum für einen bestimmten Moment von Zone zu Zone auf der ganzen Welt variiert. Zum Beispiel ist ein paar Momente nach Mitternacht in Paris ein neuer Tag für die Pariser, aber für die Kanadier ist es immer noch „gestern“ in Montréal.
ZoneId zoneId = ZoneId.of( "America/Montreal" );
ZonedDateTime zdt = ldt.atZone( zoneId );
LocalDate ldFromZdt = zdt.toLocalDate();
ZonedDateTime zdtStartOfDay = ldFromZdt.atStartOfDay( zoneId );
zdtStartOfDay.toString ()… 2008-01-01T00: 00: 00-05: 00 [America/Montreal]
Um diesen Moment durch die Linse der Zeitzone UTC zu sehen, extrahieren Sie ein Objekt Instant
. Sowohl ZonedDateTime
als auch Instant
stellen den gleichen Zeitpunkt auf der Zeitachse dar, erscheinen jedoch als zwei unterschiedliche Wanduhrzeiten .
Ein Instant
ist die Basisbausteinklasse in Java.time, immer in UTC per Definition. Verwenden Sie diese Klasse häufig, da Sie im Allgemeinen Ihre Geschäftslogik, Datenspeicherung und den Datenaustausch in UTC durchführen sollten.
Instant instant = zdtStartOfDay.toInstant();
instant.toString ()… 2008-01-01T05: 00: 00Z
Wir sehen 5 Uhr morgens statt Mitternacht. Im Standardformat steht das Z
am Ende für Zulu
und bedeutet "UTC".
Das Java.time Framework ist in Java 8 und höher. Diese Klassen ersetzen das lästige alte Legacy Datum-Zeit-Klassen wie Java.util.Date
, Calendar
, & SimpleDateFormat
.
Das Joda-Time -Projekt, das sich jetzt im Wartungsmodus befindet, rät zur Migration in die Java.time -Klassen.
Weitere Informationen finden Sie im Oracle Tutorial . Durchsuchen Sie Stack Overflow nach vielen Beispielen und Erklärungen. Spezifikation ist JSR 31 .
Sie können Java.time Objekte direkt mit Ihrer Datenbank austauschen. Verwenden Sie einen JDBC-Treiber , der JDBC 4.2 oder höher entspricht. Keine Notwendigkeit für Zeichenfolgen, keine Notwendigkeit für Java.sql.*
Klassen.
Woher bekommen Sie die Java.time-Klassen?
Das Projekt ThreeTen-Extra erweitert Java.time um zusätzliche Klassen. Dieses Projekt ist ein Testfeld für mögliche zukünftige Ergänzungen von Java.time. Hier finden Sie möglicherweise einige nützliche Klassen wie Interval
, YearWeek
, YearQuarter
und mehr .
Die Frage ist widersprüchlich. Es fragt nach einem Datum ohne Tageszeit, zeigt jedoch ein Beispiel mit einer Uhrzeit von 00:00:00
an.
UPDATE: Das Joda-Time - Projekt befindet sich jetzt im Wartungsmodus , wobei das Team die Migration zu den Java.time -Klassen empfiehlt. Siehe meine andere Antwort für Java.time-Lösung.
Wenn Sie stattdessen die Uhrzeit auf den ersten Zeitpunkt des Tages setzen möchten, verwenden Sie ein DateTime
- Objekt in der Joda-Time-Bibliothek und rufen Sie seine withTimeAtStartOfDay
-Methode auf. Beachten Sie, dass der erste Moment aufgrund der Sommerzeit oder anderer Anomalien möglicherweise nicht die Uhrzeit 00:00:00
ist.
Verwenden Sie die set()
-Methode der Calendar -Klasse, um die Felder HOUR_OF_DAY, MINUTE, SECOND
und MILLISECOND
auf Null zu setzen.
Sie können dies tun, um Probleme mit der Zeitzone zu vermeiden:
public static Date truncDate(Date date) {
Calendar cal = Calendar.getInstance(TimeZone.getTimeZone("UTC"));
cal.setTime(date);
cal.set(Calendar.HOUR_OF_DAY, 0);
cal.set(Calendar.MINUTE, 0);
cal.set(Calendar.SECOND, 0);
cal.set(Calendar.MILLISECOND, 0);
return cal.getTime();
}
Das Java-Objekt Date
ist zwar ein Zeitstempelwert, wird jedoch beim Abschneiden in eine lokale Zeitzone konvertiert. Wenn Sie also einen Wert aus der UTC-Zeitzone erwarten, erhalten Sie einen überraschenden Wert.
Nur clear()
redundante Felder.
Calendar calendar = Calendar.getInstance();
calendar.setTime(date);
calendar.set(Calendar.HOUR_OF_DAY, 0);
calendar.clear(Calendar.MINUTE);
calendar.clear(Calendar.SECOND);
calendar.clear(Calendar.MILLISECOND);
Date truncatedDate = calendar.getTime();
Es hat mich wirklich geärgert, dass der neue "verbesserte" Kalender-Konstruktor kein Millisekundenintervall wie das "schreckliche" alte Datum eins..__ nimmt.
long stuffYou = startTime.getTimeInMillis() % 1000;
startTime.setTimeInMillis(startTime.getTimeInMillis() - stuffYou);
Ich habe das Wort "Zeug" zu dieser Zeit nicht verwendet, aber dann entdeckte ich das Glück davon:
startTime.set(Calendar.MILLISECOND, 0);
Aber ich bin immer noch ziemlich sauer.
Wenn Sie Java 8+ verwenden, können Sie auf einfache Weise ein Datum ohne Uhrzeit abrufen: Verwenden Sie den Typ Java.time.LocalDate anstelle von Datum.
LocalDate now = LocalDate.now();
System.out.println(now.toString());
Die Ausgabe:
2019-05-30
https://docs.Oracle.com/javase/8/docs/api/Java/time/LocalDate.html
Könnte eine späte Antwort sein, aber hier ist eine Möglichkeit, dies in einer Zeile zu tun, ohne Bibliotheken zu verwenden:
new SimpleDateFormat("yyyy-MM-dd").parse(new SimpleDateFormat("yyyy-MM-dd").format(YOUR_TIMESTAMP))
Für alle Antworten, die Kalender verwenden, sollten Sie sie stattdessen so verwenden
public static Date truncateDate(Date date) {
Calendar c = Calendar.getInstance();
c.setTime(date);
c.set(Calendar.HOUR_OF_DAY, c.getActualMinimum(Calendar.HOUR_OF_DAY));
c.set(Calendar.MINUTE, c.getActualMinimum(Calendar.MINUTE));
c.set(Calendar.SECOND, c.getActualMinimum(Calendar.SECOND));
c.set(Calendar.MILLISECOND, c.getActualMinimum(Calendar.MILLISECOND));
return c.getTime();
}
Aber ich bevorzuge das:
public static Date truncateDate(Date date) {
return new Java.sql.Date(date.getTime());
}
Ich habe das Problem so behoben (in der Zone Eastern 8 (Pekinger Zeit)):
private Date getTruncatedDate(Date d) {
if (d == null) {
return null;
}
long h = 60 * 60 * 1000L;
long dateStamp = d.getTime() - (d.getTime() + 8 * h) % (24 * h);
return new Date(dateStamp);
}
Zunächst sollten Sie wissen, was der Zeitstempel ist . Der Zeitstempel ist der Gesamtwert der Millisekunden vom 01. Januar 00:00:00 1970 in GMT (ebenso wie in UTC) oder vom 1. Januar, 01:00 Uhr CST 1970 jetzt.
Denken Sie daran: Zeitstempel ist unabhängig von der Zeitzone.
Sie erhalten also mit folgender Aussage in verschiedenen Zeitzonen dasselbe Ergebnis:
System.out.println(new Date().getTime());
Und
System.out.println(new Date(0));
druckt verschiedene Zeitangaben in verschiedenen Zeitzonen: Wenn Sie Ihre PC-Zeitzone als UTC einstellen, erhalten Sie
Thu Jan 01 00:00:00 UTC 1970
Wenn Sie die Zeitzone jedoch als (UTC +8: 00) Peking, Chongqing, HongKong, Urumq einstellen, erhalten Sie:
Thu Jan 01 08:00:00 CST 1970
Java erhält den Zeitstempel und zeigt Datums- und Zeitinformationen entsprechend der Zeitzone an.
Für die Einführung, wie Java Datums- und Uhrzeitinformationen in verschiedenen Zeitzonen anzeigt, ist es einfach, die Zeitinformationen zu durchsuchen. Sie sollten den Zeitstempel erhalten und die Zeitzone berücksichtigen, wenn Sie die Zeitangaben abschneiden. Dann können Sie ein neues Date-Objekt mit dem Schnittzeitstempel erstellen (wir können es Datumsstempel nennen), Java kompensiert die Zeitzone, wenn Datumsinformationen angezeigt werden.
Wie in der östlichen Zone acht (Peking-Zeit) ist die Peking-Zeit 8 Stunden früher als GMT (GMT). Daher sollten Sie bei der Modulo-Operation mehr als 8 Stunden abziehen. Das heißt, Sie sollten zuerst die GMT-Zeit ermitteln, dann addiert Java 8 Stunden, wenn die Anzeigezeit auf der Zeitzone Ihres PCs basiert.
Das Zeitzonenproblem ist undurchsichtig und rätselt mich auch lange. Jetzt mache ich es klar . Hoffnung hilft.
2018-01-04 Die unten beschriebene Methode funktioniert auch.
private Date getTruncatedDate2(Date d) {
Calendar cal = Calendar.getInstance(); // locale-specific
cal.setTime(d);
cal.set(Calendar.HOUR_OF_DAY, 0);
cal.set(Calendar.MINUTE, 0);
cal.set(Calendar.SECOND, 0);
cal.set(Calendar.MILLISECOND, 0);
return cal.getTime();
}
Mit Joda-Time können Sie seit Version 2.0 LocalDate.toDate()
verwenden.
Einfach
// someDatetime is whatever Java.util.Date you have.
Date someDay = new LocalDate(someDatetime).toDate();