web-dev-qa-db-ja.com

2つの日付の時刻部分のみを比較し、日付部分は無視します

2つのDateオブジェクトが与えられた場合、年、月、日を完全に無視して、時間部分のみの違いを比較する良い方法は何ですか?

この質問 とは正反対です。

UPDATE:これが将来の参照用の最終コードです。

private long differenceBetween(Date currentTime, Date timeToRun)
{
    Calendar currentCal = Calendar.getInstance();
    currentCal.setTime(currentTime);

    Calendar runCal = Calendar.getInstance();
    runCal.setTime(timeToRun);
    runCal.set(Calendar.DAY_OF_MONTH, currentCal.get(Calendar.DAY_OF_MONTH));
    runCal.set(Calendar.MONTH, currentCal.get(Calendar.MONTH));
    runCal.set(Calendar.YEAR, currentCal.get(Calendar.YEAR));

    return currentCal.getTimeInMillis() - runCal.getTimeInMillis();
}
32
kolrie

tl; dr

最新のJava.timeクラスを使用します。

特定の時刻は、さまざまなゾーンのさまざまな日付で異なる意味を持つ可能性があるため、要求した比較は意味をなさない場合があることに注意してください。

_Duration                                  // Span of time, with resolution of nanoseconds.
.between(                                 // Calculate elapsed time.
    LocalTime.now(                        // Get current time-of-day…
        ZoneId.of( "Pacific/Auckland" )   // … as seen in a particular time zone.
    )                                     // Returns a `LocalTime` object.
    ,
    myJavaUtilDate                        // Avoid terrible legacy date-time classes such as `Java.util.Date`.
    .toInstant()                          // Convert from `Java.util.Date` to `Java.time.Instant`, both representing a moment in UTC.
    .atZone(                              // Adjust from UTC to a particular time zone. Same moment, same point on the timeline, different wall-clock time.
        ZoneId.of( "Pacific/Auckland" )   // Specify time zone by proper naming in `Continent/Region` format, never 2-4 letter pseudo-zones such as `PST`, `CEST`, `CST`, `IST`, etc.
    )                                     // Returns a `ZonedDateTime` object.
    .toLocalTime()                        // Extract the time-of-day without the date and without a time zone.
)                                         // Returns a `Duration` object.
.toMillis()                               // Calculate entire span-of-time in milliseconds. Beware of data-loss as `Instant` uses a finer resolution the milliseconds, and may carry microseconds or nanoseconds.
_

ミリ秒単位の単なる整数ではなく、タイプセーフで自明のDurationオブジェクトを渡すことをお勧めします。

Java.time

最新のアプローチでは、DateCalendarSimpleDateFormatなどのひどいレガシークラスに取って代わるJava.timeクラスを使用します。

_Java.util.Date_(UTCの瞬間)をInstantに変換します。古いクラスに追加された新しい変換メソッドを使用します。

_Instant instant = myJavaUtilDate.toInstant() ;
_

それはUTCの瞬間を表しています。日付と時刻を決定するには、 time zone が必要です。特定の瞬間において、日付と時刻は世界中でゾーンごとに異なります。たとえば、 パリフランス の真夜中の数分後は モントリオールケベック の「昨日」でありながら新しい日です。

タイムゾーンが指定されていない場合、JVMは暗黙的に現在のデフォルトのタイムゾーンを適用します。そのデフォルトは いつでも変更 実行時(!)になる可能性があるため、結果は異なる場合があります。 [希望する/期待されるタイムゾーン] [2]を引数として明示的に指定することをお勧めします。

_continent/region__America/Montreal_ のように、_Africa/Casablanca_の形式で 適切なタイムゾーン名 を指定します、または_Pacific/Auckland_。 ESTISTなどの2〜4文字の省略形は、ではない真のタイムゾーンであり、標準化されておらず、一意(!)でもないため、使用しないでください。

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

JVMの現在のデフォルトのタイムゾーンを使用する場合は、それを要求し、引数として渡します。省略した場合、JVMの現在のデフォルトが暗黙的に適用されます。デフォルトはいつでもランタイム中に JVM内の任意のアプリの任意のスレッド内の任意のコードによって変更される可能性があるため、明示的にすることをお勧めします。

_ZoneId z = ZoneId.systemDefault() ;  // Get JVM’s current default time zone.
_

ZoneIdInstantに割り当てて、ZonedDateTimeオブジェクトを生成します。

_ZonedDateTime zdt = instant.atZone( z ) ;
_

日付とタイムゾーンなしで時刻部分を抽出します。

_LocalTime lt = zdt.toLocalTime() ;
_

比較。 Duration を使用して経過時間を計算します。

_Duration d = Duration.between( ltStart , ltStop ) ;
_

これは公平な比較ではありませんであることに注意してください。日は常に24時間であるとは限らず、すべての時刻の値がすべてのゾーンのすべての日に有効であるとは限りません。たとえば、米国の夏時間の切り替え中に、午前2時がまったくない場合があります。したがって、午前1時から午前4時は、ある日付では3時間ですが、別の日付では2時間に過ぎません。


Java.timeについて

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

Joda-Time プロジェクトは現在 maintenance mode であり、 Java.time クラスへの移行を推奨しています。

詳細については、 Oracleチュートリアル を参照してください。スタックオーバーフローで多くの例と説明を検索してください。仕様は JSR 31 です。

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

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

ThreeTen-Extra プロジェクトは、追加のクラスでJava.timeを拡張します。このプロジェクトは、Java.timeに将来追加される可能性があることを証明する場です。 IntervalYearWeekYearQuarter のようないくつかの便利なクラスがここにあります。 、および more

3
Basil Bourque

日付の基になるバイナリ(long int)値を比較する場合は、次のようにできます。

public int compareTimes(Date d1, Date d2)
{
    int     t1;
    int     t2;

    t1 = (int) (d1.getTime() % (24*60*60*1000L));
    t2 = (int) (d2.getTime() % (24*60*60*1000L));
    return (t1 - t2);
}

補遺1

この手法は、ティックとカレンダーコンポーネント間で変換する代わりにlongオブジェクトの基になるDate値を直接使用するため、速度の利点があります(かなり高価で遅い)。また、Calendarオブジェクトをいじるよりもはるかに簡単です。

補遺2

上記のコードは、時間の差をintとして返します。これは、日付の年/月/日の部分を完全に無視し、2つの時間の差はないため、すべての時間のペアに対して正しくなります。 86,400,000ミリ秒以上(= 1000ミリ秒/秒×60秒/分×60分/時間×24時間/日)。

31
David R Tribble

時間のみに基づいて2つのJoda日付を比較するコンパレーターに、Joda時間のDateTimeComparator.getTimeOnlyInstance()を使用することを検討できます。

例えば:

DateTimeComparator comparator = DateTimeComparator.getTimeOnlyInstance();
comparator.compare(date1, date2);

http://joda-time.sourceforge.net/api-release/org/joda/time/DateTimeComparator.html#getTimeOnlyInstance() を参照してください

19
James

Calendar クラスを見てください。与えられたDateから時間、分、秒を抽出するためのサポートがあります。

Calendar calendar = Calendar.getInstance();
calendar.setTime(yourDateObject);
int hour = calendar.get(Calendar.HOUR);
int minute = calendar.get(Calendar.MINUTE);
int second = calendar.get(Calendar.SECOND);
5

JODAが使えない場合は、

2つのカレンダーオブジェクトを作成し、年、月、日を0に設定します。

それらを比較...

1
bbaja42

これがどれほど優れているか、または効率的であるかわかりませんが、目的を果たすDateオブジェクトを使用して簡単な関数を記述しました。最初の日付の値が2番目の日付よりも大きい場合、trueまたはfalseを返します。入力d1 && d2はDateオブジェクトです。

function CompareTimes(d1, d2) {
             if (d1.getHours() < d2.getHours()) {
                 return false;
             }
             if (d1.getHours() > d2.getHours()) {
                 return true;

             } else {
                 return (d1.getMinutes() > d2.getMinutes());
             }
};
1
Dennis Puzak

JODAがオプションではない場合、最も短いアプローチの1つは、おそらく時間を文字列に変換してから比較することです。

DateFormat df = new SimpleDateFormat("HHmmssSZ");
df.format(date1).equals(df.format(date2));
1
vanto

日付の時間部分を比較したいだけなら、これはあなたに正しい結果を与えるでしょう-

public long compareTimes(Date d1, Date d2)
    {
        long     t1;
        long     t2;
        t1 = d1.getHours()*60*60+d1.getMinutes()*60+d1.getSeconds();
        t2 = d2.getHours()*60*60+d2.getMinutes()*60+d2.getSeconds();
        long diff = t1-t2;
        System.out.println("t1 - "+t1+", t2 - "+t2+",  diff - "+diff);

        return diff;
    }
0
Amit