wake-up-neo.net

wie erstelle ich ein Java Date-Objekt von Mitternacht heute und Mitternacht morgen?

In meinem Code muss ich alle meine Dinge finden, die heute passiert sind. Ich muss also mit Daten von heute um 00:00 Uhr (Mitternacht heute früh) bis 12:00 Uhr (Mitternacht heute Nacht) vergleichen.

Ich kenne ...

Date today = new Date(); 

... holt mich jetzt. Und ...

Date beginning = new Date(0);

... bekomme ich am 1. Januar 1970 Nullzeit. Aber wie kann ich heute und morgen Nullzeit erreichen?

AKTUALISIEREN; Ich habe das getan, aber es gibt sicherlich einen einfacheren Weg?

Calendar calStart = new GregorianCalendar();
calStart.setTime(new Date());
calStart.set(Calendar.HOUR_OF_DAY, 0);
calStart.set(Calendar.MINUTE, 0);
calStart.set(Calendar.SECOND, 0);
calStart.set(Calendar.MILLISECOND, 0);
Date midnightYesterday = calStart.getTime();

Calendar calEnd = new GregorianCalendar();
calEnd.setTime(new Date());
calEnd.set(Calendar.DAY_OF_YEAR, calEnd.get(Calendar.DAY_OF_YEAR)+1);
calEnd.set(Calendar.HOUR_OF_DAY, 0);
calEnd.set(Calendar.MINUTE, 0);
calEnd.set(Calendar.SECOND, 0);
calEnd.set(Calendar.MILLISECOND, 0);
Date midnightTonight = calEnd.getTime();
154
Robert Hume

Java.util.Calendar

// today    
Calendar date = new GregorianCalendar();
// reset hour, minutes, seconds and millis
date.set(Calendar.HOUR_OF_DAY, 0);
date.set(Calendar.MINUTE, 0);
date.set(Calendar.SECOND, 0);
date.set(Calendar.MILLISECOND, 0);

// next day
date.add(Calendar.DAY_OF_MONTH, 1);

JDK 8 - Java.time.LocalTime und Java.time.LocalDate

LocalTime midnight = LocalTime.MIDNIGHT;
LocalDate today = LocalDate.now(ZoneId.of("Europe/Berlin"));
LocalDateTime todayMidnight = LocalDateTime.of(today, midnight);
LocalDateTime tomorrowMidnight = todayMidnight.plusDays(1);

Joda-Zeit

Wenn Sie ein JDK <8 verwenden, empfehle ich Joda Time , da die API wirklich schön ist:

DateTime date = new DateTime().toDateMidnight().toDateTime();
DateTime tomorrow = date.plusDays(1);

</ strike>

Seit Version 2.3 von Joda Time ist DateMidnightdeprecated, verwenden Sie also Folgendes:

DateTime today = new DateTime().withTimeAtStartOfDay();
DateTime tomorrow = today.plusDays(1).withTimeAtStartOfDay();

Übergeben Sie eine Zeitzone, wenn Sie die aktuelle Standardzeitzone der JVM nicht verwenden möchten.

DateTimeZone timeZone = DateTimeZone.forID("America/Montreal");
DateTime today = new DateTime(timeZone).withTimeAtStartOfDay(); // Pass time zone to constructor.
299
timaschew

Der einfachste Weg, um Mitternacht zu finden:

Long time = new Date().getTime();
Date date = new Date(time - time % (24 * 60 * 60 * 1000));

Nächster Tag:

Date date = new Date(date.getTime() + 24 * 60 * 60 * 1000);
31
Andrei Volgin

Denken Sie daran, dass Date nicht zur Darstellung von Datumsangaben (!) Verwendet wird. Zur Darstellung des Datums benötigen Sie einen Kalender. Diese:

Calendar c = new GregorianCalendar();

erstellt eine Calendar-Instanz, die das aktuelle Datum in Ihrer aktuellen Zeitzone darstellt. Jetzt müssen Sie jedes Feld unter dem Tag (Stunde, Minute, Sekunde und Millisekunde) abschneiden, indem Sie es auf 0 setzen. Sie haben heute Mitternacht.

Um am nächsten Tag Mitternacht zu erhalten, müssen Sie einen Tag hinzufügen:

c.add(Calendar.DAY_OF_MONTH, 1);

Beachten Sie, dass das Hinzufügen von 86400 Sekunden oder 24 Stunden aufgrund der Sommerzeit, die in der Zwischenzeit auftreten kann, falsch ist.

UPDATE: Am liebsten beschäftige ich mich mit diesem Problem jedoch mit DateUtils class aus Commons Lang :

Date start = DateUtils.truncate(new Date(), Calendar.DAY_OF_MONTH))
Date end = DateUtils.addDays(start, 1);

Es verwendet Calendar hinter den Kulissen ...

28

Der Vollständigkeit halber können Sie, wenn Sie Java 8 verwenden, auch die truncatedTo-Methode der Instant-Klasse verwenden, um Mitternacht in UTC zu erhalten.

Instant.now().truncatedTo(ChronoUnit.DAYS);

Wie im Javadoc geschrieben

Das Abschneiden mit der MINUTES-Einheit wird beispielsweise auf die nächste Minute abgerundet, wobei die Sekunden und Nanosekunden auf Null gesetzt werden.

Ich hoffe es hilft.

26
riccardo.cardin

diese Methoden werden Ihnen helfen-

public static Date getStartOfDay(Date date) {
     Calendar calendar = Calendar.getInstance();
     calendar.setTime(date);
     calendar.set(Calendar.HOUR_OF_DAY, 0);
     calendar.set(Calendar.MINUTE, 0);
     calendar.set(Calendar.SECOND, 0);
     calendar.set(Calendar.MILLISECOND, 0);
     return calendar.getTime();
 }

und 

public static Date getEndOfDay(Date date) {
    Calendar calendar = Calendar.getInstance();
    calendar.setTime(date);
    calendar.set(Calendar.HOUR_OF_DAY, 23);
    calendar.set(Calendar.MINUTE, 59);
    calendar.set(Calendar.SECOND, 59);
    calendar.set(Calendar.MILLISECOND, 999);
    return calendar.getTime();
}

Ab JodaTime 2.3 ist die toDateMidnight() veraltet.

Von Upgrade von 2.2 auf 2.3

 Abnahmen seit dem 2.2 
 ----------------------
 - DateMidnight [# 41] 
 Diese Klasse ist im Konzept 
 Fehlerhaft. Die Uhrzeit um Mitternacht tritt gelegentlich in einigen Zeitzonen nicht auf 
 Dies ist das Ergebnis einer Sommerzeit von 00:00 bis 01:00 Uhr 
 DateMidnight ist im Wesentlichen eine DateTime, deren Zeit bis Mitternacht gesperrt ist 
 Ein solches Konzept ist generell ein schlechtes Konzept, wenn man LocalDate 
 Ersetzen Sie DateMidnight durch LocalDate 
 Oder ersetzen Sie es durch DateTime, möglicherweise mithilfe der Methode withTimeAtStartOfDay () 

Hier ist ein Beispielcode ohne toDateMidnight()-Methode.

Code

DateTime todayAtMidnight = new DateTime().withTimeAtStartOfDay();
System.out.println(todayAtMidnight.toString("yyyy-MM-dd HH:mm:ss"));

Ausgabe (kann je nach lokaler Zeitzone unterschiedlich sein} _)

2013-09-28 00:00:00
8
Stephan

Java.time

Wenn Sie Java 8 oder höher verwenden, können Sie das Paket Java.time ( Tutorial ) ausprobieren:

LocalDate tomorrow = LocalDate.now().plusDays(1);
Date endDate = Date.from(tomorrow.atStartOfDay(ZoneId.systemDefault()).toInstant());
6
arganzheng

Andere Antworten sind richtig, insbesondere die Java.time-Antwort von arganzheng . Wie bereits erwähnt, sollten Sie die alten Java.util.Date/.Calendar-Klassen vermeiden, da sie schlecht entworfen, verwirrend und problematisch sind. Sie wurden durch die Java.time-Klassen ersetzt.

Lassen Sie mich Anmerkungen zur Strategie im Zusammenhang mit dem Umgang mit Mitternacht und Zeiträumen hinzufügen.

Halb offen

In der Datums- und Uhrzeitarbeit werden Zeitspannen häufig nach dem „Half-Open“ -Ansatz definiert. Bei diesem Ansatz ist der Anfang einschließlich , während das Ende ausschließlich ist. Dies löst Probleme und erleichtert Ihnen bei konsequenter Verwendung die Überlegung, wie Sie mit der Uhrzeit umgehen sollen.

Ein gelöstes Problem ist die Festlegung des Tagesendes. Ist der letzte Moment des Tages 23:59:59.999 ( Millisekunden )? Vielleicht in der Java.util.Date-Klasse (ab dem frühesten Java; lästig - vermeiden Sie diese Klasse!) Und in der höchst erfolgreichen Joda-Time -Bibliothek. In anderen Programmen wie Datenbanken wie Postgres ist der letzte Moment jedoch 23:59:59.999999 ( Mikrosekunden ). Aber in anderer Software wie dem Java.time Framework (eingebaut in Java 8 und später, Nachfolger von Joda-Time) und in einigen Datenbanken wie dem H2 Database , der letzte Moment könnte 23:59.59.999999999 ( Nanosekunden ) sein. Statt Haare zu spalten, sollten Sie nur an den ersten Moment denken, nicht an den letzten.

In Half-Open beginnt ein Tag mit dem ersten Moment eines Tages und endet mit ohne den ersten Moment des folgenden Tages. Also anstatt so zu denken:

… Von heute um 00:00 Uhr (heute um Mitternacht) bis 12:00 Uhr (heute um Mitternacht).

… Denk mal so…

vom ersten Moment von heute bis zum ersten Moment von morgen, jedoch ohne:
(> = 00:00:00.0 Heute UND <00:00:00.0 Morgen)

In der Datenbankarbeit bedeutet dieser Ansatz, dass nicht den BETWEEN -Operator in SQL verwendet.

Beginn des Tages

Außerdem ist der erste Moment des Tages nicht immer die Uhrzeit 00:00:00.0. Sommerzeit (DST) in einigen Zeitzonen und möglicherweise anderen Anomalien kann eine andere Uhrzeit den Tag beginnen.

Lassen Sie also die Klassen Java.time den Beginn eines Tages mit einem Aufruf von LocalDate::atStartOfDay( ZoneId ) bestimmen. Wir müssen also umleiten durch LocalDate und zurück zu ZonedDateTime , wie Sie in diesem Beispielcode sehen können.

ZoneId zoneId = ZoneId.of( "America/Montreal" );
ZonedDateTime now = ZonedDateTime.now( zoneId );
ZonedDateTime todayStart = now.toLocalDate().atStartOfDay( zoneId );
ZonedDateTime tomorrowStart = todayStart.plusDays( 1 );

Beachten Sie die Weitergabe des optionalen ZoneId. Ohne Angabe wird die aktuelle Standardzeitzone Ihrer JVM implizit angewendet. Besser explizit zu sein.

Die Zeitzone ist für die Datums- und Uhrzeitarbeit von entscheidender Bedeutung. Die Frage und einige andere Antworten sind möglicherweise fehlerhaft, da die Zeitzone nicht bewusst behandelt wird.

Konvertieren

Wenn Sie ein Java.util.Date oder .Calendar verwenden müssen , suchen Sie nach neuen Konvertierungsmethoden, die zu diesen alten Klassen hinzugefügt wurden.

Java.util.Date utilDate = Java.util.Date.from( todayStart.toInstant() );
Java.util.GregorianCalendar gregCal = Java.util.GregorianCalendar.from( todayStart );

Zeitspanne

Übrigens, wenn Sie viel mit Zeitspannen arbeiten, schauen Sie sich Folgendes an:

  • Duration
  • Period
  • Interval
    Die Klasse Interval befindet sich im Projekt ThreeTen-Extra , einer Erweiterung des Java.time-Frameworks. Dieses Projekt ist der Beweis für mögliche zukünftige Ergänzungen von Java.time.
    Interval todayMontreal = Interval.of( todayStart.toInstant() , tomorrowStart.toInstant() );

Über Java.time

Das Java.time Framework ist in Java 8 und höher eingebaut. Diese Klassen verdrängen das lästige alte legacy Datum-Zeit-Klassen wie Java.util.Date , Calendar , & SimpleDateFormat .

Das Projekt Joda-Time , das sich jetzt im Wartungsmodus befindet, rät zur Migration auf 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 Zeichenketten, keine Notwendigkeit für Klassen Java.sql.*.

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 .

6
Basil Bourque

Dies scheint eine Option zu sein:

DateFormat justDay = new SimpleDateFormat("yyyyMMdd");
Date thisMorningMidnight = justDay.parse(justDay.format(new Date()));

entweder einen Tag hinzufügen

Date tomorrow = new Date(thisMorningMidnight.getTime() + 24 * 60 * 60 * 1000);

oder

Calendar c = Calendar.getInstance();
c.setTime(thisMorningMidnight);
c.add(Calendar.DATE, 1);
Date tomorrowFromCalendar = c.getTime();

Ich habe eine Ahnung, dass Letzteres bevorzugt wird, wenn etwas seltsam wie die Sommerzeit ist, was dazu führt, dass 24 Stunden nicht ausreichen (siehe https://stackoverflow.com/a/4336131/32453 und seine anderen Antworten).

4
rogerdpack

Ich habe das anders gemacht als alle anderen hier. Ich bin neu in Java, daher ist meine Lösung möglicherweise schlecht. 

Date now = new Date();
Date midnightToday = new Date(now.getYear(), now.getMonth(), now.getDate());

Ich bin nicht sicher, ob das noch funktioniert, aber ich würde mich über Feedback zu dieser Lösung freuen. 

Ich bin verwirrt von der obigen Aussage, die Sie morgen berechnen können, indem Sie Folgendes aufrufen:

c.add(Calendar.DAY_OF_MONTH, 1);

Wenn Sie zum Tag des Monats 1 addieren und der 31. Tag ist, erhalten Sie nicht den 32. Tag des Monats?

Warum basieren Zeiten/Datumsangaben nicht alle auf UTC in Java? Ich denke, Timezones sollten nur in Verbindung mit I/O benötigt werden, intern jedoch immer in UTC. Die Klassen scheinen jedoch Timezone-Informationen zu enthalten, die nicht nur verschwenderisch sind, sondern auch zu Codierungsfehlern neigen. 

2
Mitch

So wie die Antworten zuvor, aber niemand erwähnte den Parameter AM_PM:

    Calendar cal = Calendar.getInstance();
    cal.set(Calendar.HOUR, 0);
    cal.set(Calendar.MINUTE, 0);
    cal.set(Calendar.SECOND, 0);
    cal.set(Calendar.MILLISECOND, 0);
    cal.set(Calendar.AM_PM, Calendar.AM);
1
Montaser

Da ein Tag 24 * 60 * 60 * 1000 ms ist, kann die Mitternacht dieses Tages wie folgt berechnet werden:.

long now = System.currentTimeMillis();
long delta = now % 24 * 60 * 60 * 1000;
long midnight = now - delta;
Date midnightDate = new Date(midnight);`
1
lshu

Apache Commons verwenden ..

//For midnight today 
Date today = new Date(); 
DateUtils.truncate(today, Calendar.DATE);

//For midnight tomorrow   
Date tomorrow = DateUtils.addDays(today, 1); 
DateUtils.truncate(tomorrow, Calendar.DATE);
0
joe4java
0
Anders B
Date now= new Date();
// Today midnight
Date todayMidnight = new Date(endTime.getTime() -endTime.getTime()%DateUtils.MILLIS_PER_DAY);

// tomorrow midnight
Date tomorrowMidnight = new Date(endTime.getTime() -endTime.getTime()%DateUtils.MILLIS_PER_DAY + DateUtils.MILLIS_PER_DAY);
0
gzg_55

Der einfachste Weg mit JodaTime

DateMidnight date = DateMidnight.now();

0
Javier Sculli