回答:
更新:当時はJoda Timeがお勧めでしたjava.time
が、可能であればJava 8以降のライブラリを使用してください。
私の好みはこれを信じられないほど簡単にするJoda Timeを使うことです:
DateTime first = ...;
DateTime second = ...;
LocalDate firstDate = first.toLocalDate();
LocalDate secondDate = second.toLocalDate();
return firstDate.compareTo(secondDate);
編集:コメントに記載されているように、使用するDateTimeComparator.getDateOnlyInstance()
とさらに簡単になります:)
// TODO: consider extracting the comparator to a field.
return DateTimeComparator.getDateOnlyInstance().compare(first, second);
(「使用ジョダ時間」について尋ねほぼすべてのSOの質問の基礎であるjava.util.Date
かjava.util.Calendar
。それは徹底的に優れたAPIです。あなたがやっている場合は何も日付/時刻と有意にあなたは、おそらくことができる場合は、あなたが実際にそれを使用する必要があります。)
あなたは絶対にしている場合は強制的に APIに建て使用するには、インスタンスの作成する必要がありCalendar
、適切な日付とし、適切なタイムゾーンを使用します。次に、各カレンダーの各フィールドを時間、分、秒、ミリ秒から0に設定し、結果の時間を比較します。Jodaソリューションと比較して間違いなくひどいです:)
タイムゾーンの部分が重要ですjava.util.Date
され、常に UTCに基づきます。私が日付に興味を持っていたほとんどの場合、それは特定のタイムゾーンの日付でした。それ自体で、Calendar
またはJoda Time を使用することを強制します(タイムゾーンを自分で説明したい場合を除きますが、これはお勧めしません)。
Android開発者向けクイックリファレンス
//Add joda library dependency to your build.gradle file
dependencies {
...
implementation 'joda-time:joda-time:2.9.9'
}
サンプルコード(例)
DateTimeComparator dateTimeComparator = DateTimeComparator.getDateOnlyInstance();
Date myDateOne = ...;
Date myDateTwo = ...;
int retVal = dateTimeComparator.compare(myDateOne, myDateTwo);
if(retVal == 0)
//both dates are equal
else if(retVal < 0)
//myDateOne is before myDateTwo
else if(retVal > 0)
//myDateOne is after myDateTwo
Apache commons-langはほとんどどこにでもあります。これはどうですか?
if (DateUtils.isSameDay(date1, date2)) {
// it's same
} else if (date1.before(date2)) {
// it's before
} else {
// it's after
}
本当にjava.util.Dateを使用したい場合は、次のようにします。
public class TimeIgnoringComparator implements Comparator<Date> {
public int compare(Date d1, Date d2) {
if (d1.getYear() != d2.getYear())
return d1.getYear() - d2.getYear();
if (d1.getMonth() != d2.getMonth())
return d1.getMonth() - d2.getMonth();
return d1.getDate() - d2.getDate();
}
}
または、代わりにカレンダーを使用します(getYear()などが非推奨であるため推奨)
public class TimeIgnoringComparator implements Comparator<Calendar> {
public int compare(Calendar c1, Calendar c2) {
if (c1.get(Calendar.YEAR) != c2.get(Calendar.YEAR))
return c1.get(Calendar.YEAR) - c2.get(Calendar.YEAR);
if (c1.get(Calendar.MONTH) != c2.get(Calendar.MONTH))
return c1.get(Calendar.MONTH) - c2.get(Calendar.MONTH);
return c1.get(Calendar.DAY_OF_MONTH) - c2.get(Calendar.DAY_OF_MONTH);
}
}
私の好みは使用することですジョダのライブラリinsetad java.util.Date
ジョダが(参照日付と時刻を区別して、直接にYearMonthDayとのDateTimeクラス)。
ただし、使用する場合はjava.util.Date
、ユーティリティメソッドを作成することをお勧めします。例えば
public static Date setTimeToMidnight(Date date) {
Calendar calendar = Calendar.getInstance();
calendar.setTime( date );
calendar.set(Calendar.HOUR_OF_DAY, 0);
calendar.set(Calendar.MINUTE, 0);
calendar.set(Calendar.SECOND, 0);
calendar.set(Calendar.MILLISECOND, 0);
return calendar.getTime();
}
この代替案について意見はありますか?
SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
sdf.format(date1).equals(sdf.format(date2));
==
オペレータは、必ずしも戻らないtrue
同等の文字列(使用するためequals()
)。もちろん、あなたが言及した他の比較演算子も使用できません。
sdf.format(date1).compareTo(sdf.format(date2));
。
私もJoda Timeを好みますが、代わりの方法を次に示します。
long oneDay = 24 * 60 * 60 * 1000
long d1 = first.getTime() / oneDay
long d2 = second.getTime() / oneDay
d1 == d2
編集
UTC以外の特定のタイムゾーンの日付を比較する必要がある場合に備えて、UTCを以下に示します。ただし、そのようなニーズがある場合は、Jodaに行くことをお勧めします。
long oneDay = 24 * 60 * 60 * 1000
long hoursFromUTC = -4 * 60 * 60 * 1000 // EST with Daylight Time Savings
long d1 = (first.getTime() + hoursFromUTC) / oneDay
long d2 = (second.getTime() + hoursFromUTC) / oneDay
d1 == d2
Math.abs(second.getTime() - first.getTime()) < 1000L*60*60*24
< oneDay
。
myJavaUtilDate1.toInstant()
.atZone( ZoneId.of( "America/Montreal" ) )
.toLocalDate()
.isEqual (
myJavaUtilDate2.toInstant()
.atZone( ZoneId.of( "America/Montreal" ) )
.toLocalDate()
)
Date
&などの厄介な古いレガシー日時クラスはCalendar
、現在java.timeクラスに取って代わられていません。
A java.util.Date
はUTCのタイムライン上の瞬間を表します。java.timeで同等のものはInstant
です。レガシークラスに追加された新しいメソッドを使用して変換できます。
Instant instant1 = myJavaUtilDate1.toInstant();
Instant instant2 = myJavaUtilDate2.toInstant();
日付で比較したい。日付を決定するには、タイムゾーンが重要です。どの日付でも、日付はゾーンごとに世界中で異なります。たとえば、パリの真夜中から数分後のフランスは新しい日ですが、モントリオールケベックでは「昨日」です。
指定適切なタイムゾーン名をの形式でcontinent/region
、のようなAmerica/Montreal
、Africa/Casablanca
またはPacific/Auckland
。決してなど3-4文字の略称を使用していないEST
か、IST
そのままではない真の時間帯ではなく、標準化、さらには一意ではありません(!)。
ZoneId z = ZoneId.of( "America/Montreal" );
をに適用ZoneId
してInstant
を取得しZonedDateTime
ます。
ZonedDateTime zdt1 = instant1.atZone( z );
ZonedDateTime zdt2 = instant2.atZone( z );
LocalDate
クラスは、時間日の時間帯なしなし日付専用の値を表しています。私たちは、抽出することができますLocalDate
から、ZonedDateTime
効果的に時刻部分を排除し、。
LocalDate localDate1 = zdt1.toLocalDate();
LocalDate localDate2 = zdt2.toLocalDate();
今のような方法を使用して、比較するisEqual
、isBefore
とisAfter
。
Boolean sameDate = localDate1.isEqual( localDate2 );
参照してくださいIdeOne.comでライブ実行このコードを。
instant1:2017-03-25T04:13:10.971Z | instant2:2017-03-24T22:13:10.972Z
zdt1:2017-03-25T00:13:10.971-04:00 [アメリカ/モントリオール] | zdt2:2017-03-24T18:13:10.972-04:00 [アメリカ/モントリオール]
localDate1:2017-03-25 | localDate2:2017-03-24
sameDate:false
java.timeのフレームワークは、Java 8に組み込まれており、後にされています。これらのクラスは面倒古い取って代わるレガシーのような日付時刻クラスをjava.util.Date
、Calendar
、& SimpleDateFormat
。
ジョダタイムプロジェクトは、今でメンテナンスモードへの移行をアドバイスjava.timeのクラス。
詳細については、Oracleチュートリアルを参照してください。また、スタックオーバーフローで多くの例と説明を検索してください。仕様はJSR 310です。
java.timeクラスはどこで入手できますか?
ThreeTen-エクストラプロジェクトでは、追加のクラスでjava.timeを拡張します。このプロジェクトは、java.timeに将来追加される可能性があることを証明する場です。あなたはここにいくつかの有用なクラスのような見つけることがInterval
、YearWeek
、YearQuarter
、および多くを。
「簡単」または「簡単」と呼ぶことができる2つの日付を比較する方法はないと思います。
精度を下げて2つの時間インスタンスを比較する場合(たとえば、日付の比較のみ)、タイムゾーンが比較に与える影響を常に考慮する必要があります。
場合はdate1
2タイムゾーンで発生したイベントを指定されており、date2
たイベントを指定し、ESTで発生したイベントを指定している場合、比較の影響を適切に理解するように注意する必要があります。
2つのイベントがそれぞれのタイムゾーンで同じカレンダーの日付に発生したかどうかを確認する目的ですか?または、2つの日付が特定のタイムゾーン(UTCまたはローカルTZなど)で同じカレンダーの日付に該当するかどうかを知る必要があります。
比較しようとしているのが実際に何であるかを理解したら、適切なタイムゾーンで年月日トリプルを取得して比較を行うだけです。
Jodaの時間により、実際の比較操作はかなり見栄えがよくなるかもしれませんが、比較のセマンティクスはまだ何かを理解する必要があります。
Java 8を使用している場合は、java.time.*
クラスを使用して日付を比較する必要があります-さまざまなjava.util.*
クラスよりも推奨されます
例えば; https://docs.oracle.com/javase/8/docs/api/java/time/LocalDate.html
LocalDate date1 = LocalDate.of(2016, 2, 14);
LocalDate date2 = LocalDate.of(2015, 5, 23);
date1.isAfter(date2);
時間なしで2つの日付のみを比較する場合は、次のコードが役立つ場合があります。
final SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMdd");
Date dLastUpdateDate = dateFormat.parse(20111116);
Date dCurrentDate = dateFormat.parse(dateFormat.format(new Date()));
if (dCurrentDate.after(dLastUpdateDate))
{
add your logic
}
これがこのブログの解決策です:http : //brigitzblog.blogspot.com/2011/10/java-compare-dates.html
long milliseconds1 = calendar1.getTimeInMillis();
long milliseconds2 = calendar2.getTimeInMillis();
long diff = milliseconds2 - milliseconds1;
long diffDays = diff / (24 * 60 * 60 * 1000);
System.out.println("Time in days: " + diffDays + " days.");
つまり、ミリ秒単位の時間差が1日の長さより短いかどうかを確認できます。
新しい考えかどうかはわかりませんが、私がやったように見せます
SimpleDateFormat dtf = new SimpleDateFormat("dd/MM/yyyy");
Date td_date = new Date();
String first_date = dtf.format(td_date); //First seted in String
String second_date = "30/11/2020"; //Second date you can set hear in String
String result = (first_date.equals(second_date)) ? "Yes, Its Equals":"No, It is not Equals";
System.out.println(result);
YEARプロパティと組み合わせてDAY_OF_YEARを確認するだけです
boolean isSameDay =
firstCal.get(Calendar.YEAR) == secondCal.get(Calendar.YEAR) &&
firstCal.get(Calendar.DAY_OF_YEAR) == secondCal.get(Calendar.DAY_OF_YEAR)
編集:
これで、Kotlin拡張機能の機能を使用できます
fun Calendar.isSameDay(second: Calendar): Boolean {
return this[Calendar.YEAR] == second[Calendar.YEAR] && this[Calendar.DAY_OF_YEAR] == second[Calendar.DAY_OF_YEAR]
}
fun Calendar.compareDatesOnly(other: Calendar): Int {
return when {
isSameDay(other) -> 0
before(other) -> -1
else -> 1
}
}
public Date saveDateWithoutTime(Date date) {
Calendar calendar = Calendar.getInstance();
calendar.setTime( date );
calendar.set(Calendar.HOUR_OF_DAY, 0);
calendar.set(Calendar.HOUR, 0);
calendar.set(Calendar.MINUTE, 0);
calendar.set(Calendar.SECOND, 0);
calendar.set(Calendar.MILLISECOND, 0);
return calendar.getTime();
}
これにより、時間を考慮せずに日付を比較できます。
SimpleDateFormatのgetDateInstanceを使用すると、時間のない2つの日付オブジェクトのみを比較できます。以下のコードを実行します。
public static void main(String[] args) {
Date date1 = new Date();
Date date2 = new Date();
DateFormat dfg = SimpleDateFormat.getDateInstance(DateFormat.DATE_FIELD);
String dateDtr1 = dfg.format(date1);
String dateDtr2 = dfg.format(date2);
System.out.println(dateDtr1+" : "+dateDtr2);
System.out.println(dateDtr1.equals(dateDtr2));
}
http://mvnrepository.com/artifact/commons-lang/commons-langを使用する
Date date1 = new Date();
Date date2 = new Date();
if (DateUtils.truncatedCompareTo(date1, date2, Calendar.DAY_OF_MONTH) == 0)
// TRUE
else
// FALSE
DateUtils.isSameDay(date1, date2)
。
ここでの回答と私のメンターガイダンスに基づく別の単純な比較方法
public static int compare(Date d1, Date d2) {
Calendar c1 = Calendar.getInstance();
Calendar c2 = Calendar.getInstance();
c1.setTime(d1);
c1.set(Calendar.MILLISECOND, 0);
c1.set(Calendar.SECOND, 0);
c1.set(Calendar.MINUTE, 0);
c1.set(Calendar.HOUR_OF_DAY, 0);
c2.setTime(d2);
c2.set(Calendar.MILLISECOND, 0);
c2.set(Calendar.SECOND, 0);
c2.set(Calendar.MINUTE, 0);
c2.set(Calendar.HOUR_OF_DAY, 0);
return c1.getTime().compareTo(c2.getTime());
}
編集:@Jonathan Drapeauによれば、上記のコードはいくつかのケースで失敗し(私はそれらのケースを見たいです)、私が理解しているように彼は次のことを提案しました:
public static int compare2(Date d1, Date d2) {
Calendar c1 = Calendar.getInstance();
Calendar c2 = Calendar.getInstance();
c1.clear();
c2.clear();
c1.set(Calendar.YEAR, d1.getYear());
c1.set(Calendar.MONTH, d1.getMonth());
c1.set(Calendar.DAY_OF_MONTH, d1.getDay());
c2.set(Calendar.YEAR, d2.getYear());
c2.set(Calendar.MONTH, d2.getMonth());
c2.set(Calendar.DAY_OF_MONTH, d2.getDay());
return c1.getTime().compareTo(c2.getTime());
}
Dateクラスは国際化に対応できなかったため、非推奨になっていることに注意してください。代わりにCalendarクラスが使用されます!
getXxx
メソッドを使用するよりも、タイムゾーンを明示的にする方が確実ですDate
。
まず、この操作はタイムゾーンに依存することに注意してください。そのため、UTC、コンピュータのタイムゾーン、自分の好きなタイムゾーン、どこで行うかを選択します。それが重要であるとまだ確信していない場合は、この回答の下部にある私の例を参照してください。
あなたの質問はこれについて完全に明確ではないので、ある時点を表し、を実装するインスタンスフィールドを持つクラスがComparable
あり、オブジェクトの自然な順序を日付ではなく、日付順にしたいとします、そのフィールドの。例えば:
public class ArnesClass implements Comparable<ArnesClass> {
private static final ZoneId arnesTimeZone = ZoneId.systemDefault();
private Instant when;
@Override
public int compareTo(ArnesClass o) {
// question is what to put here
}
}
java.time
クラスインスタンスフィールドのタイプをJava 8の対応するクラスからDate
に自由に変更しました。以下Instant
の処理に戻ることを約束しDate
ます。タイムゾーン定数も追加しました。あなたはそれをZoneOffset.UTC
またはZoneId.of("Europe/Stockholm")
あなたが適切であると思うものに設定することができます(はサブクラスであるZoneOffset
ため、作品に設定しますZoneOffset
ZoneId
)。
私はJava 8クラスを使用してソリューションを表示することを選択しました。最も簡単な方法を求めましたよね?:-)これがcompareTo
あなたが求めた方法です:
public int compareTo(ArnesClass o) {
LocalDate dateWithoutTime = when.atZone(arnesTimeZone).toLocalDate();
LocalDate otherDateWithoutTime = o.when.atZone(arnesTimeZone).toLocalDate();
return dateWithoutTime.compareTo(otherDateWithoutTime);
}
の時間部分が必要ない場合when
は、もちろんwhen
、LocalDate
すべての変換をスキップです。そうすれば、タイムゾーンについても心配する必要がなくなります。
ここで、なんらかの理由でwhen
フィールドを宣言できないInstant
か、古い形式にしたいとしますDate
。それでもJava 8を使用できる場合は、それをInstant
に変換してから、以前のように実行します。
LocalDate dateWithoutTime = when.toInstant().atZone(arnesTimeZone).toLocalDate();
同様にo.when
。
Java 8を使用できない場合、2つのオプションがあります。
Calendar
またはのいずれかの古いクラスを使用して解決しますSimpleDateFormat
。Adamskiの答えはDate
、Calendar
クラスを使用して時間部分を取り除く方法を示しています。を使用getInstance(TimeZone)
して、Calendar
必要なタイムゾーンのインスタンスを取得することをお勧めします。別の方法として、Jornの回答の後半からのアイデアを使用できます。
にはオブジェクトが含まれているため、使用SimpleDateFormat
は実際には間接的な使用方法です。ただし、直接使用するよりも問題が少ない場合があります。Calendar
SimpleDateFormat
Calendar
Calendar
private static final TimeZone arnesTimeZone = TimeZone.getTimeZone("Europe/Stockholm");
private static final DateFormat formatter = new SimpleDateFormat("yyyyMMdd");
static {
formatter.setTimeZone(arnesTimeZone);
}
private Date when;
@Override
public int compareTo(ArnesClass o) {
return formatter.format(when).compareTo(formatter.format(o.when));
}
これはロブの答えに触発されました。
特定のタイムゾーンを選択する必要があるのはなぜですか?UTCで3月24日の0:00(真夜中)と12:00(正午)の2回を比較するとします。CET(たとえば、Europe / Paris)でこれを行うと、3月24日の午前1時と午後1時、つまり同じ日付になります。ニューヨーク(東部夏時間)では、3月23日は20:00、3月24日は8:00です。つまり、同じ日付ではありません。したがって、選択するタイムゾーンによって違いが生じます。コンピュータのデフォルトに依存している場合、誰かがこのグローバル化された世界の別の場所にあるコンピュータでコードを実行しようとすると、驚かれるかもしれません。
Java 8の日付と時刻クラスのJava 6および7へのバックポートであるThreeTenバックポートへのリンク:http ://www.threeten.org/threetenbp/ 。
私の命題:
Calendar cal = Calendar.getInstance();
cal.set(1999,10,01); // nov 1st, 1999
cal.set(Calendar.AM_PM,Calendar.AM);
cal.set(Calendar.HOUR,0);
cal.set(Calendar.MINUTE,0);
cal.set(Calendar.SECOND,0);
cal.set(Calendar.MILLISECOND,0);
// date column in the Thought table is of type sql date
Thought thought = thoughtDao.getThought(date, language);
Assert.assertEquals(cal.getTime(), thought.getDate());
public static Date getZeroTimeDate(Date fecha) {
Date res = fecha;
Calendar calendar = Calendar.getInstance();
calendar.setTime( fecha );
calendar.set(Calendar.HOUR_OF_DAY, 0);
calendar.set(Calendar.MINUTE, 0);
calendar.set(Calendar.SECOND, 0);
calendar.set(Calendar.MILLISECOND, 0);
res = calendar.getTime();
return res;
}
Date currentDate = getZeroTimeDate(new Date());// get current date
これがこの問題を解決する最も簡単な方法です。
私はタイムスタンプで比較することでこれを解決しました:
Calendar last = Calendar.getInstance();
last.setTimeInMillis(firstTimeInMillis);
Calendar current = Calendar.getInstance();
if (last.get(Calendar.DAY_OF_MONTH) != current.get(Calendar.DAY_OF_MONTH)) {
//not the same day
}
Androidでは巨大なスペースを使用するので、Joda Timeの使用は避けます。サイズが重要です。;)
Java 8とInstantを使用する別のソリューションは、truncateToメソッドを使用することです
このインスタントのコピーを、指定された単位に切り捨てて返します。
例:
@Test
public void dateTruncate() throws InterruptedException {
Instant now = Instant.now();
Thread.sleep(1000*5);
Instant later = Instant.now();
assertThat(now, not(equalTo(later)));
assertThat(now.truncatedTo(ChronoUnit.DAYS), equalTo(later.truncatedTo(ChronoUnit.DAYS)));
}
// Create one day 00:00:00 calendar
int oneDayTimeStamp = 1523017440;
Calendar oneDayCal = Calendar.getInstance();
oneDayCal.setTimeInMillis(oneDayTimeStamp * 1000L);
oneDayCal.set(Calendar.HOUR_OF_DAY, 0);
oneDayCal.set(Calendar.MINUTE, 0);
oneDayCal.set(Calendar.SECOND, 0);
oneDayCal.set(Calendar.MILLISECOND, 0);
// Create current day 00:00:00 calendar
Calendar currentCal = Calendar.getInstance();
currentCal.set(Calendar.HOUR_OF_DAY, 0);
currentCal.set(Calendar.MINUTE, 0);
currentCal.set(Calendar.SECOND, 0);
currentCal.set(Calendar.MILLISECOND, 0);
if (oneDayCal.compareTo(currentCal) == 0) {
// Same day (excluding time)
}
これは私のために働いたものです:
var Date1 = new Date(dateObject1.toDateString()); //this sets time to 00:00:00
var Date2 = new Date(dateObject2.toDateString());
//do a normal compare
if(Date1 > Date2){ //do something }