Сброс временной части временной метки в Java

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

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

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

Ответ 1

Вы можете выбрать 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

Мне нравятся даты Java.

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

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

Ответ 2

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

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

Ответ 3

Предполагая, что ваша "метка времени" представляет собой 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);
}

Ответ 4

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

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

Ответ 5

Сделайте это

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

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

а выход -

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

Ответ 6

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

Ответ 7

Использование Calendar.set() было бы законным решением "по книге", но вы также можете использовать 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!

Ответ 8

Найдите ниже решение, которое использует время Joda и поддерживает часовые пояса. Таким образом, вы получите текущую дату и время (в 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;
    }
}

Ответ 9

Здесь простая функция с основным примером:

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

Ответ 10

Просто пытаюсь поставить ответ для Java-8, хотя ответы с использованием Calendar также допустимы, но многие люди больше не используют этот класс.

См. SO ответы это & это, чтобы понять преобразования между java.time.ZonedDateTime и java.sql.Timestamp

тогда вы можете просто усечь ZonedDateTime в дни & вернуться обратно к Timestamp

Timestamp.valueOf(ZonedDateTime.now().truncatedTo(ChronoUnit.DAYS).toLocalDateTime())