web-dev-qa-db-ja.com

Java日付締め切り時刻情報

日付と時刻の情報を含むJava Dateオブジェクトがあります。時間情報を切り捨て、時間-分-秒を切り捨てるメソッドを記述したいので、日付だけが残っています。

入力例:

2008-01-01 13:15:00

期待される出力:

2008-01-01 00:00:00

ヒントはありますか?私はこのようなことをしようとしました:

(timestamp / (24 * 60 * 60 * 1000)) * (24 * 60 * 60 * 1000)

しかし、タイムゾーンに問題が発生しました。

107
Marco

recommended日付/時刻操作を行う方法は、 Calendar オブジェクトを使用することです:

Calendar cal = Calendar.getInstance(); // locale-specific
cal.setTime(dateObject);
cal.set(Calendar.HOUR_OF_DAY, 0);
cal.set(Calendar.MINUTE, 0);
cal.set(Calendar.SECOND, 0);
cal.set(Calendar.MILLISECOND, 0);
long time = cal.getTimeInMillis();
167
cletus

Apache Commons Langの DateUtils truncateメソッドを見ましたか?

Date truncatedDate = DateUtils.truncate(new Date(), Calendar.DATE);

time要素を削除します。

134
A_M

Joda を見ましたか?これはmuchより簡単で直感的な日付と時刻の操作方法です。たとえば、(たとえば) LocalDateTimeLocalDate オブジェクトの間で簡単に変換できます。

例えば(APIを説明するため)

LocalDate date = new LocalDateTime(milliseconds).toLocalDate()

さらに、日付/時刻フォーマッタに関するいくつかのスレッド安全性の問題を解決し、Javaで日付/時刻の問題を処理するために強く推奨されます。

41
Brian Agnew

Java.time クラスがJava 8以降に組み込まれたことを考慮した簡単な更新。

LocalDateTime には truncatedTo があり、ここで話していることを効果的に解決します:

LocalDateTime.now().truncatedTo(ChronoUnit.MINUTES)

これは、現在の時間を分単位でのみ表します。

2015-03-05T11:47

DAYSより小さい ChronoUnit (または TemporalUnit )を使用して切り捨てを実行できます(切り捨てはLocalDateTimeの時刻部分にのみ適用され、日付部分には適用されないため) )。

27
Adam Berry
Date date = new Date();
Calendar cal = Calendar.getInstance();
cal.setTime(date);
cal.set(Calendar.HOUR_OF_DAY, 0);
cal.set(Calendar.MINUTE, 0);
cal.set(Calendar.SECOND, 0);
cal.set(Calendar.MILLISECOND, 0);
date = cal.getTime();
25
jitter

Jodaを使用すると、簡単に予定日を取得できます。

バージョン2.7の時点(おそらく2.2よりも前のバージョン以降)で、コメンターが指摘しているように、toDateMidnightは推奨されないか、適切な名前のwithTimeAtStartOfDay()が推奨されており、

DateTime.now().withTimeAtStartOfDay()

可能。

より良いAPIの利点が追加されました。

古いバージョンでは、次のことができます

new DateTime(new Date()).toDateMidnight().toDate()
22
h7r

タイムスタンプの場合:

timestamp -= timestamp % (24 * 60 * 60 * 1000)
7
Gan Quan

新しいJava8 APIで切り捨てを行いました。私は1つの奇妙なことに直面しましたが、一般的には切り捨てられます...

Instant instant = date.toInstant();
instant = instant.truncatedTo(ChronoUnit.DAYS);
date = Date.from(instant);
6
Sergio Kosik

次のように、truncateを使用してApacheのDateUtilsを使用します。

DateUtils.truncate(Calendar.getInstance().getTime(), Calendar.DATE);

Java.util.Date JavaDocsから:

クラスDateは、特定の瞬間をミリ秒の精度で表します

およびJava.sql.Date JavaDocsから:

SQL DATEの定義に準拠するには、Java.sql.Dateインスタンスによってラップされたミリ秒値を、インスタンスが関連付けられている特定のタイムゾーンで時間、分、秒、ミリ秒をゼロに設定して「正規化」する必要があります。

したがって、時間の部分が必要ない場合は、Java.sql.Dateを使用するのが最善のアプローチです

Java.util.Date utilDate = new Java.util.Date();
Java.sql.Date sqlDate = new Java.sql.Date(System.currentTimeMillis());

出力は次のとおりです。

Java.util.Date : Thu Apr 26 16:22:53 PST 2012
Java.sql.Date  : 2012-04-26
5
Sunil Manheri

tl; dr

LocalDateTime.parse(                            // Lacking an offset or time zone, parse as a `LocalDateTime`. *Not* a specific moment in time.
    "2008-01-01 13:15:00".replace( " " , "T" )  // Alter input string to comply with ISO 8601 standard format.
)
.toLocalDate()                                  // Extract a date-only value.
.atStartOfDay(                                  // Do not assume the day starts at 00:00:00. Let class determine start-of-day.
    ZoneId.of( "Europe/Paris" )                 // Determining a specific start-of-day requires a time zone.
)                                               // Result is a `ZonedDateTime` object. At this point we have a specific moment in time, a point on the timeline.
.toString()                                     // Generate a String in standard ISO 8601 format, wisely extended to append the name of the time zone in square brackets.

2008-01-01T00:00 + 01:00 [ヨーロッパ/パリ]

目的の形式で文字列を生成するには、 DateTimeFormatter を渡します。

LocalDateTime.parse(                            // Lacking an offset or time zone, parse as a `LocalDateTime`. *Not* a specific moment in time.
    "2008-01-01 13:15:00".replace( " " , "T" )  // Alter input string to comply with ISO 8601 standard format.
)
.toLocalDate()                                  // Extract a date-only value.
.atStartOfDay(                                  // Do not assume the day starts at 00:00:00. Let class determine start-of-day.
    ZoneId.of( "Europe/Paris" )                 // Determining a specific start-of-day requires a time zone.
)                                               // Result is a `ZonedDateTime` object. At this point we have a specific moment in time, a point on the timeline.
.format(                                        // Generate a String representing the object’s value.
    DateTimeFormatter.ISO_LOCAL_DATE_TIME       // Built-in predefined formatter close to what you want. 
)
.replace( "T" , " " )                           // Replace the standard’s use of a 'T' in the middle with your desired SPACE character.

2008-01-01 00:00:00

詳細

他の回答は正しいですが、Java.timeフレームワークによって時代遅れになった古い日時クラスを使用してください。

Java.time

Java.timeフレームワークは、Java 8以降に組み込まれています。 Java.time機能の多くは、Java 6および7( ThreeTen-Backport )にバックポートされ、さらにAndroid( ThreeTenABP )に適合しています。

まず、ISO 8601形式の標準バージョンに準拠するように入力文字列を変更します。標準の ISO 8601 形式は、日時値を表す文字列の解析/生成のために、Java.timeクラスでデフォルトで使用されます。途中のSPACEをTに置き換える必要があります。

String input = "2008-01-01 13:15:00".replace( " " , "T" );  // → 2008-01-01T13:15:00

これで LocalDateTime として解析できます。ここで、「ローカル」は特定のローカリティがないことを意味します。入力に offset-from-UTC またはタイムゾーン情報がありません。

LocalDateTime ldt = LocalDateTime.parse( input );

ldt.toString()…2008-01-01T13:15:00

時刻もタイムゾーンも気にしない場合は、 LocalDate に変換します。

LocalDate ld = ldt.toLocalDate();

ld.toString()…2008-01-01

初日の瞬間

代わりに時刻を1日の最初の瞬間に設定する場合は、 ZonedDateTime クラスを使用し、LocalDateオブジェクトに変換して、その atStartOfDay メソッドを呼び出します。夏時間またはその他の異常のために、最初の瞬間は00:00:00の時間ではない可能性があることに注意してください。

タイムゾーンは非常に重要です。これは、特定の瞬間について、日付が世界中でゾーンによって異なるためです。たとえば、パリの真夜中から数分後はパリジャンにとって新しい日ですが、カナダ人にとってはモントリオールではまだ「昨日」です。

ZoneId zoneId = ZoneId.of( "America/Montreal" );
ZonedDateTime zdt = ldt.atZone( zoneId );
LocalDate ldFromZdt = zdt.toLocalDate();
ZonedDateTime zdtStartOfDay = ldFromZdt.atStartOfDay( zoneId );

zdtStartOfDay.toString()…2008-01-01T00:00:00-05:00 [アメリカ/モントリオール]

UTC

UTC タイムゾーンのレンズを通してその瞬間を確認するには、 Instant オブジェクトを抽出します。 ZonedDateTimeInstantは、タイムライン上の同じ瞬間を表しますが、2つの異なる 壁時計時間 として表示されます。

InstantはJava.timeの基本的なビルディングブロッククラスであり、常に定義によりUTCです。通常、UTCでビジネスロジック、データストレージ、およびデータ交換を行う必要があるため、このクラスを頻繁に使用します。

Instant instant = zdtStartOfDay.toInstant();

instant.toString()…2008-01-01T05:00:00Z

真夜中の行程ではなく午前5時です。標準形式では、末尾のZZuluの略で、「UTC」を意味します。


Java.timeについて

Java.time フレームワークは、Java 8以降に組み込まれています。これらのクラスは、 Java.util.DateCalendar 、& SimpleDateFormat などの厄介な古い レガシー 日時クラスに取って代わります。

メンテナンスモード になった Joda-Time プロジェクトは、 Java.time クラスへの移行を推奨しています。

詳細については、 Oracle Tutorial を参照してください。また、多くの例と説明についてはStack Overflowを検索してください。仕様は JSR 31 です。

Java.timeオブジェクトをデータベースと直接交換できます。 JDBC 4.2 以降に準拠する JDBCドライバー を使用します。文字列やJava.sql.*クラスは必要ありません。

Java.timeクラスはどこで入手できますか?

  • Java SE 8Java SE 9 、およびそれ以降
    • ビルトイン。
    • 実装がバンドルされた標準Java APIの一部。
    • Java 9は、いくつかのマイナーな機能と修正を追加します。
  • Java SE 6 および Java SE 7
    • Java.time機能の多くは、 ThreeTen-Backport のJava 6および7にバックポートされています。
  • Android
    • Androidの以降のバージョンには、Java.timeクラスの実装がバンドルされています。
    • 以前のAndroid(<26)の場合、 ThreeTenABP プロジェクトはThreeTen-Backport(上記)に適合します。 ThreeTenABPの使用方法… を参照してください。

ThreeTen-Extra プロジェクトは、追加のクラスでJava.timeを拡張します。このプロジェクトは、Java.timeに将来追加される可能性のある証明の場です。 IntervalYearWeekYearQuartermore などの便利なクラスがあります。

3
Basil Bourque

問題は矛盾しています。時刻なしの日付を要求しますが、00:00:00の時刻を持つ例を表示します。

ジョーダタイム

UPDATE:Joda-Time プロジェクトは メンテナンスモード になり、チームは移行をアドバイスしています Java.time クラスへ。 Java.timeソリューションについては、 my other Answer を参照してください。

代わりに時刻を1日の最初の瞬間に設定する場合は、Joda-Timeライブラリで DateTime オブジェクトを使用し、その withTimeAtStartOfDay メソッドを呼び出します。夏時間やその他の異常のために、最初の瞬間は00:00:00の時間ではないことに注意してください。

2
Basil Bourque

ただclear()冗長フィールド。

Calendar calendar = Calendar.getInstance();
calendar.setTime(date);
calendar.set(Calendar.HOUR_OF_DAY, 0);
calendar.clear(Calendar.MINUTE);
calendar.clear(Calendar.SECOND);
calendar.clear(Calendar.MILLISECOND);
Date truncatedDate = calendar.getTime();

Java 8以降では、truncatedToLocalDateTimeメソッドを使用することをお勧めします。例:

LocalDateTime.now().truncatedTo(ChronoUnit.DAYS)
2
m190

Calendar クラスのset()メソッドを使用して、HOUR_OF_DAY, MINUTE, SECONDおよびMILLISECONDフィールドをゼロに設定します。

2

これにより、タイムゾーンの問題を回避できます。

public static Date truncDate(Date date) {
    Calendar cal = Calendar.getInstance(TimeZone.getTimeZone("UTC"));
    cal.setTime(date);
    cal.set(Calendar.HOUR_OF_DAY, 0);
    cal.set(Calendar.MINUTE, 0);
    cal.set(Calendar.SECOND, 0);
    cal.set(Calendar.MILLISECOND, 0);
    return cal.getTime();
}

Java Dateオブジェクトはタイムスタンプ値ですが、トランケート中にローカルタイムゾーンに変換されるため、UTCタイムゾーンから値を期待する場合は驚くべき値を取得します。

1
GMsoF

新しい「改善された」カレンダーコンストラクターが、「ひどい」古い日付のようなミリ秒の整数をとらないことに本当に悩まされました。それから私は本当に交差し、これを書いた:

long stuffYou = startTime.getTimeInMillis() % 1000;
startTime.setTimeInMillis(startTime.getTimeInMillis() - stuffYou);

当時は「もの」という言葉を使用していませんでしたが、次の幸福を発見しました。

startTime.set(Calendar.MILLISECOND, 0);

しかし、私はまだそれについてかなり交差しています。

1
Dave

Java 8+を使用している場合、時間なしで日付を取得する簡単な方法は次のとおりです。Dateの代わりにJava.time.LocalDateタイプを使用します。

LocalDate now = LocalDate.now();
 System.out.println(now.toString());

出力:

2019-05-30

https://docs.Oracle.com/javase/8/docs/api/Java/time/LocalDate.html

0
Amy Doxy

応答が遅れるかもしれませんが、ライブラリを使用せずに1行で実行する方法を次に示します。

new SimpleDateFormat("yyyy-MM-dd").parse(new SimpleDateFormat("yyyy-MM-dd").format(YOUR_TIMESTAMP))
0
Alex

カレンダーを使用したすべての回答については、代わりにこのように使用する必要があります

public static Date truncateDate(Date date) {
    Calendar c = Calendar.getInstance();
    c.setTime(date);
    c.set(Calendar.HOUR_OF_DAY, c.getActualMinimum(Calendar.HOUR_OF_DAY));
    c.set(Calendar.MINUTE, c.getActualMinimum(Calendar.MINUTE));
    c.set(Calendar.SECOND, c.getActualMinimum(Calendar.SECOND));
    c.set(Calendar.MILLISECOND, c.getActualMinimum(Calendar.MILLISECOND));
    return c.getTime();
}

しかし、私はこれを好む:

public static Date truncateDate(Date date) {
    return new Java.sql.Date(date.getTime());
}
0
Guest

私はこのような問題を修正しました(東部8ゾーン(北京時間)):

private Date getTruncatedDate(Date d) {
    if (d == null) {
        return null;
    }
    long h = 60 * 60 * 1000L;
    long dateStamp = d.getTime() - (d.getTime() + 8 * h) % (24 * h);
    return new Date(dateStamp);
}

まず、タイムスタンプとは何かを明確にする必要があります。タイムスタンプは、GMTの1970年1月1日00:00:00(UTCと同じ)、または1970年1月1日木曜日08:00:00 CST 1970から現在までの合計ミリ秒です。

注意:タイムスタンプはタイムゾーンに依存しません。

したがって、異なるタイムゾーンで次のステートメントを使用しても同じ結果が得られます。

System.out.println(new Date().getTime());

そして

System.out.println(new Date(0));

異なるタイムゾーンで異なる時間情報を出力します。PCタイムゾーンをUTCに設定すると、

Thu Jan 01 00:00:00 UTC 1970

ただし、タイムゾーンを(UTC +8:00)北京、重慶、香港、ウルムクに設定すると、次のようになります。

Thu Jan 01 08:00:00 CST 1970

Javaはタイムスタンプを取得し、タイムゾーンに従って日付と時刻の情報を表示します。

Javaがさまざまなタイムゾーンで日付と時刻の情報を表示する方法の概要については、時刻情報を変換する方法は簡単です。タイムスタンプを取得し、時間情報を切断するときにタイムゾーンを考慮する必要があります。次に、カットタイムスタンプ(日付スタンプと呼ぶことができます)を使用して新しいDateオブジェクトを作成できます。Javaは、日付情報を表示するときにタイムゾーンを補正します。

東部8ゾーン(北京時間)と同様に、北京時間はGMTより8時間早いため、モジュロ演算を行う場合はさらに8時間を差し引く必要があります。つまり、GMT時間を最初に取得する必要があります。その後、Javaは、PCのタイムゾーン設定に基づいて時間を表示するときに8時間を追加します。


タイムゾーンの問題はあいまいであり、長い間私を困惑させます。今、私はそれを明確にします。希望が役立ちます。


2018-01-04以下の方法も機能します。

private Date getTruncatedDate2(Date d) {
    Calendar cal = Calendar.getInstance(); // locale-specific
    cal.setTime(d);
    cal.set(Calendar.HOUR_OF_DAY, 0);
    cal.set(Calendar.MINUTE, 0);
    cal.set(Calendar.SECOND, 0);
    cal.set(Calendar.MILLISECOND, 0);


return cal.getTime();

}

0
Gelbert

Joda-Time バージョン2.0以降では、LocalDate.toDate()を使用できます。

単に

// someDatetime is whatever Java.util.Date you have.
Date someDay = new LocalDate(someDatetime).toDate();
0
lamusique