come creare un object Data Java di mezzanotte oggi e mezzanotte di domani?

Nel mio codice ho bisogno di trovare tutte le mie cose che sono successe oggi. Quindi devo confrontarmi con le date di oggi alle 00:00 (mezzanotte di questa mattina) alle 12:00 (mezzanotte di stasera).

Lo so …

Date today = new Date(); 

… mi prende adesso. E …

 Date beginning = new Date(0); 

… mi fa perdere tempo il 1 gennaio 1970. Ma quale è un modo semplice per ottenere il tempo zero oggi e zero domani?

AGGIORNARE; L’ho fatto, ma sicuramente c’è un modo più semplice?

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

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 e 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-Time

Se stai usando un JDK <8, ti consiglio Joda Time , perché l'API è davvero carina:

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

Dalla versione 2.3 di Joda Time DateMidnight è deprecato , quindi usa questo:

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

Passa un fuso orario se non vuoi il fuso orario predefinito della JVM.

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

Ricorda, la Date non viene utilizzata per rappresentare le date (!). Per rappresentare la data è necessario un calendario. Questo:

 Calendar c = new GregorianCalendar(); 

creerà un’istanza di Calendar rappresenta la data presente nel tuo fuso orario corrente. Ora ciò che ti serve è troncare ogni campo sotto il giorno (ora, minuto, secondo e millisecondo) impostandolo su 0 . Adesso hai una mezzanotte oggi.

Ora per ottenere la mezzanotte del giorno successivo, è necessario aggiungere un giorno:

 c.add(Calendar.DAY_OF_MONTH, 1); 

Tieni presente che l’aggiunta di 86400 secondi o 24 ore non è corretta a causa dell’ora legale che potrebbe verificarsi nel frattempo.

AGGIORNAMENTO: Comunque il mio modo preferito per affrontare questo problema è usare la class DateUtils da Commons Lang :

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

Usa il Calendar dietro le quinte …

Il modo più semplice per trovare una mezzanotte:

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

Il giorno dopo:

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

Per completezza, se si utilizza Java 8 è anche ansible utilizzare il metodo truncatedTo della class Instant per ottenere la mezzanotte in UTC .

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

Come scritto nel Javadoc

Ad esempio, il troncamento con l’unità MINUTES verrà arrotondato al minuto più vicino, impostando i secondi e i nanosecondi a zero.

Spero che sia d’aiuto.

A partire da JodaTime 2.3, toDateMidnight() è deprecato.

Da Upgrade da 2.2 a 2.3

     Rinunce da 2.2
     ----------------------
     - DateMidnight [# 41]
      Questa class è imperfetta nel concetto
      Il tempo di mezzanotte occasionalmente non si verifica in alcuni fusi orari
      Questo è il risultato di un ora legale dalle 00:00 all'01: 00
      DateMidnight è essenzialmente un DateTime con un orario bloccato a mezzanotte
      Tale concetto è in genere più povero da utilizzare, dato LocalDate
      Sostituisci DateMidnight con LocalDate
      Oppure sostituirlo con DateTime, magari usando il metodo withTimeAtStartOfDay ()

Ecco un codice di esempio senza il metodo toDateMidnight() .

Codice

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

Uscita ( può essere diversa a seconda del fuso orario locale )

 2013-09-28 00:00:00 

questi metodi ti aiuteranno-

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

e

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

java.time

Se stai usando Java 8 e versioni successive, puoi provare il pacchetto java.time ( Tutorial ):

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

Questa sembra essere un’opzione:

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

per aggiungere un giorno ad esso, neanche

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

o

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

Ho la sensazione che quest’ultimo sia preferito in caso di qualcosa di strano come l’ora legale che causa l’aggiunta di 24 ore per non essere sufficiente (consultare https://stackoverflow.com/a/4336131/32453 e le altre risposte).

Altre risposte sono corrette, specialmente la risposta java.time di arganzheng . Come già detto, dovresti evitare le vecchie classi java.util.Date/.Calendar in quanto sono mal progettate, confuse e problematiche. Sono stati soppiantati dalle classi java.time.

Permettetemi di aggiungere note sulla strategia in merito alla gestione di mezzanotte e intervalli di tempo .

Mezzo aperto

Nel lavoro con data e ora, gli intervalli di tempo vengono spesso definiti utilizzando l’approccio “Semiaperto”. In questo approccio l’inizio è inclusivo mentre il finale è esclusivo . Questo risolve i problemi e, se utilizzato coerentemente, rende molto più semplice il ragionamento sulla gestione delle date.

Un problema risolto sta definendo la fine della giornata. È l’ultimo momento del giorno 23:59:59.999 ( millisecondi )? Forse, nella class java.util.Date (dal primo in Java, fastidioso – evitare questa class!) E nella libreria di Joda-Time di grande successo. Ma in altri software, come un database come Postgres, l’ultimo momento sarà 23:59:59.999999 ( microsecondi ). Ma in altri software come il framework java.time (integrato in Java 8 e versioni successive, successore di Joda-Time) e in alcuni database come H2 Database , l’ultimo momento potrebbe essere 23:59.59.999999999 ( nanosecondi ). Piuttosto che spaccare i capelli, pensa in termini di primo momento soltanto, non all’ultimo momento.

In Half-Open, un giorno va dal primo momento di un giorno e sale fino a ma non include il primo momento del giorno seguente. Quindi piuttosto che pensare in questo modo:

… da oggi alle 00:00 (mezzanotte di questa mattina) alle 12:00 (mezzanotte di stasera).

… pensa come questo …

dal primo momento di oggi correndo fino a escludere il primo momento di domani:
(> = 00:00:00.0 oggi AND < 00:00:00.0 domani)

Nel lavoro di database, questo approccio significa non utilizzare l’ operatore BETWEEN in SQL.

Inizio della giornata

Inoltre, il primo momento della giornata non è sempre l’ora del giorno 00:00:00.0 . L’ora legale (DST) in alcuni fusi orari e, eventualmente, altre anomalie, può significare che un orario diverso inizia la giornata.

Pertanto, le classi java.time eseguono il lavoro di determinazione dell’avvio di un giorno con una chiamata a LocalDate::atStartOfDay( ZoneId ) . Quindi dobbiamo deviare attraverso LocalDate e tornare a ZonedDateTime come puoi vedere in questo codice di esempio.

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

Nota il passaggio del ZoneId opzionale. Se omesso, l’attuale fuso orario predefinito della JVM viene applicato implicitamente. Meglio essere espliciti.

Il fuso orario è fondamentale per il lavoro di data e ora. La domanda e alcune altre risposte sono potenzialmente errate perché non gestiscono consapevolmente il fuso orario.

Convertire

Se è necessario utilizzare un java.util.Date o .Calendar, cercare nuovi metodi di conversione aggiunti a quelle vecchie classi.

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

Lasso di tempo

A proposito, se stai facendo molto lavoro con spanne di tempo dai un’occhiata a:

  • Duration
  • Period
  • Interval
    La class Interval si trova nel progetto ThreeTen-Extra , un’estensione del framework java.time. Questo progetto è il terreno di prova per eventuali future aggiunte a java.time.
    Interval todayMontreal = Interval.of( todayStart.toInstant() , tomorrowStart.toInstant() );

L’ho fatto in modo diverso rispetto a tutti gli altri qui. Sono nuovo di Java, quindi forse la mia soluzione è scarsa.

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

Non sono sicuro che funzioni ancora, ma in ogni caso, apprezzerei qualsiasi feedback su questa soluzione.

Sono confuso dalla dichiarazione di cui sopra che puoi calcolare domani chiamando:

 c.add(Calendar.DAY_OF_MONTH, 1); 

Se aggiungi 1 al giorno del mese ed è il 31 ° giorno, non ottieni il 32 ° giorno del mese?

Perché gli orari / le date non sono tutti basati su UTC in Java? Penso che i Timezones dovrebbero essere necessari solo se usati con i / o, ma internamente dovrebbe sempre essere usato in UTC. Tuttavia, le classi sembrano includere informazioni sul fuso orario che sembrano non solo inutili, ma soggette a errori di codifica.

Praticamente come le risposte precedenti, ma nessuno ha menzionato il parametro 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); 

Il modo più semplice con JodaTime

DateMidnight date = DateMidnight.now();

A causa di un giorno è 24 * 60 * 60 * 1000 ms, la mezzanotte di questo giorno può essere calcasting come …

 long now = System.currentTimeMillis(); long delta = now % 24 * 60 * 60 * 1000; long midnight = now - delta; Date midnightDate = new Date(midnight);` 
 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); 

Vecchio stile ..

 private static Date getDateWithMidnight(){ long dateInMillis = new Date().getTime(); return new Date(dateInMillis - dateInMillis%(1000*60*60*24) - TimeZone.getDefault().getOffset(dateInMillis)); } 

So che questo è un post molto vecchio. Ho pensato di condividere le mie conoscenze qui!

Per la data di metà notte di oggi con il fuso orario esatto è ansible utilizzare il seguente

 public static Date getCurrentDateWithMidnightTS(){ return new Date(System.currentTimeMillis() - (System.currentTimeMillis()%(1000*60*60*24)) - (1000*60 * 330)); } 

Dove (1000*60 * 330) viene sottratto cioè effettivamente correlato al fuso orario ad esempio il fuso orario indiano cioè kolkata differisce di +5: 30hrs dal reale. Quindi sottraendo quello con la conversione in millisecondi.

Quindi cambia l’ultimo numero sottratto in base a te. Sto creando un prodotto, vale a dire solo con sede in India, quindi ho appena usato un timestamp specifico.

 Date todayMidnightUTC = java.sql.Date.valueOf(LocalDate.now()); Date tomorrowMidnightUTC = java.sql.Date.valueOf(LocalDate.now().plusDays(1)); Date anyMidnightLocal = java.sql.Date.valueOf(LocalDate.from(dateTime.toInstant().atZone(ZoneId.systemDefault()))); 

Ma attenzione che java.sql.Date.toInstant() genera sempre UnsupportedOperationException .

Via LocalDate per java.util.Date e viceversa conversione più semplice?