web-dev-qa-db-ja.com

Javaでタイムスタンプの時間部分をリセットする

Javaでは、タイムスタンプを指定して、タイムパートのみを00:00:00にリセットして、タイムスタンプがその特定の日の真夜中を表す方法は?

T-SQLでは、このクエリで同じことを実現できますが、Javaでこれを行う方法はわかりません。

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

39
Vijay Dev

日付->カレンダー->セット->日付に移動できます:

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フィールドがあることに注意してください。カレンダーはもちろん、nanoを何も知らないので、最後にzeroedDateを作成するときにそれを盲目的に無視し、事実上それをドロップします。これを使用して、新しいTimetampオブジェクトを作成できます。

また、Calendarはスレッドセーフではないため、新しいCalendarインスタンスの作成を回避するために、複数のスレッドから呼び出される静的な単一calインスタンスを作成できるとは考えないでください。

76
Alex Miller

Commons langを使用している場合は、DateUtils.truncatejavadoc documentation です。

@Alex Millerが言ったのと同じことをします。

19
ScArcher2

「タイムスタンプ」がエポックの開始(1970年1月1日)からのミリ秒数として表されるJava.util.Dateであると仮定すると、次の算術演算を実行できます。

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

これを行う

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

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

そして出力は

2014年3月19日水曜日14:16:47 PDT 2014
3月19日水曜日00:00:00 PDT 2014

4
Ziya

私はこの解決策を好む:

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

私はDateTime操作をあまりしないので、これはそれを行うための最良の方法ではないかもしれません。カレンダーを作成し、日付をソースとして使用します。次に、時間、分、秒を0に設定し、日付に戻します。しかし、より良い方法を見ることができればうれしいです。

1
Jan Gressmann

Joda Timeを採用し、タイムゾーンをサポートするソリューションを以下に示します。したがって、現在の日付と時刻(currentDatecurrentTimeに)または通知する日付と時刻(informedDateinformedTimeに)を取得します。 JVMで現在構成されているタイムゾーン。

以下のコードは、通知された日付/時刻が将来のものであるかどうかも通知します(変数schedulable)。

Joda Timeはうるう秒をサポートしていないことに注意してください。そのため、真の値から26または27秒遅れることがあります。これはおそらく、累積エラーが1分に近くなり、人々がそれを気にし始める次の50年以内に解決されるでしょう。

参照: 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
Richard Gomes

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.sql.Dateから別のJava.util.Dateを作成したくないのです!

0
Domchi

Java-8の答えを入れようとしているだけですが、Calendarを使用した答えも有効ですが、多くの人がそのクラスを使用していません。

SO Answers thisthis を参照して、Java.time.ZonedDateTimeJava.sql.Timestampの間の変換を理解してください。

その後、単にZonedDateTimeを切り捨てて、Timestampに再変換できます。

Timestamp.valueOf(ZonedDateTime.now().truncatedTo(ChronoUnit.DAYS).toLocalDateTime())
0
Sabir Khan

主な例を使用した単純な関数を次に示します。

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