時間を00:00:00に設定します


121

Javaでの時間のリセットに問題があります。特定の日付について、時間を00:00:00に設定します。

これは私のコードです:

/**
     * Resets milliseconds, seconds, minutes and hours from the provided date
     *
     * @param date
     * @return
     */
    public static Date trim(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.set(Calendar.MILLISECOND, 0);
        calendar.set(Calendar.SECOND, 0);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.HOUR, 0);

        return calendar.getTime();
    }

問題は時々時間があるということである12:00:00、時にはそれがある00:00:00と私は上に保存されたエンティティーのためのデータベース照会時に07.02.2013 00:00:00格納され、実際のエンティティの時間を、ある12:00:00クエリが失敗しました。

知っ12:00:00 == 00:00:00てる!

AppEngineを使用しています。これはappengineのバグ、問題、またはその他の問題ですか?それとも別のものに依存していますか?


これは異なるロケールに関係しているのでしょうか、それとも常に同じPCから発生しますか?
LostBoy 2013

appengineにデプロイすると発生します。
アデリン2013

時間を短縮するための他の多くのソリューション:stackoverflow.com/a/1908955/2646526
heenenee

FYI、といった面倒な古い日付時刻クラスjava.util.Datejava.util.Calendarjava.text.SimpleDateFormat今のレガシーに取って代わられ、java.timeの Javaの8&9のJavaを参照してくださいに組み込まれたクラスOracleでのチュートリアル
バジルブルク2018

1
私はを使用しましたがcalendar.set(Calendar.HOUR_OF_DAY, 0);、私の目的のために、それはうまくいきます。
hariprasad

回答:


209

別の定数の代わりに使用しCalendar.HOUR、使用しますCalendar.HOUR_OF_DAY

calendar.set(Calendar.HOUR_OF_DAY, 0);

Calendar.HOUR0〜11(AM / PMでCalendar.HOUR_OF_DAY使用)を使用し、0〜23 を使用します。

Javadocsを引用するには:

public static final int HOUR

午前または午後の時間を示すgetおよびsetのフィールド番号。HOURは12時間制(0-11)に使用されます。正午と真夜中は12ではなく0で表されます。たとえば、午後10:04:15.250 PMのHOURは10です。

そして

public static final int HOUR_OF_DAY

時刻を示すgetおよびsetのフィールド番号。HOUR_OF_DAYは24時間制で使用されます。たとえば、10:04:15.250 PMのHOUR_OF_DAYは22です。

テスト(「現在」は現在、2013年7月23日太平洋夏時間の14時55分頃):

public class Main
{
   static SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

    public static void main(String[] args)
    {
        Calendar now = Calendar.getInstance();
        now.set(Calendar.HOUR, 0);
        now.set(Calendar.MINUTE, 0);
        now.set(Calendar.SECOND, 0);
        System.out.println(sdf.format(now.getTime()));
        now.set(Calendar.HOUR_OF_DAY, 0);
        System.out.println(sdf.format(now.getTime()));
    }
}

出力:

$ javac Main.java
$ java Main
2013-07-23 12:00:00
2013-07-23 00:00:00

3
@JarrodRobersonしかし、使用Calendar.HOURしてもPMはAMに設定されず、12:00正午のままになります。
rgettman 2013

時間、分、秒でLocalDateを作成するのを手伝ってくれませんか?1つのオプションは、DateTimeに従うことです。
ウッディ

11
フィールドHOURとHOUR_OF_DAYを作成した人は誰でも、フラッグされて配給されるべきでした。
AndroidDev 2015

1
@AndroidDev am / pmを発明した人なら誰でも同じに値します...これは非メトリック標準にも
当てはまり

1
FYI、といった面倒な古い日付時刻クラスjava.util.Datejava.util.Calendarjava.text.SimpleDateFormat今のレガシーに取って代わられ、java.timeの Javaの8&9のJavaを参照してくださいに組み込まれたクラスOracleでのチュートリアル
バジルブルク2018

29

java.time

java.timeJava 8以降に組み込まれているフレームワークを使用します。チュートリアルを参照してください。

import java.time.LocalTime;
import java.time.LocalDateTime;

LocalDateTime now = LocalDateTime.now(); # 2015-11-19T19:42:19.224
# start of a day
now.with(LocalTime.MIN); # 2015-11-19T00:00
now.with(LocalTime.MIDNIGHT); # 2015-11-19T00:00

時刻(時間、分、秒などの部分)が必要ない場合は、LocalDateクラスの使用を検討してください。

LocalDate.now(); # 2015-11-19

この質問が最初に尋ねられてからJava 1.8がリリースされて以来、これは新しい受け入れられた答えになるはずです。
マットフォーサイス2018

LocalDateTimeこれに使用するクラスはまったく間違っています。タイムゾーンやUTCからのオフセットの概念がないため、瞬間を表すことはできません。電話をLocalDateTime.nowかけることはほとんど意味がありません。ZonedDateTime代わりに使用してください。それ以外の場合は、重要なタイムゾーンの問題を無視しています。1つの理由として、一部のゾーンの一部の日付が00:00に開始されないことがあります。
バジルブルク

12

これを行うために使用するユーティリティ関数をいくつか示します。

/**
 * sets all the time related fields to ZERO!
 *
 * @param date
 *
 * @return Date with hours, minutes, seconds and ms set to ZERO!
 */
public static Date zeroTime( final Date date )
{
    return DateTimeUtil.setTime( date, 0, 0, 0, 0 );
}

/**
 * Set the time of the given Date
 *
 * @param date
 * @param hourOfDay
 * @param minute
 * @param second
 * @param ms
 *
 * @return new instance of java.util.Date with the time set
 */
public static Date setTime( final Date date, final int hourOfDay, final int minute, final int second, final int ms )
{
    final GregorianCalendar gc = new GregorianCalendar();
    gc.setTime( date );
    gc.set( Calendar.HOUR_OF_DAY, hourOfDay );
    gc.set( Calendar.MINUTE, minute );
    gc.set( Calendar.SECOND, second );
    gc.set( Calendar.MILLISECOND, ms );
    return gc.getTime();
}

6

もう1つのJAVA 8ウェイ:

LocalDateTime localDateTime = LocalDateTime.now().truncatedTo(ChronoUnit.HOURS);

しかし、すでに存在する日付を編集する方がはるかに便利です。


1
LocalDateTimeタイムゾーンやUTCからのオフセットの概念がないため、瞬間を表すことはできません。電話をLocalDateTime.nowかけることはほとんど意味がありません。ZonedDateTime代わりに使用する必要があります。
バジルブルク

3

次のように、主にタイムゾーンをDateFormatコンポーネントに設定することをお勧めします。

DateFormat dateFormat = new SimpleDateFormat("HH:mm:ss");
dateFormat.setTimeZone(TimeZone.getTimeZone("GMT"));

次に、フォーマッタに0ミリ秒を渡すと、「00:00:00」の時間を取得できます。

String time = dateFormat.format(0);

または、Dateオブジェクトを作成できます。

Date date = new Date(0); // also pass milliseconds
String time = dateFormat.foramt(date);

または、カレンダーコンポーネントを使用してより多くの可能性を持つことができますが、タイムゾーンをGMTとしてカレンダーインスタンスに設定する必要もあります。

Calendar calendar = Calendar.getInstance(TimeZone.getTimeZone("GMT"), Locale.US);
calendar.set(Calendar.HOUR_OF_DAY, 5);
calendar.set(Calendar.MINUTE, 37);
calendar.set(Calendar.SECOND, 27);

dateFormat.format(calendar.getTime());

2

tl; dr

myJavaUtilDate                                 // The terrible `java.util.Date` class is now legacy. Use *java.time* instead.
.toInstant()                                   // Convert this moment in UTC from the legacy class `Date` to the modern class `Instant`.
.atZone( ZoneId.of( "Africa/Tunis" ) )         // Adjust from UTC to the wall-clock time used by the people of a particular region (a time zone).
.toLocalDate()                                 // Extract the date-only portion.
.atStartOfDay( ZoneId.of( "Africa/Tunis" ) )   // Determine the first moment of that date in that zone. The day does *not* always start at 00:00:00.

java.time

あなたは何年も前にJSR 310で定義された最新のjava.timeクラスに取って代わられたひどい古い日時クラスを使用しています。

DateInstant

A java.util.DateはUTCの瞬間を表します。交換はInstantです。古いクラスに追加された新しい変換メソッドを呼び出します。

Instant instant = myJavaUtilDate.toInstant() ;

タイムゾーン

新しい時刻を有効にするタイムゾーンを指定します。

指定適切なタイムゾーン名をの形式でContinent/Region、のようなAmerica/MontrealAfrica/CasablancaまたはPacific/Auckland。決してなど2-4文字の略称を使用していないESTか、ISTそのままではない真の時間帯ではなく、標準化、さらには一意ではありません(!)。

ZoneId z = ZoneId.of( "America/Montreal" ) ;

ZonedDateTime

をに適用ZoneIdしてInstantを取得しZonedDateTimeます。同じ瞬間、タイムライン上の同じポイントですが、実時間は異なります。

ZonedDateTime zdt = instant.atZone( z ) ;

時刻の変更

時刻を変更するように要求しました。a LocalTimeを適用して、時間、分、秒、小数秒のすべての時刻部分を変更します。ZonedDateTime元の値に基づいて、新しいものがインスタンス化されます。java.timeのクラスは、この使用不変オブジェクトを提供するために、パターンをスレッドセーフに

LocalTime lt = LocalTime.of( 15 , 30 ) ;  // 3:30 PM.
ZonedDateTime zdtAtThreeThirty = zdt.with( lt ) ; 

一日の最初の瞬間

しかし、特に00:00を要求しました。だから、どうやらあなたは一日の最初の瞬間を望んでいる。注意:一部のゾーンでは、00:00:00に開始されない日があります。夏時間(DST)などの異常のため、01:00:00などの別の時間に開始される場合があります。

してみましょうjava.timeは最初の瞬間を決定します。日付のみの部分を抽出します。次に、タイムゾーンを渡して最初の瞬間を取得します。

LocalDate ld = zdt.toLocalDate() ;
ZonedDateTime zdtFirstMomentOfDay = ld.atStartOfDay( z ) ;

UTCに調整

UTCに戻る必要がある場合は、を抽出しInstantます。

Instant instant = zdtFirstMomentOfDay.toInstant() ;

InstantDate

java.timejava.util.Dateまだ更新されていない古いコードと相互運用する必要がある場合は、変換してください。

java.util.Date d = java.util.Date.from( instant ) ;

1

これを行う方が簡単かもしれません(Java 8の場合)

LocalTime.ofNanoOfDay(0)

ありがとう、私は過去2年間、そしてそれ以前はJava 6/7で他のものを扱っていました。私はJavaに戻って(Groovyでいくつかの作業を行った後)、Java 8の違いを気に入っています。
meszias 2017

1

Java 8 / Joda -datetime apiの LocalDateクラスを使用して、java.util.Date時間部分を00:00:00に設定できます

Date datewithTime = new Date() ; // ex: Sat Apr 21 01:30:44 IST 2018
LocalDate localDate = LocalDate.fromDateFields(datewithTime);
Date datewithoutTime = localDate.toDate(); // Sat Apr 21 00:00:00 IST 2018

1

文字列のフォーマット00:00:00が必要な場合は、以下のようにSimpleDateFormatを使用する必要があります。「h」ではなく「H」を使用します。

Date today = new Date();
SimpleDateFormat ft = new SimpleDateFormat("dd-MM-yyyy HH:mm:ss"); 
//not SimpleDateFormat("dd-MM-yyyy hh:mm:ss")
Calendar calendarDM = Calendar.getInstance();
calendarDM.setTime(today);
calendarDM.set(Calendar.HOUR, 0);
calendarDM.set(Calendar.MINUTE, 0);
calendarDM.set(Calendar.SECOND, 0);
System.out.println("Current Date: " + ft.format(calendarDM.getTime()));

//Result is: Current Date: 29-10-2018 00:00:00

0

これを行う別の方法は、秒なしでDateFormatを使用することです。

public static Date trim(Date date) {
    DateFormat format = new SimpleDateFormat("dd.MM.yyyy");
    Date trimmed = null;
    try {
        trimmed = format.parse(format.format(date));
    } catch (ParseException e) {} // will never happen
    return trimmed;
}

0

次のいずれかでこれを行うことができます。

Calendar cal = Calendar.getInstance();
cal.set(year, month, dayOfMonth, 0, 0, 0);
Date date = cal.getTime();

0

Java8が新しい日付関数を追加すると、これを簡単に行うことができます。


    // If you have instant, then:
    Instant instant1 = Instant.now();
    Instant day1 = instant1.truncatedTo(ChronoUnit.DAYS);
    System.out.println(day1); //2019-01-14T00:00:00Z

    // If you have Date, then:
    Date date = new Date();
    Instant instant2 = date.toInstant();
    Instant day2 = instant2.truncatedTo(ChronoUnit.DAYS);
    System.out.println(day2); //2019-01-14T00:00:00Z

    // If you have LocalDateTime, then:
    LocalDateTime dateTime = LocalDateTime.now();
    LocalDateTime day3 = dateTime.truncatedTo(ChronoUnit.DAYS);
    System.out.println(day3); //2019-01-14T00:00
    String format = day3.format(DateTimeFormatter.ISO_LOCAL_DATE_TIME);
    System.out.println(format);//2019-01-14T00:00:00


LocalDateTimeタイムゾーンやUTCからのオフセットの概念がないため、瞬間を表すことはできません。電話をLocalDateTime.nowかけることはほとんど意味がありません。ZonedDateTime代わりに使用する必要があります。
バジルブルク
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.