Java'da iki tarih arasındaki gün farkı?


81

İki tarih arasındaki günlerin sayısını bulmam gerekiyor : biri bir rapordan, diğeri de geçerli tarih. Snippet'im:

  int age=calculateDifference(agingDate, today);

İşte calculateDifferenceözel bir yöntemdir, agingDateve todayvardır Datesadece açıklama için, nesneler. Bir Java forumundan iki makale takip ettim, Konu 1 / Konu 2 .

Bağımsız bir programda iyi çalışıyor, ancak bunu rapordan okumak için mantığıma dahil ettiğimde değerlerde olağandışı bir fark görüyorum.

Neden oluyor ve bunu nasıl düzeltebilirim?

DÜZENLE :

Gerçek Gün sayısına kıyasla daha fazla sayıda gün alıyorum.

public static int calculateDifference(Date a, Date b)
{
    int tempDifference = 0;
    int difference = 0;
    Calendar earlier = Calendar.getInstance();
    Calendar later = Calendar.getInstance();

    if (a.compareTo(b) < 0)
    {
        earlier.setTime(a);
        later.setTime(b);
    }
    else
    {
        earlier.setTime(b);
        later.setTime(a);
    }

    while (earlier.get(Calendar.YEAR) != later.get(Calendar.YEAR))
    {
        tempDifference = 365 * (later.get(Calendar.YEAR) - earlier.get(Calendar.YEAR));
        difference += tempDifference;

        earlier.add(Calendar.DAY_OF_YEAR, tempDifference);
    }

    if (earlier.get(Calendar.DAY_OF_YEAR) != later.get(Calendar.DAY_OF_YEAR))
    {
        tempDifference = later.get(Calendar.DAY_OF_YEAR) - earlier.get(Calendar.DAY_OF_YEAR);
        difference += tempDifference;

        earlier.add(Calendar.DAY_OF_YEAR, tempDifference);
    }

    return difference;
}

Not :

Ne yazık ki, yanıtların hiçbiri sorunu çözmeme yardımcı olmadı. Bu sorunu Joda-time kütüphanesinin yardımıyla başardım .


3
Olağandışı fark değerleri ile neyi kastediyorsunuz? Lütfen daha açık konuşabilir misiniz veya bir tür örnek verebilir misiniz?
Marcel Gheorghita

1
CalculateDifference yöntemi kodunu gönderebilir misiniz?
Eugene Ryzhikov

Bilginize, gibi zahmetli eski tarih-saat sınıfları java.util.Date, java.util.Calendarve java.text.SimpleDateFormatşimdi mirası supplanted, java.time sınıfları. Oracle'ın Eğitimi bölümüne bakın . Aynı şekilde, Joda-Time projesi şu anda bakım modunda ve ekip java.time sınıflarına geçişi tavsiye ediyor.
Basil Bourque

Yanıtlar:


149

Kusurlu java.util.Date ve arkadaşlar yerine mükemmel Joda Time kitaplığını kullanmanızı öneririm . Basitçe yazabilirsin

import java.util.Date;
import org.joda.time.DateTime;
import org.joda.time.Days;

Date past = new Date(110, 5, 20); // June 20th, 2010
Date today = new Date(110, 6, 24); // July 24th 
int days = Days.daysBetween(new DateTime(past), new DateTime(today)).getDays(); // => 34

3
joda-time.sourceforge.net/faq.html#datediff - Ben de aynı şeyi önerecektim.
Nebril

2
jodaInstance = yeni DateTime (jdkDate); Joda zaman ve java.util.Date ve arkadaşlar arasındaki dönüşüm günü, bkz joda-time.sourceforge.net/userguide.html#JDK_Interoperability
Adam Schmideg

2
@ven coder - Sanırım bunu joda time kullanımı hakkında ayrı bir soru olarak gönderebilirsiniz. Ayrıca görünüşte yanlış olan sonucu veren bir kod parçası da sağlayabilirsiniz.
Adam Schmideg

2
@ven coder - Örnek kodu güncelledim, benim için çalışıyor. Bu sorunun cevaplandığını görüyorum. İşinize yaramayan kodu burada veya ayrı bir soruda gösterin.
Adam Schmideg

1
Bilginize, Joda-Time projesi şu anda bakım modunda ve ekip java.time sınıflarına geçişi tavsiye ediyor . Oracle'ın Eğitimine bakın .
Basil Bourque

48

Oyuna katılmak için çok geç kalmış olabilirim ama ne halt ha? :)

Bunun bir iş parçacığı sorunu olduğunu düşünüyor musunuz? Örneğin bu yöntemin çıktısını nasıl kullanıyorsunuz? VEYA

Şu kadar basit bir şey yapmak için kodunuzu değiştirebilir miyiz:

Calendar calendar1 = Calendar.getInstance();
    Calendar calendar2 = Calendar.getInstance();
    calendar1.set(<your earlier date>);
    calendar2.set(<your current date>);
    long milliseconds1 = calendar1.getTimeInMillis();
    long milliseconds2 = calendar2.getTimeInMillis();
    long diff = milliseconds2 - milliseconds1;
    long diffSeconds = diff / 1000;
    long diffMinutes = diff / (60 * 1000);
    long diffHours = diff / (60 * 60 * 1000);
    long diffDays = diff / (24 * 60 * 60 * 1000);
    System.out.println("\nThe Date Different Example");
    System.out.println("Time in milliseconds: " + diff
 + " milliseconds.");
    System.out.println("Time in seconds: " + diffSeconds
 + " seconds.");
    System.out.println("Time in minutes: " + diffMinutes 
+ " minutes.");
    System.out.println("Time in hours: " + diffHours 
+ " hours.");
    System.out.println("Time in days: " + diffDays 
+ " days.");
  }

18
Bu kod, gün ışığından yararlanma saatine dikkat etmez, bu nedenle gün cinsinden farkın sonucu doğru olmayabilir.
Johanna

@Johanna Çok geç olmasına rağmen, bu başarısız olduğunda bir örnek verebilir misiniz lütfen? Çok denedim ama başarısız olduğu herhangi bir tarih aralığı bulamadım. Teşekkür ederim.
abhilash

4
Bu hata yalnızca, Orta Avrupa Saati, Berlin, Paris veya Amsterdam gibi yaz saati uygulamasını kullanan bir saat dilimindeyseniz (yerel saat dilimi ayarınız) oluşur. Yaz saati uygulamasının başlangıç ​​ve bitiş günü 24 saat içermez, örneğin 30 Mart 2014'te yalnızca 23 saat varken 26 Ekim 2014'te 25 saat olacaktır. Daha önceki tarih 30 Mart 2: 00'dan önceyse ve sonraki tarih 30 Mart 3: 00'dan sonraysa hesaplama başarısız olur.
Johanna

23

Fark / (24 * vb.) Saat Dilimini hesaba katmaz, bu nedenle varsayılan saat diliminizde DST varsa, hesaplamayı iptal edebilir.

Bu bağlantının güzel bir küçük uygulaması var.

Bağlantının kopması durumunda yukarıdaki bağlantının kaynağı:

/** Using Calendar - THE CORRECT WAY**/  
public static long daysBetween(Calendar startDate, Calendar endDate) {  
  //assert: startDate must be before endDate  
  Calendar date = (Calendar) startDate.clone();  
  long daysBetween = 0;  
  while (date.before(endDate)) {  
    date.add(Calendar.DAY_OF_MONTH, 1);  
    daysBetween++;  
  }  
  return daysBetween;  
}  

ve

/** Using Calendar - THE CORRECT (& Faster) WAY**/  
public static long daysBetween(final Calendar startDate, final Calendar endDate)
{
  //assert: startDate must be before endDate  
  int MILLIS_IN_DAY = 1000 * 60 * 60 * 24;  
  long endInstant = endDate.getTimeInMillis();  
  int presumedDays = 
    (int) ((endInstant - startDate.getTimeInMillis()) / MILLIS_IN_DAY);  
  Calendar cursor = (Calendar) startDate.clone();  
  cursor.add(Calendar.DAY_OF_YEAR, presumedDays);  
  long instant = cursor.getTimeInMillis();  
  if (instant == endInstant)  
    return presumedDays;

  final int step = instant < endInstant ? 1 : -1;  
  do {  
    cursor.add(Calendar.DAY_OF_MONTH, step);  
    presumedDays += step;  
  } while (cursor.getTimeInMillis() != endInstant);  
  return presumedDays;  
}

4
İkinci yöntem yanlış, final whileolmalı. while (cursor.getTimeInMillis() <= endInstant); Aksi takdirde, bir günden azsa sonsuz bir döngü elde edersiniz.
Chris.Jenkins

Bağlantıdaki yorumdan "Verilen algoritmanın beklediğinizden 'bir gün daha' verebileceğini bilmelisiniz. 2009-02-28 19:00:00 ve 2009-02-28 arası gün sayısı olarak 1 veriyor. 19:00:01. "
Zyoo

16

java.time

Java 8 ve sonraki sürümlerde, java.time çerçevesini ( Öğretici ) kullanın.

Duration

DurationSınıf saniye sayısı artı bir kesirli ikinci olarak bir zaman aralığını temsil etmektedir. Günleri, saatleri, dakikaları ve saniyeleri sayabilir.

ZonedDateTime now = ZonedDateTime.now();
ZonedDateTime oldDate = now.minusDays(1).minusMinutes(10);
Duration duration = Duration.between(oldDate, now);
System.out.println(duration.toDays());

ChronoUnit

İhtiyacınız olan tek şey gün sayısı ise, alternatif olarak numaralandırmayı da kullanabilirsiniz . Hesaplama yöntemlerinin yerine a döndürdüğüne dikkat edin .ChronoUnit longint

long days = ChronoUnit.DAYS.between( then, now );

ayrıca tarihleri ​​ChronoUnit.DAYS. arasında doğru sırayla geçirdiğinizden emin olun, aksi takdirde sonuç -ve sonuç döndürür
RRR_J

13
import java.util.Calendar;
import java.util.Date;

public class Main {
    public static long calculateDays(String startDate, String endDate)
    {
        Date sDate = new Date(startDate);
        Date eDate = new Date(endDate);
        Calendar cal3 = Calendar.getInstance();
        cal3.setTime(sDate);
        Calendar cal4 = Calendar.getInstance();
        cal4.setTime(eDate);
        return daysBetween(cal3, cal4);
    }

    public static void main(String[] args) {
        System.out.println(calculateDays("2012/03/31", "2012/06/17"));

    }

    /** Using Calendar - THE CORRECT WAY**/
    public static long daysBetween(Calendar startDate, Calendar endDate) {
        Calendar date = (Calendar) startDate.clone();
        long daysBetween = 0;
        while (date.before(endDate)) {
            date.add(Calendar.DAY_OF_MONTH, 1);
            daysBetween++;
        }
        return daysBetween;
    }
}

1
Döngü mükemmel bir fikir değil. Aynı şeyi yapmak için daha basit seçenekler varken performans nasıl olur?
angelcervera

1
Bir performans iyileştirmesi, 2'nin katları ile artış ve ardından tarih.büyük (endDate) koşulu yanlış olduğunda, önceki yinelemeye geri dönün ve artırıcıyı 1'e sıfırlamak olacaktır. Yani, bir milyar gün uzaktaysanız, bir milyar yerine belki 30 tane yineleme yapabilir. Milisaniyeleri kontrol ederek bir tahminde bulunarak da performansı artırabilirsiniz, ancak bu muhtemelen daha az zarif olacaktır.
Muhd

12

Fark olarak neyi tanımladığınıza bağlıdır. Gece yarısı iki tarihi karşılaştırmak için yapabilirsiniz.

long day1 = ...; // in milliseconds.
long day2 = ...; // in milliseconds.
long days = (day2 - day1) / 86400000;

9
Bu kod, gün ışığından yararlanma saatine dikkat etmez, bu nedenle sonuç doğru olmayabilir.
Johanna

@Johanna Bu çözüm DST ile çalışır. Bölmeden sonra raund uygulandığında bu fark göz ardı edilir ve sonuç normaldir.
angelcervera

1
@angelcervera Çoğu zaman doğru olacaktır, ancak eğer yakınsa, fazladan saat doğruluğu +/- 1 gün iptal edebilir (yani yanlış yöne yuvarlanır).
Muhd

3
@Muhd Evet, haklısın. Üçüncü satır şu olmalıdır: uzun günler = Matematik.round ((gün2 - gün1) / 86400000D); Bölenin çift değerli olması çok önemlidir.
angelcervera

3
Afedersiniz. Bu sabah birinci sınıf matematik modülümü beynime takmayı unuttum. Negatif çıkarmanın hesaplamayı bozacağını düşünüyordum. Yorumlara olumsuz oy verebilmeliyiz.
Snekse

9

DST tarihleri ​​için doğru yuvarlama ile milisaniye saatleri arasındaki farkı kullanan çözüm:

public static long daysDiff(Date from, Date to) {
    return daysDiff(from.getTime(), to.getTime());
}

public static long daysDiff(long from, long to) {
    return Math.round( (to - from) / 86400000D ); // 1000 * 60 * 60 * 24
}

Bir not: Elbette tarihler belirli bir zaman diliminde olmalıdır.

Önemli kod:

Math.round( (to - from) / 86400000D )

Tur istemiyorsanız, UTC tarihlerini kullanabilirsiniz.


1
@marcolopes No, 32 döndürür. System.out.println (daysDiff (new Date (2014, 2, 1), new Date (2014, 3, 2))); Dikkatli olun, çünkü Ocak 0.
angelcervera

4

Sorunun gösterimi: (Kodum haftalar içinde delta hesaplıyor, ancak aynı sorun gün cinsinden delta için de geçerli)

İşte oldukça makul görünen bir uygulama:

public static final long MILLIS_PER_WEEK = 7L * 24L * 60L * 60L * 1000L;

static public int getDeltaInWeeks(Date latterDate, Date earlierDate) {
    long deltaInMillis = latterDate.getTime() - earlierDate.getTime();
    int deltaInWeeks = (int)(deltaInMillis / MILLIS_PER_WEEK);
    return deltaInWeeks; 
}

Ancak bu test başarısız olacaktır:

public void testGetDeltaInWeeks() {
    delta = AggregatedData.getDeltaInWeeks(dateMar09, dateFeb23);
    assertEquals("weeks between Feb23 and Mar09", 2, delta);
}

Sebebi:

09 Mart Pzt 00:00:00 EDT 2009 = 1.236.571.200.000
23 Şubat Pzt 00:00:00 EST 2009 = 1.235.365.200.000
MilisPerHafta = 604.800.000
Böylece,
(09 Mart - 23 Şubat) / Milis Başına Hafta =
1.206.000.000 / 604.800.000 = 1.994 ...

ancak bir takvime bakan herkes cevabın 2 olduğu konusunda hemfikirdir.


1
Farkına varmak EDT ve EST'ye . Yaz saati uygulamasına bakıyorsunuz. Haftada 168 saat (baharda bir saat "kazanma" için +1) * iki hafta, fazladan DST saatini ekleyerek ve şunlara sahip olursunuz: 335/168 = 1.9940476190.
jpswain

3

Bu işlevi kullanıyorum:

DATEDIFF("31/01/2016", "01/03/2016") // me return 30 days

işlevim:

import java.util.Date;

public long DATEDIFF(String date1, String date2) {
        long MILLISECS_PER_DAY = 24 * 60 * 60 * 1000;
        long days = 0l;
        SimpleDateFormat format = new SimpleDateFormat("dd/MM/yyyy"); // "dd/MM/yyyy HH:mm:ss");

        Date dateIni = null;
        Date dateFin = null;        
        try {       
            dateIni = (Date) format.parse(date1);
            dateFin = (Date) format.parse(date2);
            days = (dateFin.getTime() - dateIni.getTime())/MILLISECS_PER_DAY;                        
        } catch (Exception e) {  e.printStackTrace();  }   

        return days; 
     }


2

@ Mad_Troll'un cevabına dayanarak, bu yöntemi geliştirdim.

Buna karşı yaklaşık 30 test vakası çalıştırdım, gün altı saat parçalarını doğru şekilde işleyen tek yöntem.

Örnek: Şimdi & şimdi + 1 milisaniye geçerseniz, bu hala aynı gündür. Amaçlı 1-1-13 23:59:59.098için 1-1-13 23:59:59.099doğru bir şekilde, 0 gün geri döner; Burada yayınlanan diğer yöntemlerin paylaştırılması bunu doğru şekilde yapmayacaktır.

Bunları hangi yöne koyduğunuzun umurunda değil, bitiş tarihiniz başlangıç ​​tarihinizden önceyse geriye doğru sayılacaktır.

/**
 * This is not quick but if only doing a few days backwards/forwards then it is very accurate.
 *
 * @param startDate from
 * @param endDate   to
 * @return day count between the two dates, this can be negative if startDate is after endDate
 */
public static long daysBetween(@NotNull final Calendar startDate, @NotNull final Calendar endDate) {

    //Forwards or backwards?
    final boolean forward = startDate.before(endDate);
    // Which direction are we going
    final int multiplier = forward ? 1 : -1;

    // The date we are going to move.
    final Calendar date = (Calendar) startDate.clone();

    // Result
    long daysBetween = 0;

    // Start at millis (then bump up until we go back a day)
    int fieldAccuracy = 4;
    int field;
    int dayBefore, dayAfter;
    while (forward && date.before(endDate) || !forward && endDate.before(date)) {
        // We start moving slowly if no change then we decrease accuracy.
        switch (fieldAccuracy) {
            case 4:
                field = Calendar.MILLISECOND;
                break;
            case 3:
                field = Calendar.SECOND;
                break;
            case 2:
                field = Calendar.MINUTE;
                break;
            case 1:
                field = Calendar.HOUR_OF_DAY;
                break;
            default:
            case 0:
                field = Calendar.DAY_OF_MONTH;
                break;
        }
        // Get the day before we move the time, Change, then get the day after.
        dayBefore = date.get(Calendar.DAY_OF_MONTH);
        date.add(field, multiplier);
        dayAfter = date.get(Calendar.DAY_OF_MONTH);

        // This shifts lining up the dates, one field at a time.
        if (dayBefore == dayAfter && date.get(field) == endDate.get(field))
            fieldAccuracy--;
        // If day has changed after moving at any accuracy level we bump the day counter.
        if (dayBefore != dayAfter) {
            daysBetween += multiplier;
        }
    }
    return daysBetween;
}

@NotNullEk açıklamaları kaldırabilirsiniz , bunlar Intellij tarafından anında kod analizi yapmak için kullanılır


Millis'i hesaba katıyorum, bu hesap makinesinin yapmadığını, sayıları 0'a yuvarladığını varsayıyorum. Cevabın üst kısmında belirttiğim gibi. Saatlerinizi / dakikalarınızı / saniyenizi / milislerinizi düzleştirin ve daha sonra doğru sayılacağını göreceksiniz.
Chris.Jenkins

1

Bunun "bağımsız bir programda iyi çalıştığını" söylüyorsunuz, ancak "bunu rapordan okumak için mantığıma dahil ettiğinizde" "olağandışı fark değerleri" elde ediyorsunuz. Bu, raporunuzun doğru çalışmayan bazı değerlere sahip olduğunu ve bağımsız programınızın bu değerlere sahip olmadığını gösterir. Bağımsız bir program yerine, bir test senaryosu öneririm. JUnit'in TestCase sınıfından alt sınıflara ayırarak bağımsız bir program gibi bir test senaryosu yazın. Şimdi ne kadar değer beklediğinizi bilerek çok spesifik bir örnek çalıştırabilirsiniz (ve bugün test değeri için vermeyin, çünkü bugün zamanla değişir). Bağımsız programda kullandığınız değerleri girerseniz, testleriniz muhtemelen başarılı olacaktır. Bu harika - bu davaların çalışmaya devam etmesini istiyorsunuz. Şimdi, raporunuzdan olmayan bir değer ekleyin doğru çalış. Yeni testiniz muhtemelen başarısız olacaktır. Neden başarısız olduğunu anlayın, düzeltin ve yeşile dönün (tüm testler geçti). Raporunuzu çalıştırın. Hala bozuk olanı görün; bir test yazın; geçmesini sağlayın. Çok yakında raporunuzun işe yaradığını göreceksiniz.


1

Bu temel işlev için yüzlerce satır kod ???

Sadece basit bir yöntem:

protected static int calculateDayDifference(Date dateAfter, Date dateBefore){
    return (int)(dateAfter.getTime()-dateBefore.getTime())/(1000 * 60 * 60 * 24); 
    // MILLIS_IN_DAY = 1000 * 60 * 60 * 24;
}

5
Saat dilimlerini yok sayar. Yaz Saati Uygulaması ve diğer anormallikleri yok sayar. Kısmi günlerin yuvarlanmasını göz ardı eder.
Fesleğen Bourque

1
public static int getDifferenceIndays(long timestamp1, long timestamp2) {
    final int SECONDS = 60;
    final int MINUTES = 60;
    final int HOURS = 24;
    final int MILLIES = 1000;
    long temp;
    if (timestamp1 < timestamp2) {
        temp = timestamp1;
        timestamp1 = timestamp2;
        timestamp2 = temp;
    }
    Calendar startDate = Calendar.getInstance(TimeZone.getDefault());
    Calendar endDate = Calendar.getInstance(TimeZone.getDefault());
    endDate.setTimeInMillis(timestamp1);
    startDate.setTimeInMillis(timestamp2);
    if ((timestamp1 - timestamp2) < 1 * HOURS * MINUTES * SECONDS * MILLIES) {
        int day1 = endDate.get(Calendar.DAY_OF_MONTH);
        int day2 = startDate.get(Calendar.DAY_OF_MONTH);
        if (day1 == day2) {
            return 0;
        } else {
            return 1;
        }
    }
    int diffDays = 0;
    startDate.add(Calendar.DAY_OF_MONTH, diffDays);
    while (startDate.before(endDate)) {
        startDate.add(Calendar.DAY_OF_MONTH, 1);
        diffDays++;
    }
    return diffDays;
}

1

ThreeTen-Ekstra

Vitalii Fedorenko tarafından cevap ile modern bir şekilde bu hesaplamayı nasıl gerçekleştirileceği açıklayan doğru java.time sınıfları ( Duration& ChronoUnitsonradan Java 8 yerleşik ve) (ve arka portlu Java 6 & 7 ve Android'e ).

Days

Kodunuzda rutin olarak birkaç gün kullanıyorsanız, yalnızca tam sayıları sınıf kullanımıyla değiştirebilirsiniz. DaysSınıf bulunabilir ThreeTen-Extra , proje java.time mümkün gelecek eklemeler için bir java.time uzatılmasını ve ispat zemin. DaysSınıf uygulamanızda gün sayısı temsil türüdür güvenli bir yol sağlar. Sınıf, ZEROve için uygun sabitleri içerir ONE.

Soru'daki eski modası geçmiş java.util.Datenesneler göz önüne alındığında , önce bunları modern java.time.Instantnesnelere dönüştürün . Eski tarih-saat sınıfları, java.time biçimine dönüştürmeyi kolaylaştırmak için yeni eklenmiş yöntemler içerir java.util.Date::toInstant.

Instant start = utilDateStart.toInstant(); // Inclusive.
Instant stop = utilDateStop.toInstant();  // Exclusive.

Her iki Instantnesneyi için fabrika yöntemine geçirin org.threeten.extra.Days.

Mevcut uygulamada (2016-06) bu bir sarmalayıcı çağrısıdır java.time.temporal.ChronoUnit.DAYS.between, ChronoUnitayrıntılar için sınıf belgesini okuyun . Açıklamak gerekirse: tüm büyük DAYSenum olan ChronoUnitilk-cap ederken DaysThreeTen-EXTRA bir sınıftır.

Days days = Days.between( start , stop );

Bu Daysnesneleri kendi kodunuzdan geçirebilirsiniz . Çağırarak standart ISO 8601 biçiminde bir Dizeye serileştirebilirsiniz toString. Bu format , başlangıcı işaretlemek için PnDa kullanır Pve Daralarında birkaç gün olan "günler" anlamına gelir. Hem java.time sınıfları hem de ThreeTen-Extra, tarih-saat değerlerini temsil eden Dizeleri oluştururken ve ayrıştırırken varsayılan olarak bu standart biçimleri kullanır.

String output = days.toString();

P3D

Days days = Days.parse( "P3D" );  

0

Bu kod, 2 tarih Dizesi arasındaki günleri hesaplar:

    static final long MILLI_SECONDS_IN_A_DAY = 1000 * 60 * 60 * 24;
    static final String DATE_FORMAT = "dd-MM-yyyy";
    public long daysBetween(String fromDateStr, String toDateStr) throws ParseException {
    SimpleDateFormat format = new SimpleDateFormat(DATE_FORMAT);
    Date fromDate;
    Date toDate;
    fromDate = format.parse(fromDateStr);
    toDate = format.parse(toDateStr);
    return (toDate.getTime() - fromDate.getTime()) / MILLI_SECONDS_IN_A_DAY;
}

0

Örneğin , Joda Time kullanarak uygun sayı veya günleri döndüren bir çözüm arıyorsanız 11/30/2014 23:59ve 12/01/2014 00:01işte çözümü.

private int getDayDifference(long past, long current) {
    DateTime currentDate = new DateTime(current);
    DateTime pastDate = new DateTime(past);
    return currentDate.getDayOfYear() - pastDate.getDayOfYear();
} 

Bu uygulama 1gün cinsinden fark olarak geri dönecektir . Burada yayınlanan çözümlerin çoğu, iki tarih arasındaki farkı milisaniye cinsinden hesaplar. Bu 0iki tarih arasında sadece 2 dakika fark olduğu için iade edileceği anlamına gelir .


0

Joda Time kitaplığını kullanmalısınız çünkü Java Util Date bazen yanlış değerler verir.

Joda ve Java Util Tarihi

Örneğin dün (gg-aa-yyyy, 12-07-2016) ile 1957'de yılın ilk günü (gg-aa-yyyy, 01-01-1957) arasındaki günler:

public class Main {

public static void main(String[] args) {
    SimpleDateFormat format = new SimpleDateFormat("dd-MM-yyyy");

    Date date = null;
    try {
        date = format.parse("12-07-2016");
    } catch (ParseException e) {
        e.printStackTrace();
    }

    //Try with Joda - prints 21742
    System.out.println("This is correct: " + getDaysBetweenDatesWithJodaFromYear1957(date));
    //Try with Java util - prints 21741
    System.out.println("This is not correct: " + getDaysBetweenDatesWithJavaUtilFromYear1957(date));    
}


private static int getDaysBetweenDatesWithJodaFromYear1957(Date date) {
    DateTime jodaDateTime = new DateTime(date);
    DateTimeFormatter formatter = DateTimeFormat.forPattern("dd-MM-yyyy");
    DateTime y1957 = formatter.parseDateTime("01-01-1957");

    return Days.daysBetween(y1957 , jodaDateTime).getDays();
}

private static long getDaysBetweenDatesWithJavaUtilFromYear1957(Date date) {
    SimpleDateFormat format = new SimpleDateFormat("dd-MM-yyyy");

    Date y1957 = null;
    try {
        y1957 = format.parse("01-01-1957");
    } catch (ParseException e) {
        e.printStackTrace();
    }

    return TimeUnit.DAYS.convert(date.getTime() - y1957.getTime(), TimeUnit.MILLISECONDS);
}

Bu yüzden Joda Time kütüphanesini kullanmanızı gerçekten tavsiye ediyorum.


1
Bilginize, Joda-Time hala aktif olarak desteklenirken, geliştirme ekibi java.time'a geçişi tavsiye ediyor . Ana sayfalarından alıntı yapmak gerekirse: "Joda-Time, Java SE 8'den önceki Java için fiili standart tarih ve saat kitaplığıdır. Artık kullanıcılardan java.time'a (JSR-310) geçiş yapmaları isteniyor."
Basil Bourque

-6

Ben bu şekilde yaptım. bu kolay :)

Date d1 = jDateChooserFrom.getDate();
Date d2 = jDateChooserTo.getDate();

Calendar day1 = Calendar.getInstance();
day1.setTime(d1);

Calendar day2 = Calendar.getInstance();
day2.setTime(d2);

int from = day1.get(Calendar.DAY_OF_YEAR);
int to = day2.get(Calendar.DAY_OF_YEAR);

int difference = to-from;

4
Bunun üzerinde biraz test yapın, bunun işe yaramayacağını çok çabuk anlayacaksınız. 31 Aralık 2013'ten 1 Ocak 2014'e kadar, bu bir günlük fark değil mi? Hesaplamanız 1 - 365 = -364 olacaktır. Bu kesinlikle doğru değil.
Chris.Jenkins
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.