39

Java では、タイムスタンプが与えられた場合、タイムスタンプがその特定の日の真夜中を表すように、時間部分だけを 00:00:00 にリセットする方法は?

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

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

4

10 に答える 10

81

日付 - >カレンダー - >設定 - >日付に移動できます。

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 フィールドがあることに注意してください。もちろん、Calendar は nanos について何も知らないので、盲目的に無視し、最後に zeroedDate を作成するときに効果的に削除します。これを使用して、新しい Timetamp オブジェクトを作成できます。

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

于 2008-10-22T18:38:31.013 に答える
19

commons lang を使用している場合は、DateUtils.truncate. これがjavadocのドキュメントです。

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

于 2008-10-22T21:22:41.307 に答える
7

「タイムスタンプ」がエポックの開始 (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);
}
于 2008-10-22T18:37:47.940 に答える
4

私はこの解決策を好みます:

GregorianCalendar now = new GregorianCalendar();
GregorianCalendar calendar = new GregorianCalendar(
              now.get(GregorianCalendar.YEAR), now.get(GregorianCalendar.MONTH), 
              now.get(GregorianCalendar.DAY_OF_MONTH));
于 2012-11-19T21:57:19.080 に答える
1

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

于 2008-10-22T18:38:38.767 に答える
0

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を作成したくないのです。

于 2008-10-22T19:21:25.810 に答える
0

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

以下のコードは、通知された日付/時刻が未来であるかどうかも通知します (変数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;
    }
}
于 2015-07-10T12:20:07.887 に答える
0

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

SO Answer this & thisjava.time.ZonedDateTimeを参照して、 &間の変換を理解してください。java.sql.Timestamp

ZonedDateTimeその後、単純に日数を切り捨てて再変換することができますTimestamp

Timestamp.valueOf(ZonedDateTime.now().truncatedTo(ChronoUnit.DAYS).toLocalDateTime())
于 2019-08-20T13:03:07.110 に答える