Domanda

In Java, dato un timestamp, come reimpostare la sola parte temporale alle 00:00:00 in modo che il timestamp rappresenti la mezzanotte di quel particolare giorno?

In T-SQL, questa query farà lo stesso, ma non so come farlo in Java.

SELEZIONA CAST (FLOOR (CAST (GETDATE () AS FLOAT)) COME DATETIME) COME 'DateTimeAtMidnight';

È stato utile?

Soluzione

Puoi selezionare Date- > Calendar- > set- > Date:

Date date = new Date();                      // timestamp now
Calendar cal = Calendar.getInstance();       // get calendar instance
cal.setTime(date);                           // set cal to date
cal.set(Calendar.HOUR_OF_DAY, 0);            // set hour to midnight
cal.set(Calendar.MINUTE, 0);                 // set minute in hour
cal.set(Calendar.SECOND, 0);                 // set second in minute
cal.set(Calendar.MILLISECOND, 0);            // set millis in second
Date zeroedDate = cal.getTime();             // actually computes the new Date

Adoro le date di Java.

Nota che se stai usando java.sql.Timestamps reali, hanno un campo nanos extra. Il calendario ovviamente non conosce nulla dei nanos, quindi lo ignorerà alla cieca e lo lascerà cadere in modo efficace quando si crea alla fine la data zero, che è quindi possibile utilizzare per creare un nuovo oggetto Timetamp.

Dovrei anche notare che Calendar non è thread-safe, quindi non pensare che puoi creare una singola istanza cal statica chiamata da più thread per evitare di creare nuove istanze di Calendar.

Altri suggerimenti

Se stai usando lang comuni puoi chiamare DateUtils.truncate . Ecco il documentazione javadoc .

Fa la stessa cosa che @Alex Miller ha detto di fare.

Supponendo che il tuo " timestamp " è un java.util.Date, che è rappresentato come il numero di millisecondi dall'inizio dell'epoca (1 gennaio 1970), è possibile eseguire l'aritmetica seguente:

public static Date stripTimePortion(Date timestamp) {
    long msInDay = 1000 * 60 * 60 * 24; // Number of milliseconds in a day
    long msPortion = timestamp.getTime() % msInDay;
    return new Date(timestamp.getTime() - msPortion);
}

Preferisco questa soluzione:

GregorianCalendar now = new GregorianCalendar();
GregorianCalendar calendar = new GregorianCalendar(
              now.get(GregorianCalendar.YEAR), now.get(GregorianCalendar.MONTH), 
              now.get(GregorianCalendar.DAY_OF_MONTH));

Fallo

import org.apache.commons.lang.time.DateUtils;

Date myDate = new Date();
System.out.println(myDate);        
System.out.println(DateUtils.truncate(myDate, Calendar.DATE));

e l'output è

Mer 19 Mar 14:16:47 PDT 2014
Mer 19 Mar 00:00:00 PDT 2014

Dato che non faccio molta manipolazione di DateTime, questo potrebbe non essere il modo migliore per farlo. Genererei un Calendario e userei la Data come fonte. Quindi impostare ore, minuti e secondi su 0 e riconvertire nuovamente in Data. Sarebbe bello vedere un modo migliore, però.

L'uso di Calendar.set () sarebbe sicuramente "dal libro" soluzione, ma potresti anche utilizzare java.sql.Date:

java.util.Date originalDate = new java.util.Date();
java.sql.Date wantedDate = new java.sql.Date(originalDate.getTime());

Questo farebbe esattamente quello che vuoi da:

  

Per conformarsi alla definizione di SQL DATE, i valori in millisecondi racchiusi da un'istanza java.sql.Date devono essere "normalizzati" impostando le ore, i minuti, i secondi e i millisecondi a zero nel particolare fuso orario con cui il l'istanza è associata.

Poiché java.sql.Date estende java.util.Date, puoi utilizzarlo liberamente come tale. Tieni presente che WantDate.getTime () recupererà il timestamp originale, ecco perché non vuoi creare un altro java.util.Date da java.sql.Date!

Trova di seguito una soluzione che utilizza Joda Time e supporta i fusi orari. Pertanto, otterrai la data e l'ora correnti (in currentDate e currentTime ) o una data e ora che informi (in informatedDate e informatoTime ) nel fuso orario attualmente configurato nella JVM.

Il codice seguente informa anche se la data / ora informate è futura (variabile programmabile ).

Si noti che Joda Time non supporta secondi bisestili . Quindi, puoi avere circa 26 o 27 secondi sul valore reale. Questo probabilmente sarà risolto solo nei prossimi 50 anni, quando l'errore accumulato sarà più vicino a 1 minuto e le persone inizieranno a preoccuparsene.

Vedi anche: https://en.wikipedia.org/wiki/Leap_second

/**
 * This class splits the current date/time (now!) and an informed date/time into their components:
 * <lu>
 *     <li>schedulable: if the informed date/time is in the present (now!) or in future.</li>
 *     <li>informedDate: the date (only) part of the informed date/time</li>
 *     <li>informedTime: the time (only) part of the informed date/time</li>
 *     <li>currentDate: the date (only) part of the current date/time (now!)</li>
 *     <li>currentTime: the time (only) part of the current date/time (now!)</li>
 * </lu>
 */
public class ScheduleDateTime {
    public final boolean schedulable;
    public final long millis;
    public final java.util.Date informedDate;
    public final java.util.Date informedTime;
    public final java.util.Date currentDate;
    public final java.util.Date currentTime;

    public ScheduleDateTime(long millis) {
        final long now = System.currentTimeMillis();
        this.schedulable = (millis > -1L) && (millis >= now);

        final TimeZoneUtils tz = new TimeZoneUtils();

        final java.util.Date          dmillis   = new java.util.Date( (millis > -1L) ? millis : now );
        final java.time.ZonedDateTime zdtmillis = java.time.ZonedDateTime.ofInstant(dmillis.toInstant(), java.time.ZoneId.systemDefault());
        final java.util.Date          zdmillis  = java.util.Date.from(tz.tzdate(zdtmillis));
        final java.util.Date          ztmillis  = new java.util.Date(tz.tztime(zdtmillis));

        final java.util.Date          dnow   = new java.util.Date(now);
        final java.time.ZonedDateTime zdtnow = java.time.ZonedDateTime.ofInstant(dnow.toInstant(), java.time.ZoneId.systemDefault());
        final java.util.Date          zdnow  = java.util.Date.from(tz.tzdate(zdtnow));
        final java.util.Date          ztnow  = new java.util.Date(tz.tztime(zdtnow));

        this.millis       = millis;
        this.informedDate = zdmillis;
        this.informedTime = ztmillis;
        this.currentDate  = zdnow;
        this.currentTime  = ztnow;
    }
}



public class TimeZoneUtils {

    public java.time.Instant tzdate() {
        final java.time.ZonedDateTime zdtime = java.time.ZonedDateTime.now();
        return tzdate(zdtime);
    }
    public java.time.Instant tzdate(java.time.ZonedDateTime zdtime) {
        final java.time.ZonedDateTime zddate = zdtime.truncatedTo(java.time.temporal.ChronoUnit.DAYS);
        final java.time.Instant instant = zddate.toInstant();
        return instant;
    }

    public long tztime() {
        final java.time.ZonedDateTime zdtime = java.time.ZonedDateTime.now();
        return tztime(zdtime);
     }
    public long tztime(java.time.ZonedDateTime zdtime) {
        final java.time.ZonedDateTime zddate = zdtime.truncatedTo(java.time.temporal.ChronoUnit.DAYS);
        final long millis = zddate.until(zdtime, java.time.temporal.ChronoUnit.MILLIS);
        return millis;
    }
}

Ecco una semplice funzione con un esempio principale:

import java.util.Calendar;
import java.util.Date;
public class Util {
/**
 * Returns an imprecise date/timestamp. 
 * @param date
 * @return the timestamp with zeroized seconds/milliseconds
 */
public static Date getImpreciseDate(Date date) {
   Calendar cal = Calendar.getInstance(); // get calendar instance
   cal.setTime(date);// set cal to date
   cal.set(Calendar.SECOND, 0); // zeroize seconds 
   cal.set(Calendar.MILLISECOND, 0);   // zeroize milliseconds
   return cal.getTime();
}

public static void main(String[] args){
   Date now = new Date();
   now.setTime(System.currentTimeMillis()); // set time to now
   System.out.println("Precise date:  " + Util.getImpreciseDate(now));
   System.out.println("Imprecise date:  " + Util.getImpreciseDate(now));
}
}
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top