Zaman bölümü olmadan iki tarih nasıl karşılaştırılır?


204

Bir java.util.Date zaman bölümünü yok sayan bir CompareTo yöntemi istiyorum. Sanırım bunu çözmenin birkaç yolu var. En basit yol nedir?

Yanıtlar:


213

Güncelleme: Joda Time o zaman iyi bir öneriyken, java.timemümkünse Java 8+'den gelen kütüphaneyi kullanın .


Benim tercihim Joda Time'ı kullanmak , bunu inanılmaz derecede kolaylaştırıyor:

DateTime first = ...;
DateTime second = ...;

LocalDate firstDate = first.toLocalDate();
LocalDate secondDate = second.toLocalDate();

return firstDate.compareTo(secondDate);

DÜZENLEME: Yorumlarda belirtildiği gibi, DateTimeComparator.getDateOnlyInstance()daha basit kullanıyorsanız :)

// TODO: consider extracting the comparator to a field.
return DateTimeComparator.getDateOnlyInstance().compare(first, second);

( "Kullanım Joda Time" hakkında sormak neredeyse tüm SO sorular temelidir java.util.Dateya java.util.Calendar. Bu bir iyice üstün API var. Eğer yapıyorsanız şey tarihlere / saatlere ile anlamlı Eğer muhtemelen, gerçekten kullanmalıdır.)

Kesinlikle ediyorsanız zorla API yerleşik kullanmak için, bir örneğini oluşturmalısınız Calendaruygun tarih ve uygun saat dilimini kullanarak. Daha sonra her takvimdeki her alanı saat, dakika, saniye ve milisaniye dışında 0 olarak ayarlayabilir ve elde edilen süreleri karşılaştırabilirsiniz. Joda çözümü ile karşılaştırıldığında kesinlikle icky :)

Saat dilimi bölümü önemlidir: java.util.Dateher zaman UTC'ye dayanır. Bir tarihle ilgilendiğim çoğu durumda, bu belirli bir saat dilimindeki bir tarihtir . Bu tek başına sizi Calendarveya Joda Time'ı kullanmaya zorlayacaktır (tavsiye etmediğim saat dilimini kendiniz hesaplamak istemiyorsanız).

Android geliştiricileri için hızlı başvuru

//Add joda library dependency to your build.gradle file
dependencies {
     ...
     implementation 'joda-time:joda-time:2.9.9'
}

Örnek kod (örnek)

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

28
Jon'un dediği gibi "Joda Zamanını Kullan" java.util.Date veya java.util.Calendar hakkında soran hemen hemen tüm SO sorularının temelini oluşturuyor. en azından java yolunu yapmanın ne kadar zor olabileceğini göstermek. Ve bundan sonra Joda kullanmanızı
önerir

13
@JuanZe: Bu, ağrılı bir API'da, tanım gereği acı verici olan bir şeyin tam olarak nasıl yapılacağını tam olarak hesaplamayı gerektirir. O zamanı daha üretken bir şey yaparak geçirmeyi tercih ederim :)
Jon Skeet

1
@ MetroidFan2002: LocalDate, daha etkileyici olduğu ve tüm günlerin gece yarısı olmadığı için DateMidnight'dan daha iyi bir seçenektir ...
Jon Skeet

2
@dertoni: Tabii - Brezilya'da, saatler gün ışığından yararlanma saati nedeniyle ilerlediğinde, günün başında olur ... yani bir saat 23:59:58, 23:59:59, 01:00 : 00, 01:00:01 vb.
Jon Skeet


126

Apache müşterekleri neredeyse her yerde bulunur. Peki buna ne dersiniz?

if (DateUtils.isSameDay(date1, date2)) {
    // it's same
} else if (date1.before(date2)) {
   // it's before
} else {
   // it's after
}


2
Ne yazık ki boş tarihleri ​​tolere etmiyor
Pavel Niedoba

Çocuklar, bugünlerde Java 8 var stackoverflow.com/a/35411693/259237
André

Bu yoldan önce kullanılmasını önermiyorum çünkü birinci veya ikinci Date nesnesi Timestamp'tan alınmamışsa ve milisaniyeye sahipse ve diğeri normal bir Date nesnesiyse, sorun yaşayacağınız için, çünkü Datetamp deposundan tarih farklı bir bölümde her iki tarih eşit olsa bile milisaniye farklılıklar verir.
Zini

Ne yazık ki, Apache 1.3 milyardan fazla Android cihazda değil ve sadece bir kullanım senaryosuna bağımlı büyük bir kütüphane. Başka bir şeye ihtiyacım olacak: /
milosmns

58

Gerçekten java.util.Date kullanmak istiyorsanız, böyle bir şey yapardınız:

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();
  }
}

veya bunun yerine bir Takvim kullanma (tercih edilir, getYear () vb. kullanımdan kaldırıldığından)

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);
  }
}

1
İkinci yöntemde bazı referanslarınızı d1, d2'den c1, c2'ye güncellemeyi unuttunuz.
stivlo

1
Bu detayı düzelttikten sonra kodunuz iyi çalışıyor: Ben kapsamlı bir şekilde test ettim. Tarihlerden bir Takvim oluşturma adımını ekledim ve yeni oluşturulan github projemde org.obliquid.helpers kodunuzu kullandım , teşekkürler.
stivlo

Herhangi bir harici kütüphane kullanmadan tatlı, güzel bir çözüm.
4gus71n

1
Bu yöntemlerin tümü kullanımdan kaldırılmıştır. Bunun herhangi bir etkisi olabilir mi?
Pranav Mahajan

36

Benim tercihim, Joda'nın tarih ve saat arasında bir ayrım yapması nedeniyle doğrudan Joda kütüphanesini kullanmak olacaktır java.util.Date(bkz. YearMonthDay ve DateTime sınıfları).

Ancak, kullanmak isterseniz java.util.Datebir yardımcı yöntem yazmanızı öneririm; Örneğin

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();
}

1
Joda-Time YearMonthDay, LocalDate lehine kullanımdan kaldırıldı. Ayrıca, saat diliminde gün ışığından yararlanma saati nedeniyle gece yarısı 00: 00'da takvimde yer alan kodda sorunlar olacaktır.
JodaStephen

1
Bu zamanın% 100'ünde işe yaramıyor. Bunu yaptığım bir kullanım durumu vardı ve calendar.getTime () yine de parametre tarihi olarak ayarlanmış saatlerle zamanı döndürür. Alanları temizlemek ve sadece yıl, ay ve günü ayarlamak için en iyisidir.
Jonathan Drapeau

31

Bu alternatif hakkında herhangi bir görüşünüz var mı?

SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
sdf.format(date1).equals(sdf.format(date2));

1
Dizelere dönüştürmek iyi bir fikir olsa bile bunun işe yarayacağını sanmıyorum. ==Operatör zorunlu döndürmez trueeşdeğer Yaylı (kullanımı için equals()). Bahsettiğiniz diğer karşılaştırma operatörlerini de kesinlikle kullanamazsınız.
harto

1
Ahh evet - yakutum Java'mı mahvediyor! <,> Vb olsa ints için dizeleri dönüştürmek Could
Robert Brown

Joda'yı kullanmak sağlam bir yol, ama bu zarif!
Arne Evertsson

Bu herkes için işe yaramaz, ancak çok basit ve hafiftir; diğer kütüphaneler olmadığında iyi bir alternatif.
Jacob Marble

Tarihlerin sırasını almak için de kullanabilirsiniz sdf.format(date1).compareTo(sdf.format(date2));.
Ole VV

18

İki tarihin yalnızca ayını, gününü ve yılını karşılaştırmak istiyorsanız, aşağıdaki kod benim için çalışır:

SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
sdf.format(date1).equals(sdf.format(date2));

Teşekkürler Rob.


13

Ben de Joda Time'ı tercih ediyorum , ama işte bir alternatif:

long oneDay = 24 * 60 * 60 * 1000
long d1 = first.getTime() / oneDay
long d2 = second.getTime() / oneDay
d1 == d2

DÜZENLE

UTC dışında belirli bir saat dilimi için tarihleri ​​karşılaştırmanız gerektiğinde UTC'yi aşağıya koydum. Eğer böyle bir ihtiyacınız varsa, o zaman gerçekten Joda'ya gitmenizi tavsiye ederim.

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

Joda Time'ı kullanmayı tercih ederim dedim, ama bu iyi bir nokta. Bu kadar düşük taktiklere sadece TZ ile gerçekten ilgilenmediğimde başvuruyorum.
Daniel C.Sobral

Math.abs(second.getTime() - first.getTime()) < 1000L*60*60*24
Bölümden

@Vadzim Yap < oneDay.
Daniel C. Sobral

2
@Vadzim, bu sadece tarihlerin 1 günden daha kısa olup olmadığını kontrol eder. Aynı gün oldukları anlamına gelmez.
arahant

@arahant, evet. ikinci tarih her zaman gece yarısı hizalandığında bu yeterli olabilir.
Vadzim

12

tl; Dr.

myJavaUtilDate1.toInstant()
               .atZone( ZoneId.of( "America/Montreal" ) )
               .toLocalDate()
               .isEqual (
                   myJavaUtilDate2.toInstant()
                                  .atZone( ZoneId.of( "America/Montreal" ) )
                                  .toLocalDate()
               )

Eski tarih ve saat sınıflarından kaçının

Java.time sınıflarının yerini aldığı Date& gibi sıkıntılı eski eski tarih-saat sınıflarından kaçının Calendar.

Java.time kullanma

A java.util.Date, UTC'deki zaman çizelgesindeki bir anı temsil eder. Java.time içindeki eşdeğerdir Instant. Eski sınıfa eklenen yeni yöntemleri kullanarak dönüştürebilirsiniz.

Instant instant1 = myJavaUtilDate1.toInstant();
Instant instant2 = myJavaUtilDate2.toInstant();

Tarihe göre karşılaştırmak istiyorsunuz. Bir tarihin belirlenmesinde saat dilimi çok önemlidir. Belirli bir an için, tarih tüm dünyada bölgeye göre değişir. Örneğin, Paris'te gece yarısından birkaç dakika sonra Fransa , Montréal Québec'te hala “dün” yeni bir gündür .

Bir belirtme uygun bir zaman dilimi adı biçiminde continent/region, örneğin America/Montreal, Africa/Casablancaya daPacific/Auckland . Hiçbir zaman gibi 3-4 harfli bir kısaltma kullanın ESTveya ISToldukları gibi değil , gerçek zaman dilimleri, değil standardize ve hatta benzersiz değil (!).

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

Uygula ZoneIdiçin Instantbir olsun ZonedDateTime.

ZonedDateTime zdt1 = instant1.atZone( z );
ZonedDateTime zdt2 = instant2.atZone( z );

LocalDateSınıf zaman günün-ve saat dilimi bulunmayan olmadan tarih salt değerini temsil eder. Günün saat bölümünü etkin LocalDatebir ZonedDateTimeşekilde ortadan kaldırarak bir ' den ayıklayabiliriz .

LocalDate localDate1 = zdt1.toLocalDate();
LocalDate localDate2 = zdt2.toLocalDate();

Şimdi karşılaştırın, gibi yöntemleri kullanarak isEqual , isBeforeve isAfter.

Boolean sameDate = localDate1.isEqual( localDate2 );

IdeOne.com'da canlı olarak çalışan bu koda bakın .

instant1: 2017-03-25T04: 13: 10.971Z | instant2: 2017-03-24T22: 13: 10.972Z

zdt1: 2017-03-25T00: 13: 10.971-04: 00 [Amerika / Montreal] | zdt2: 2017-03-24T18: 13: 10.972-04: 00 [Amerika / Montreal]

localDate1: 2017-03-25 | localDate2: 2017-03-24

sameDate: yanlış


Java.time hakkında

Java.time çerçevesi daha sonra Java 8 ve yerleşiktir. Bu sınıflar zahmetli eski yerini mirası gibi tarih-saat sınıfları java.util.Date, Calendar&SimpleDateFormat .

Artık bakım modunda olan Joda-Time projesi java.time'a geçişi tavsiye ediyor sınıflarına .

Daha fazla bilgi için Oracle Eğiticisine bakın . Ve birçok örnek ve açıklama için Stack Overflow'da arama yapın. Spesifikasyon JSR 310'dur .

Java.time sınıflarını nereden edinebilirsiniz?

ThreeTen-Ekstra proje ek sınıfları ile java.time uzanır. Bu proje, java.time'a gelecekteki olası eklemeler için bir kanıt zeminidir. Burada bazı yararlı sınıfları gibi bulabilir Interval, YearWeek, YearQuarter, ve daha .


7

Daha önce bahsedilen apache commons-utils :

org.apache.commons.lang.time.DateUtils.truncate(date, Calendar.DAY_OF_MONTH)

size yalnızca tarih içeren, zaman içermeyen bir Date nesnesi verir ve bunları Date.compareTo


6

Korkarım "kolay" veya "basit" olarak adlandırılabilecek iki tarihi karşılaştırmanın bir yöntemi yoktur.

İki zaman örneğini herhangi bir düşük hassasiyetle karşılaştırırken (örn. Yalnızca tarihleri ​​karşılaştırırken), zaman diliminin karşılaştırmayı nasıl etkilediğini her zaman dikkate almalısınız.

Örneğin date1, +2 saat diliminde gerçekleşen bir olay belirtiyorsa ve date2örneğin EST'de gerçekleşen bir olay belirtiyorsa, karşılaştırmanın sonuçlarını doğru bir şekilde anlamaya dikkat etmelisiniz.

Amacınız, iki olayın kendi takvim saatlerinde aynı takvim tarihinde gerçekleşip gerçekleşmediğini anlamak mı? Veya iki tarihin belirli bir saat diliminde (örneğin UTC veya yerel TZ'niz) aynı takvim tarihine girip girmediğini bilmeniz gerekir.

Karşılaştırmaya çalıştığınızın aslında ne olduğunu anladıktan sonra, sadece uygun bir zaman diliminde yıl-ay-tarihini üçe katlayıp karşılaştırmayı yapmak meselesidir.

Joda zamanı, gerçek karşılaştırma işleminin daha temiz görünmesini sağlayabilir, ancak karşılaştırmanın anlambilimi hala kendiniz anlamanız gereken bir şeydir.



5

Zaman olmadan yalnızca iki tarihi karşılaştırmak istiyorsanız, aşağıdaki kod size yardımcı olabilir:

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
}

Bu Rob'ın cevabı ile aynı . Bence Jorn'un çözümü daha iyidir çünkü dizelere gidiş dönüş içermez ve aynı şeyi yapmalıdır.
Rup

4

İşte bu blogdan bir çözüm: 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.");

yani milisaniye cinsinden zaman farkının bir günün uzunluğundan az olup olmadığını görebilirsiniz.


4
Bu örnek, iki tarihin birbirinden 24 saat içinde olup olmadığını kontrol eder, ancak her ikisinin de aynı tarihte olup olmadığını kontrol etmez, yani bir gece yarısını geçirmek mümkündür. Bunun yerine, her iki milis kümesini MILLIS_IN_DAY'e bölmek ve sonucu karşılaştırmak daha iyidir, ancak bu yerel saatler için değil, yalnızca UTC için kesin olacaktır.
Rup

4

'

SimpleDateFormat sdf= new SimpleDateFormat("MM/dd/yyyy")

   Date date1=sdf.parse("03/25/2015");



  Date currentDate= sdf.parse(sdf.format(new Date()));

   return date1.compareTo(currentDate);

'


3

Yeni düşünmek ya da başka bir şey bilmiyorum, ama sana yaptığım gibi gösteriyorum

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);

3

YEAR özelliği ile birlikte DAY_OF_YEAR sayfasını kontrol etmeniz yeterlidir

boolean isSameDay = 
firstCal.get(Calendar.YEAR) == secondCal.get(Calendar.YEAR) &&
firstCal.get(Calendar.DAY_OF_YEAR) == secondCal.get(Calendar.DAY_OF_YEAR)

DÜZENLE:

Şimdi Kotlin uzatma fonksiyonlarının gücünü kullanabiliriz

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
    }
}

Yanlış çünkü farklı yıllara sahip tarihler yılın aynı günü olabilir, örneğin 2015-01-01 ve 2016-01-01.
Nelson Eldoro

@nelsoneldoro Yorumunuz için teşekkürler, yıl için bir çek eklemeyi unuttum, şimdi tamam olmalı.
Simon K. Gerges

2

Java 8'de Joda Time'ınkine çok benzeyen LocalDate'i kullanabilirsiniz.


2
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();
}

Bu, tarihleri ​​dikkate almadan tarihleri ​​karşılaştırmanıza yardımcı olacaktır.


1

SimpleDateFormat'ın getDateInstance özelliğini kullanarak yalnızca iki tarih nesnesini zaman olmadan karşılaştırabiliriz. Aşağıdaki kodu yürütün.

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));  

    }


1

Buradaki yanıtlara ve rehber rehberime dayalı başka bir Basit karşılaştırma yöntemi

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());
  }

DÜZENLEME : @Jonathan Drapeau göre, yukarıdaki kod bazı durumlarda başarısız (bu davaları görmek istiyorum, lütfen) ve o anladığım gibi şunları önerdi:

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 sınıfının, uluslararasılaştırmaya uygun olmadığından kullanımdan kaldırıldığını lütfen unutmayın. Bunun yerine Calendar sınıfı kullanılır!


Bu zamanın% 100'ünde işe yaramıyor. Bunu yaptığım bir kullanım durumu vardı ve calendar.getTime () yine de parametre tarihi olarak ayarlanmış saatlerle zamanı döndürür. Alanları temizlemek ve sadece yıl, ay ve günü ayarlamak için en iyisidir.
Jonathan Drapeau

@JonathanDrapeau, açık bir zaman dilimi seçmemenin bir sonucuyla karşılaşmış gibi görünebilir. Kesinlikle daha iyi zaman dilimini açıkça kullanım dışı getXxxyöntemleri kullanmak daha yapmak Date.
Ole VV

1

İlk olarak, bu işlemin saat dilimine bağlı olduğunu unutmayın. Bu nedenle, UTC'de mi, bilgisayarın saat diliminde mi, en sevdiğiniz saat diliminde mi veya nerede yapmak istediğinizi seçin. Henüz önemli olduğuna ikna olmadıysanız, bu cevabın altındaki örneğime bakın.

Sorunuz bu konuda oldukça açık olmadığından, zaman noktasını temsil eden ve uygulayan bir örnek alanına sahip bir sınıfınız olduğunu Comparableve nesnelerinizin doğal sıralamasının tarihe göre olmasını istediğinizi varsayıyorum. , bu alanın. Örneğin:

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 8 java.timesınıfları

Ben sizin örnek alanın türünü değiştirme özgürlüğünü almış Dateetmek Instant, Java 8. karşılık gelen sınıf I tedavisinde dönüşü söz Dateaşağıda. Ayrıca bir saat dilimi sabiti ekledim. Sen bunu ayarlayabilirsiniz ZoneOffset.UTCveya ZoneId.of("Europe/Stockholm")veya ne (a ayarlayarak uygun bulmak ZoneOffsetçünkü işlerin ZoneOffsetbir alt sınıf taşımaktadır ZoneId).

Java 8 sınıflarını kullanarak çözümü göstermeyi seçtim. En basit yolu istedin değil mi? :-) İşte istediğiniz compareToyöntem:

public int compareTo(ArnesClass o) {
    LocalDate dateWithoutTime = when.atZone(arnesTimeZone).toLocalDate();
    LocalDate otherDateWithoutTime = o.when.atZone(arnesTimeZone).toLocalDate();
    return dateWithoutTime.compareTo(otherDateWithoutTime);
}

Eğer zaman dilimine hiç ihtiyacınız yoksa when, elbette whena bildirmek LocalDateve tüm dönüşümleri atlamak daha kolaydır . O zaman artık saat dilimi hakkında endişelenmemize gerek yok.

Şimdi nedense size beyan edemez herhalde whenbir alan Instantveya bir eski moda tutmak istiyoruz Date. Hala Java 8'i kullanabiliyorsanız, sadece dönüştürün ve Instantdaha önce olduğu gibi yapın:

    LocalDate dateWithoutTime = when.toInstant().atZone(arnesTimeZone).toLocalDate();

Benzer şekilde o.when.

Java 8 yok mu?

Java 8'i kullanamıyorsanız, iki seçenek vardır:

  1. Ya eski sınıflardan birini kullanarak çözün ya Calendarda SimpleDateFormat.
  2. Java 8 tarih ve saat sınıflarının backport'unu Java 6 ve 7'ye kullanın, sonra yukarıdaki gibi yapın. Altta bir bağlantı ekliyorum. JodaTime kullanmayın. JodaTime muhtemelen tavsiye eden cevaplar yazıldığında iyi bir öneriydi; ancak JodaTime artık bakım modunda, bu nedenle ThreeTen backport daha iyi ve daha dayanıklı bir seçenektir.

Eski moda yollar

Adamski'nin cevabıDate , Calendardersi kullanarak zaman bölümünü nasıl keseceğinizi gösteriyor . İstediğiniz saat dilimi getInstance(TimeZone)için Calendarörneği almak için kullanmanızı öneririz . Alternatif olarak bu fikri Jorn'un cevabının ikinci yarısından kullanabilirsiniz .

Kullanımı SimpleDateFormatgerçekten kullanarak dolaylı bir yoldur Calendarbir yana SimpleDateFormatbir içeriyor Calendarnesne. Bununla birlikte, Calendardoğrudan kullanmaktan daha az zahmetli bulabilirsiniz :

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));
}

Bu Rob'ın cevabından ilham aldı .

Zaman dilimi bağımlılığı

Neden belirli bir saat dilimi seçmeliyiz? UTC'de 24 Mart 0:00 (gece yarısı) ve 12:00 (öğlen) olmak üzere iki kez karşılaştırmak istediğimizi varsayalım. Bunu CET'te (örneğin, Avrupa / Paris) yaparsanız, 24 Mart'ta saat 01:00 ve 13:00, yani aynı tarih. New York'ta (Doğu Yaz Saati), 23 Mart'ta 20:00 ve 24 Mart'ta 8:00, yani aynı tarih değil. Bu nedenle hangi saat dilimini seçtiğinizi fark eder. Sadece bilgisayarın varsayılanına güveniyorsanız, birisi kodunuzu bu küreselleşmiş dünyada başka bir yerde bir bilgisayarda çalıştırmaya çalıştığında sürprizlerle karşılaşabilirsiniz.

bağlantı

Java 8 tarih ve saat sınıflarının Java 6 ve 7'ye arka havuzu olan ThreeTen Backport'a bağlantı: http://www.threeten.org/threetenbp/ .


0

Benim önerim:

    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());

0

Apache ortaklarını kullanarak şunları yapabilirsiniz:

import org.apache.commons.lang3.time.DateUtils

DateUtils.truncatedEquals(first, second, Calendar.DAY_OF_MONTH)

0
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   

bu sorunu çözmenin en basit yolu budur.


0

Ben zaman damgası ile karşılaştırarak çözdü:

    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
    }

Joda Time kullanmaktan kaçınıyorum çünkü Android'de büyük bir alan kullanıyor. Boyut önemlidir. ;)


0

Java 8 ve Instant kullanan başka bir çözüm, truncatedTo yöntemini kullanmaktır

Bu Anında kesilen bir kopyasını belirtilen birime döndürür.

Misal:

@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)));
}

0
// 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)
}

Teşekkürler! Yine de aynı yaklaşıma sahip bir avuç başka cevap var - her ne kadar şimdi Takvim nesnelerini doğrudan karşılaştırırken, büyük ölçüde getTime () leri karşılaştırdığınızı görüyorum.
Rup

-2

Benim için işe yarayan buydu:

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 }

2
"Normal" karşılaştırmanız Java'da bile derlenmez. Olursa, nesne referanslarını karşılaştırır, ancak buna izin verilmez.
stivlo

Markdown'u ekledim ama stivlo haklı. Bu kodun sizin için nasıl çalıştığı hakkında hiçbir fikrim yok.
Pops

Bu muhtemelen js.
Andrey Luiz

-2

Nasıl hakkında DateUtil.daysBetween(). Java ve bir sayı döndürüyor (gün farkı).

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.