Joda-Time में दो तिथियों के बीच दिनों की संख्या


335

मैं दो Joda-Time DateTime उदाहरणों के बीच के दिनों में अंतर कैसे पता करूँ ? 'दिनों में अंतर' से मेरा मतलब है कि अगर सोमवार सोमवार को शुरू होता है और मंगलवार को होता है, तो मुझे शुरुआत और समाप्ति तिथियों के घंटे / मिनट / सेकंड की परवाह किए बिना 1 की वापसी मूल्य की उम्मीद है।

Days.daysBetween(start, end).getDays() मुझे 0 देता है यदि प्रारंभ शाम में होता है और सुबह समाप्त होता है।

मैं भी अन्य तिथि क्षेत्रों के साथ एक ही मुद्दा रहा हूँ, इसलिए मैं उम्मीद कर रहा था कि कम महत्व के क्षेत्रों को 'अनदेखा' करने का एक सामान्य तरीका होगा।

दूसरे शब्दों में, फरवरी और 4 मार्च के बीच के महीने भी 1 होंगे, जैसा कि 14:45 और 15:12 के बीच का समय होगा। हालाँकि 14:01 और 14:55 के बीच का अंतर 0 होगा।

जवाबों:


393

अनायास, withTimeAtStartOfDay उत्तर गलत है, लेकिन केवल कभी-कभी। तुम्हें चाहिए:

Days.daysBetween(start.toLocalDate(), end.toLocalDate()).getDays()

यह पता चला है कि "आधी रात / दिन की शुरुआत" कभी-कभी 1am (दिन के उजाले की बचत कुछ स्थानों पर इस तरह से होती है) का मतलब है, जो Days.daysBetween ठीक से संभाल नहीं करता है।

// 5am on the 20th to 1pm on the 21st, October 2013, Brazil
DateTimeZone BRAZIL = DateTimeZone.forID("America/Sao_Paulo");
DateTime start = new DateTime(2013, 10, 20, 5, 0, 0, BRAZIL);
DateTime end = new DateTime(2013, 10, 21, 13, 0, 0, BRAZIL);
System.out.println(daysBetween(start.withTimeAtStartOfDay(),
                               end.withTimeAtStartOfDay()).getDays());
// prints 0
System.out.println(daysBetween(start.toLocalDate(),
                               end.toLocalDate()).getDays());
// prints 1

एक के माध्यम से जा रहे हैं LocalDateपूरे मुद्दे नजरअंदाज कर देता है।


क्या आप विशिष्ट डेटा के साथ एक उदाहरण मामला प्रदान कर सकते हैं, जहां आपको लगता Days.daysBetweenहै कि गलत है?
बेसिल बोर्के

जब आप उपयोग करने के लिए कहते हैं Instant, तो आप सिर्फ इसके बारे में बात नहीं कर start.toInstant()रहे हैं?
पैट्रिक एम

@ पैट्रिकम हां, मैं था। प्रतिबिंब पर, यह स्पष्ट रूप से स्पष्ट नहीं है कि यह किस उद्देश्य से लगाया गया है, इसलिए मैं उस अंतिम वाक्य को हटा दूंगा। धन्यवाद!
ऐलिस परसेल

@ क्रिस्पी डेज़बेटन डॉक्टर का कहना है कि यह WHOLE दिनों की संख्या देता है । मेरे मामले में 2 दिन और 1 घंटा मुझे 3 दिन वापस करना चाहिए। आपके उदाहरण में यह 2 दिन का है। क्या इसको हासिल करने के लिए कोई रास्ता है?
सुजीत जोशी

@SujitJoshi मुझे डर है कि मैं आपके सवाल को नहीं समझता। मेरा सुझाव है कि एक पूर्ण स्टैक ओवरफ्लो प्रश्न पोस्ट करना और मेरे लिए यहां एक लिंक चिपकाना :)
ऐलिस परसेल

186

Days कक्षा

विधि के Daysसाथ वर्ग का उपयोग करना withTimeAtStartOfDayचाहिए:

Days.daysBetween(start.withTimeAtStartOfDay() , end.withTimeAtStartOfDay() ).getDays() 

1
धन्यवाद! मैं joda के साथ android.text.format.DateUtils.getRelativeTimeSpanString () का व्यवहार प्राप्त करने की कोशिश कर रहा था और यह वास्तव में उपयोगी था।
gosho_ot_pochivka

1
सर, इस पोस्ट के संदर्भ में toDateMidnight()डेटाइम प्रकार से विधि को हटा दिया गया है।
अनिकेत कुलकर्णी

2
अब आपको .toDateMidnight () के बजाय .withTimeAtStartOfDay () का उपयोग करना चाहिए
bgolson

2
क्या होगा यदि endइससे पहले start, यह नकारात्मक दिन लौटाता है?
आख़िरी

7
@ सखार: आप इसे क्यों नहीं आजमाते?
माइकल Borgwardt


9

tl; डॉ

java.time.temporal.ChronoUnit.DAYS.between( 
    earlier.toLocalDate(), 
    later.toLocalDate() 
)

... या ...

java.time.temporal.ChronoUnit.HOURS.between( 
    earlier.truncatedTo( ChronoUnit.HOURS )  , 
    later.truncatedTo( ChronoUnit.HOURS ) 
)

java.time

FYI करें, जोडा-टाइम परियोजना अब रखरखाव मोड में है , जिसमें टीम java.time कक्षाओं में प्रवास की सलाह दे रही है ।

जोडा-टाइम के बराबर DateTimeहै ZonedDateTime

ZoneId z = ZoneId.of( "Pacific/Auckland" ) ;
ZonedDateTime now = ZonedDateTime.now( z ) ;

जाहिरा तौर पर आप तारीखों से दिनों की गिनती करना चाहते हैं, जिसका अर्थ है कि आप दिन के समय को अनदेखा करना चाहते हैं। उदाहरण के लिए, आधी रात से एक मिनट पहले शुरू करना और आधी रात के बाद एक मिनट के बाद एक दिन में परिणाम आना चाहिए। इस व्यवहार के लिए, LocalDateअपने से निकालें ZonedDateTimeLocalDateवर्ग समय के दिन और समय क्षेत्र के बिना बिना एक दिनांक-केवल मूल्य का प्रतिनिधित्व करता।

LocalDate localDateStart = zdtStart.toLocalDate() ;
LocalDate localDateStop = zdtStop.toLocalDate() ;

ChronoUnitबीते दिनों या अन्य इकाइयों की गणना करने के लिए एनम का उपयोग करें ।

long days = ChronoUnit.DAYS.between( localDateStart , localDateStop ) ;

काट-छांट

जैसा कि आप इस गिनती को करने के लिए एक अधिक सामान्य तरीके के बारे में पूछ रहे हैं, जहां आप घंटे के एक घंटे के रूप में घंटे के डेल्टा के रूप में रुचि रखते हैं, साठ मिनट के स्पैन-ऑफ-टाइम के रूप में पूरे घंटे के बजाय truncatedToविधि का उपयोग करें ।

उसी दिन 14:45 से 15:12 तक आपका उदाहरण है।

ZoneId z = ZoneId.of( "America/Montreal" ); 
ZonedDateTime start = ZonedDateTime.of( 2017 , 1 , 17 , 14 , 45 , 0 , 0 , z );
ZonedDateTime stop = ZonedDateTime.of( 2017 , 1 , 17 , 15 , 12 , 0 , 0 , z );

long hours = ChronoUnit.HOURS.between( start.truncatedTo( ChronoUnit.HOURS ) , stop.truncatedTo( ChronoUnit.HOURS ) );

1

यह दिनों के लिए काम नहीं करता है। इस मामले में toLocalDate () का उपयोग करें।


जावा के बारे में

Java.time ढांचे जावा 8 और बाद में बनाया गया है। इन कक्षाओं परेशानी वर्ष प्रतिस्थापित विरासत जैसे तिथि-समय कक्षाएं java.util.Date, Calendar, और SimpleDateFormat

अब जोडा-टाइम परियोजना, रखरखाव मोड में , java.time कक्षाओं में प्रवासन की सलाह देती है ।

अधिक जानने के लिए, Oracle ट्यूटोरियल देखें । और कई उदाहरणों और स्पष्टीकरणों के लिए ढेर अतिप्रवाह खोजें। विशिष्टता JSR 310 है

आप अपने डेटाबेस से सीधे java.time वस्तुओं का आदान-प्रदान कर सकते हैं । JDBC 4.2 या उसके बाद के JDBC ड्राइवर का अनुपालन करें । तार की कोई जरूरत नहीं, कक्षाओं की कोई जरूरत नहीं ।java.sql.*

Java.time कक्षाएं कहाँ से प्राप्त करें?

ThreeTen-अतिरिक्त परियोजना अतिरिक्त कक्षाओं के साथ java.time फैली हुई है। यह परियोजना java.time के लिए भविष्य के अतिरिक्त के लिए एक साबित जमीन है। आप यहाँ कुछ उपयोगी वर्गों जैसे मिल सकता है Interval, YearWeek, YearQuarter, और अधिक

ThreeTen-अतिरिक्त परियोजना अतिरिक्त कक्षाओं के साथ java.time फैली हुई है। यह परियोजना java.time के लिए भविष्य के अतिरिक्त के लिए एक साबित जमीन है। आप यहाँ कुछ उपयोगी वर्गों जैसे मिल सकता है Interval, YearWeek, YearQuarter, और अधिक


आपका टीएल; DR, ट्रंकट का उपयोग करने वाले दिनों के लिए स्वीकृत उत्तर में विस्तृत बग के शिकार हो जाता है, अर्थात जब यह दिन के 1 बजे शुरू होता है, तो यह बंद हो जाता है। मैंने इसे सही उत्तर का उपयोग करने के लिए अद्यतन किया है जो आपने आगे दिया है, तोलोकडेट का उपयोग करके।
ऐलिस पर्ससेल

2

स्वीकृत उत्तर दो LocalDateवस्तुओं का निर्माण करता है, जो काफी महंगे हैं यदि आप बहुत सारा डेटा पढ़ रहे हैं। मैं इसका उपयोग करता हूं:

  public static int getDaysBetween(DateTime earlier, DateTime later)
  {
    return (int) TimeUnit.MILLISECONDS.toDays(later.getMillis()- earlier.getMillis());
  }

कॉल करके getMillis()आप पहले से मौजूद चर का उपयोग करते हैं।
MILLISECONDS.toDays()फिर, एक साधारण अंकगणितीय गणना का उपयोग करता है, कोई वस्तु नहीं बनाता है।


1
यह उत्तर केवल तभी काम करता है जब आपकी 'दिनों' की परिभाषा समय क्षेत्रों और तिथियों के संबंध में 24 घंटे लंबी हो। यदि हां, तो इस दृष्टिकोण का उपयोग करें। यदि नहीं, तो समय क्षेत्र को संबोधित करने वाले अन्य उत्तरों को देखें।
तुलसी बोर्क

@BasilBourque, आप सही हैं, फिर भी, मैं अंकगणितीय गणना के आधार पर एक समाधान के लिए जाऊंगा, बल्कि प्रत्येक विधि कॉल के लिए महंगी वस्तुओं का निर्माण करूँगा, इस तरह की गणना के लिए कई स्वाद हैं, यदि आप एक वेब पेज से एक इनपुट पढ़ रहे हैं, ठीक हो सकता है, लेकिन अगर आप लॉग फ़ाइल को सैकड़ों हज़ारों लाइनों के साथ संसाधित कर रहे हैं, तो यह बहुत धीमा कर देता है
JBoy

1
यदि आपका लूप गर्म है तो जावा ऑब्जेक्ट एलोकेशन को दूर कर देगा। Docs.oracle.com/javase/7/docs/technotes/guides/vm/…
ऐलिस परसेल

1

java.time.Period

दिनों की गिनतीjava.time.Period करने के लिए कक्षा का उपयोग करें ।

जावा 8 की गणना के बाद से अंतर का उपयोग करना अधिक सहज है LocalDate , LocalDateTimeदो तिथियों का प्रतिनिधित्व करने के

    LocalDate now = LocalDate.now();
    LocalDate inputDate = LocalDate.of(2018, 11, 28);

    Period period = Period.between( inputDate, now);
    int diff = period.getDays();
    System.out.println("diff = " + diff);

0
DateTime  dt  = new DateTime(laterDate);        

DateTime newDate = dt.minus( new  DateTime ( previousDate ).getMillis());

System.out.println("No of days : " + newDate.getDayOfYear() - 1 );    

-11
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
सवाल विशेष रूप से joda-time की तलाश में है।
कपड़ाल k
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.