2008-10-22 7 views
38

В Java, заданной временной меткой, как сбросить только часть времени до 00:00:00, чтобы временная метка представляла собой полночь того времени?Сброс временной части временной метки в Java

В T-SQL этот запрос будет делать то же самое, но я не знаю, как это сделать в Java.

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

ответ

75

Вы можете пойти Дата-> Календарь> комплект-> Дата:

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 

Я люблю даты Java.

Обратите внимание, что если вы используете фактические java.sql.Timestamps, у них есть дополнительное поле nanos. Календарь, конечно, ничего не знает о наносах, поэтому слепо проигнорирует его и эффективно отбрасывает его при создании zeroedDate в конце, который затем можно использовать для создания нового объекта Timetamp.

Я также должен отметить, что Календарь не является потокобезопасным, поэтому не думайте, что вы можете сделать статический экземпляр одного календаря из нескольких потоков, чтобы избежать создания новых экземпляров календаря.

+18

Серьезно, кто когда-либо называл это Date? Это временная метка. –

7

Предполагая, что ваша «метка» является java.util.Date, который представлен как количество миллисекунд с начала эпохи (1 января 1970 г.), вы можете выполнить следующие арифметические операции:

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

Обратите внимание, что если дата здесь на самом деле экземпляр java.sql.Timestamp, вы бы пропустить настройку нанос до 0, который, вероятно, укусит вас в задницу позже. –

+0

Кроме того, вы делаете предположение, что секунды прыжка никогда не влияют на миллионы с эпохи. Я думаю, что это правда, но я не уверен, что это гарантировано. –

+1

Согласно javadoc для java.sql.Timestamp, getTime() все равно должен возвращать миллисекунды. GetNanos() вернет наносекунды. – thoroughly

1

Поскольку я не делаю много манипуляции с DateTime, это может быть не лучший способ сделать это. Я бы создал календарь и использовал Date как источник. Затем установите часы, минуты и секунды на 0 и преобразуйте обратно в Date. Было бы неплохо увидеть лучший способ.

0

Использование Calendar.set() будет certanly быть "по книге" решение, но вы можете также использовать java.sql.Date:

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

Что будет делать именно то, что вы хотите с:

Чтобы соответствовать определению SQL DATE, значения миллисекунд, завернутые экземпляром java.sql.Date, должны быть «нормализованы», установив часы, минуты, секунды и миллисекунды на нуль в конкретном часовом поясе, с которым экземпляр связан.

Поскольку java.sql.Date расширяет java.util.Date, вы можете свободно использовать его как таковой. Имейте в виду, что wantedDate.getTime() будет извлекать исходную временную метку, хотя - вот почему вы не хотите создавать другой java.util.Date из java.sql.Date!

+1

Это довольно опасно, я думаю. java.sql.Date не работает как java.util.Date и сохраняет полное значение. Если вы попытаетесь получить из него h/m/s, он выбрасывает IllegalArgumentException. Он также наследует java.util.Date равным, поэтому не будет сравнивать, как ожидалось, обязательно. –

18

Если вы используете commons lang, то можете позвонить по телефону DateUtils.truncate. Вот javadoc documentation.

Он делает то же самое @Alex Miller сказал.

+0

Где вы находите эту библиотеку, DateUtils? – MAbraham1

4

Я предпочитаю это решение:

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

Сделайте это

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

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

, а выход

ср 19 марта 14:16:47 PDT 2014
ср 19 марта 00: 00:00 PDT 2014

0

Найдите ниже решение, которое использует Joda T ime и поддерживает часовые пояса. Таким образом, вы получите текущую дату и время (в currentDate и currentTime), а также дату и время, когда вы сообщаете (в informedDate и informedTime) в текущем настроенном часовом поясе в JVM.

В приведенном ниже коде также сообщается, будет ли информированная дата/время в будущем (переменная schedulable).

Обратите внимание, что Joda Time не поддерживает скачок секунд. Таким образом, вы можете быть на 26 или 27 секунд от истинного значения. Вероятно, это будет разрешено только в ближайшие 50 лет, когда накопленная ошибка будет ближе к 1 минуте, и люди начнут заботиться об этом.

Смотрите также: 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

Это выглядит как [java.time] (http://docs.oracle.com/javase/8/docs/api/java/time/package-summary.html) код, а не [Joda-Time] (http://www.joda.org/joda-time/). –

0

Вот простая функция с основным, например:

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)); 
} 
} 
Смежные вопросы