2008-10-22 14 views
38

En Java, con una marca de tiempo, ¿cómo restablecer la parte de tiempo solo a 00:00:00 para que la marca de tiempo represente la medianoche de ese día en particular?Restablecer la parte de tiempo de una marca de tiempo en Java

En T-SQL, esta consulta hará para lograr lo mismo, pero no sé cómo hacer esto en Java.

SELECT CAST(FLOOR(CAST(GETDATE() AS FLOAT)) AS DATETIME) AS 'DateTimeAtMidnight';

Respuesta

75

Usted puede ir Date-> calendario-> desechable-> Fecha:

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 

me encanta fechas de Java.

Tenga en cuenta que si utiliza java.sql.Timestamps reales, tienen un campo nanos adicional. El calendario, por supuesto, no sabe nada de los nanos, por lo que lo ignorará a ciegas y lo abandonará efectivamente al crear el zeroedDate al final, que luego podría usar para crear un nuevo objeto Timetamp.

También debo tener en cuenta que Calendar no es seguro para subprocesos, por lo tanto, no crea que puede hacer que una instancia única de llamada estática se invoque desde varios subprocesos para evitar la creación de nuevas instancias de Calendario.

+18

En serio, ¿quién lo ha llamado Fecha? Es una marca de tiempo. –

7

Asumiendo que su "marca de tiempo" es un java.util.Date, que se representa como el número de milisegundos desde el comienzo de la época (Enero 1, 1970), se pueden realizar las siguientes aritmética:

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

Tenga en cuenta que si la Fecha de aquí es en realidad una instancia java.sql.Timestamp, se perdería entorno nanos a 0 que probablemente te muerda en el trasero más tarde. –

+0

Además, está asumiendo que los segundos interminables nunca afectan al millis desde la época. Creo que es cierto, pero no estoy seguro de si está garantizado. –

+1

De acuerdo con javadoc para java.sql.Timestamp, getTime() aún debe devolver milisegundos. El getNanos() devolverá nanosegundos. – thoroughly

1

Dado que no hago mucha manipulación de DateTime, esta podría no ser la mejor manera de hacerlo. Generaría un Calendario y usaría la Fecha como fuente. Luego configure horas, minutos y segundos en 0 y conviértelos nuevamente a la fecha. Aunque sería bueno ver una mejor manera.

0

Usando Calendar.set() sería certanly ser "por el libro" solución, pero también se puede utilizar java.sql.Date:

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

que haría exactamente lo que quiere desde:

Para cumplir con la definición de SQL DATE, los valores de milisegundos envueltos por una instancia de java.sql.Date deben 'normalizarse' al establecer las horas, minutos, segundos y milisegundos en cero en la zona horaria particular con la que instancia está asociada.

Como java.sql.Date extiende java.util.Date, puede usarlo libremente como tal. Tenga en cuenta que wantedDate.getTime() recuperará la marca de tiempo original, es por eso que no desea crear otro java.util.Date desde java.sql.Date.

+1

Esto es bastante peligroso, creo. java.sql.Date no funciona como java.util.Date y aún conserva el valor completo. Si intentas obtener la h/m/s, arroja IllegalArgumentException. También hereda java.util.Date equal así que no se comparará como se espera necesariamente. –

18

Si está utilizando commons lang puede llamar al DateUtils.truncate. Aquí está el javadoc documentation.

Hace lo mismo que dijo @Alex Miller.

+0

¿Dónde encuentra esa biblioteca, DateUtils? – MAbraham1

4

prefiero esta solución:

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

Haga esto

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

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

y la salida es

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

0

Encuentre a continuación una solución que emplea Joda T ime y admite zonas horarias. Por lo tanto, obtendrá la fecha y hora actuales (en currentDate y currentTime) o alguna fecha y hora que informa (en informedDate y informedTime) en la zona horaria configurada actualmente en la JVM.

El código a continuación también informa si la fecha/hora está en el futuro (variable schedulable).

Tenga en cuenta que Joda Time no es compatible con segundos bisiestos. Por lo tanto, puede estar a unos 26 o 27 segundos del valor verdadero. Esto probablemente solo se resuelva en los próximos 50 años, cuando el error acumulado será más cercano a 1 minuto y las personas comenzarán a preocuparse por ello.

Consulte también: 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; 
    } 
} 
+0

Parece el código [java.time] (http://docs.oracle.com/javase/8/docs/api/java/time/package-summary.html), no [Joda-Time] (http://www.joda.org/joda-time/). –

0

Aquí es una función simple con un ejemplo principal:

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