software - java verify




समय के बिना दो तिथियों की तुलना कैसे करें? (20)

मैं एक तुलना करना चाहूंगा जो एक java.util.Date के समय भाग को अनदेखा करता है। मुझे लगता है कि इसे हल करने के कई तरीके हैं। सबसे आसान तरीका क्या है?


tl; डॉ

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

विरासत दिनांक-समय कक्षाओं से बचें

Date और Calendar जैसी परेशानी पुरानी विरासत डेट-टाइम कक्षाओं से बचें, जो अब जावा.टाइम कक्षाओं द्वारा आपूर्ति की जाती है।

जावा.टाइम का उपयोग करना

एक java.util.Date यूटीसी में समयरेखा पर एक पल का प्रतिनिधित्व करता है। Java.time में बराबर Instant । आप विरासत वर्ग में जोड़े गए नए तरीकों का उपयोग करके परिवर्तित कर सकते हैं।

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

आप तिथि से तुलना करना चाहते हैं। एक तिथि निर्धारित करने में एक समय क्षेत्र महत्वपूर्ण है। किसी भी क्षण के लिए, तिथि ज़ोन द्वारा दुनिया भर में बदलती है। उदाहरण के लिए, पेरिस फ्रांस में मध्यरात्रि के कुछ मिनट बाद एक नया दिन है जबकि मॉन्ट्रियल क्यूबेक में अभी भी "कल" ​​है।

continent/region , जैसे America/Montreal , Africa/Casablanca , या Pacific/Auckland के प्रारूप में उचित समय क्षेत्र का नाम निर्दिष्ट करें। EST या IST जैसे 3-4 अक्षर संक्षेप का कभी भी उपयोग न करें क्योंकि वे सही समय क्षेत्र नहीं हैं, मानकीकृत नहीं हैं, और यहां तक ​​कि अनूठा (!) भी नहीं।

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

ZoneId करने के लिए ZoneId को Instant लागू करें।

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

https://docs.oracle.com/javase/8/docs/api/java/time/LocalDate.html क्लास समय-समय पर और समय क्षेत्र के बिना दिनांक-केवल मूल्य का प्रतिनिधित्व करता है। हम LocalDate से LocalDate को निकाल सकते हैं, जो समय-समय पर प्रभावी ढंग से उन्मूलन कर सकते हैं।

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

अब तुलना करें, जैसे कि isEqual , isBefore , और isAfter तरीकों का उपयोग कर तुलना करें।

Boolean sameDate = localDate1.isEqual( localDate2 );

यह कोड IdeOne.com पर लाइव चलाएं देखें।

तत्काल 1: 2017-03-25T04: 13: 10.971Z | तत्काल 2: 2017-03-24 टी 22: 13: 10.9 72Z

zdt1: 2017-03-25T00: 13: 10.971-04: 00 [अमेरिका / मॉन्ट्रियल] | zdt2: 2017-03-24T18: 13: 10.972-04: 00 [अमेरिका / मॉन्ट्रियल]

स्थानीय दिनांक 1: 2017-03-25 | स्थानीय दिनांक 2: 2017-03-24

sameDate: झूठी

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

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

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

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

जावा.टाइम कक्षाएं कहां प्राप्त करें?

  • जावा एसई 8 और एसई 9 और बाद में
    • निर्मित।
    • एक बंडल कार्यान्वयन के साथ मानक जावा एपीआई का हिस्सा।
    • जावा 9 कुछ मामूली विशेषताओं और फिक्सेस जोड़ता है।
  • जावा एसई 6 और एसई 7
    • जावाटाइम की अधिकांश कार्यक्षमता को ThreeTen-Backport में जावा 6 और 7 में बैक-पोर्ट किया गया है।
  • Android
    • ThreeTenABP प्रोजेक्ट विशेष रूप से एंड्रॉइड के लिए थ्रीटेन-बैकपोर्ट (ऊपर उल्लिखित) को अनुकूलित करता है।
    • देखें थ्रीटेबैप का उपयोग कैसे करें ...।

ThreeTen-Extra प्रोजेक्ट अतिरिक्त कक्षाओं के साथ जावा.टाइम बढ़ाता है। यह परियोजना java.time के संभावित भविष्य के जोड़ों के लिए एक सिद्ध भूमि है। आपको यहां कुछ उपयोगी कक्षाएं मिल सकती हैं जैसे Interval , YearWeek , YearQuarter , more


SimpleDateFormat के getDateInstance का उपयोग करके, हम बिना किसी समय के केवल दो दिनांक वस्तु की तुलना कर सकते हैं। नीचे दिए गए कोड का निष्पादन करें।

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

    }

`

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

`


अपाचे कॉमन्स का उपयोग करके आप कर सकते हैं:

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

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

इसी से मेरा काम बना है:

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 }

जावा 8 और इंस्टेंट का उपयोग करने वाला एक अन्य समाधान, truncatedTo विधि का उपयोग कर रहा है

निर्दिष्ट इकाई को इस त्वरित प्रतिलिपि की एक प्रति देता है।

उदाहरण:

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

पहले से ही अपाचे कॉमन्स-यूटिल्स का उल्लेख किया गया है:

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

आपको तारीख के बिना तारीख की तारीख देता है, और आप इसे Date.compareTo तुलना कर सकते हैं


मुझे डर है कि दो तिथियों की तुलना करने की कोई विधि नहीं है जिसे "आसान" या "सरल" कहा जा सकता है।

किसी भी तरह की कम परिशुद्धता (उदाहरण के लिए तुलनात्मक तिथियों) के साथ दो बार उदाहरणों की तुलना करते समय, आपको हमेशा ध्यान रखना चाहिए कि समय क्षेत्र तुलना को कैसे प्रभावित करता है।

यदि date2 1 +2 date2 में हुई घटना को निर्दिष्ट कर रहा है और date2 2 ईएसटी में हुई एक घटना निर्दिष्ट कर रहा है, उदाहरण के लिए, आपको तुलना के प्रभावों को सही ढंग से समझने के लिए सावधानी बरतनी चाहिए।

क्या आपका उद्देश्य यह पता लगाना है कि क्या दो घटनाएं उसी कैलेंडर तिथि में अपने संबंधित समय क्षेत्र में हुईं? या आपको यह जानने की ज़रूरत है कि क्या दो तिथियां एक विशिष्ट समय क्षेत्र (यूटीसी या आपके स्थानीय टीजेड, उदाहरण के लिए) में समान कैलेंडर तिथि में आती हैं।

एक बार जब आप यह समझ लें कि वास्तव में यह क्या है कि आप तुलना करने की कोशिश कर रहे हैं, तो यह उचित समय क्षेत्र में वर्ष-दर-दिन ट्रिपल प्राप्त करने और तुलना करने की बात है।

जोडा समय वास्तविक तुलना ऑपरेशन को अधिक स्वच्छ बना सकता है, लेकिन तुलना के अर्थशास्त्र अभी भी कुछ हैं जो आपको स्वयं को समझने की आवश्यकता है।


मेरा प्रस्ताव:

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

मेरी वरीयता java.util.Date के Joda लाइब्रेरी इंसेटेड का उपयोग करना होगा, क्योंकि जोडा तिथि और समय के बीच एक अंतर बनाता है ( YearMonthDay और DateTime कक्षाएं देखें)।

हालांकि, अगर आप java.util.Date का उपयोग करना चाहते हैं तो मैं एक उपयोगिता विधि लिखने का सुझाव 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();
}

मैंने टाइमस्टैम्प की तुलना करके इसे हल किया:

    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
    }

मैं जोडा समय का उपयोग करने से बचता हूं क्योंकि एंड्रॉइड पर एक विशाल स्थान का उपयोग करता है। आकर महत्त्व रखता है। ;)


यदि आप केवल दो महीने के दिन और वर्ष की तुलना करना चाहते हैं, तो कोड मेरे लिए काम करता है:

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

धन्यवाद रोब।


यदि आप जावा 8 का उपयोग कर रहे हैं, तो आपको java.time.* उपयोग करना चाहिए 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);

यदि आप वास्तव में 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);
  }
}

यहां और मेरे सलाहकार मार्गदर्शन के आधार पर एक और सरल तुलना विधि

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

संपादित करें : @ जोनाथन ड्रैपौ के मुताबिक, ऊपर दिए गए कोड में कुछ मामलों में असफल रहा है (मैं उन मामलों को देखना चाहूंगा), और उन्होंने निम्नानुसार सुझाव दिया:

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

कृपया ध्यान दें कि, तिथि वर्ग को बहिष्कृत किया गया है क्योंकि यह अंतर्राष्ट्रीयकरण के लिए उपयुक्त नहीं था। इसके बजाय कैलेंडर वर्ग का उपयोग किया जाता है!


सबसे पहले, ध्यान रखें कि यह ऑपरेशन समय क्षेत्र पर निर्भर करता है। तो चुनें कि क्या आप यूटीसी में कंप्यूटर के समय क्षेत्र में अपने पसंदीदा समय क्षेत्र या कहां में ऐसा करना चाहते हैं। यदि आप अभी तक इस बात से सहमत नहीं हैं, तो इस उत्तर के निचले हिस्से में मेरा उदाहरण देखें।

चूंकि आपका प्रश्न इस बारे में बिल्कुल स्पष्ट नहीं है, इसलिए मुझे लगता है कि आपके पास एक समय क्षेत्र का प्रतिनिधित्व करने वाला एक उदाहरण क्षेत्र है और 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
    }

}

जावा 8 जावा। java.time कक्षाएं

मैंने आपके इंस्टेंस फ़ील्ड के प्रकार को Date से Instant , जावा 8 में इसी वर्ग से बदलने की स्वतंत्रता ली है। मैं नीचे दी गई Date के इलाज पर वापस आने का वादा करता हूं। मैंने एक समय क्षेत्र स्थिर भी जोड़ा है। आप इसे ZoneOffset.UTC या ZoneId.of("Europe/Stockholm") सेट कर सकते हैं या जो आपको उचित लगता है (इसे ZoneOffset कार्यों में सेट करना क्योंकि ZoneOffset का उप-वर्ग है)।

मैंने जावा 8 कक्षाओं का उपयोग करके समाधान दिखाना चुना है। आपने सबसे सरल तरीके से पूछा, है ना? :-) compareTo की गई है जिस विधि से आपने पूछा था:

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

यदि आपको कभी भी समय के समय की आवश्यकता नहीं है, तो LocalDate और सभी रूपांतरणों को छोड़ना घोषित करना आसान है। तब हमें समय क्षेत्र के बारे में चिंता करने की ज़रूरत नहीं है।

अब मान लीजिए कि किसी कारण से आप अपने क्षेत्र को Instant घोषित नहीं कर सकते हैं या आप इसे पुराने तरीके से रखना चाहते हैं। यदि आप अभी भी जावा 8 का उपयोग कर सकते हैं, तो इसे Instant परिवर्तित करें, फिर पहले की तरह करें:

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

इसी प्रकार o.when

जावा 8 नहीं?

यदि आप जावा 8 का उपयोग नहीं कर सकते हैं, तो दो विकल्प हैं:

  1. पुरानी कक्षाओं में से किसी एक का उपयोग करके इसे हल करें, या तो Calendar या SimpleDateFormat
  2. Java 6 और 7 के लिए जावा 8 दिनांक और समय कक्षाओं के बैकपोर्ट का उपयोग करें, फिर बस उपरोक्त के रूप में करें। मैं नीचे एक लिंक शामिल हैं। जोडाटाइम का प्रयोग न करें। जोडाटाइम शायद एक अच्छा सुझाव था जब उत्तर देने के उत्तर लिखे गए थे; लेकिन जोडाटाइम अब रखरखाव मोड में है, इसलिए थ्रीटेन बैकपोर्ट एक बेहतर और अधिक भविष्यप्रवाह विकल्प है।

पुराने तरीके से

एडमस्की का जवाब आपको दिखाता है कि Calendar वर्ग का उपयोग करके Date से समय को कैसे विभाजित करना है। मेरा सुझाव है कि आप इच्छित क्षेत्र के लिए Calendar उदाहरण प्राप्त करने के लिए getInstance(TimeZone) का उपयोग करें। एक विकल्प के रूप में आप जोर्न के जवाब के दूसरे भाग से विचार का उपयोग कर सकते हैं।

SimpleDateFormat का उपयोग करना SimpleDateFormat का उपयोग SimpleDateFormat का वास्तव में अप्रत्यक्ष तरीका है क्योंकि 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));
}

यह रॉब के जवाब से प्रेरित था।

समय क्षेत्र निर्भरता

हमें एक विशिष्ट समय क्षेत्र क्यों चुनना है? मान लें कि हम दो बार तुलना करना चाहते हैं कि यूटीसी में 24 मार्च 0:00 (आधी रात) और 12:00 (दोपहर) हैं। यदि आप सीईटी (कहते हैं, यूरोप / पेरिस) में ऐसा करते हैं, तो वे 24 मार्च को 1 बजे और 1 बजे हैं, जो वही तारीख है। न्यूयॉर्क (पूर्वी डेलाइट टाइम) में, वे 24 मार्च को 24:00 बजे और 8:00 बजे 20:00 बजे हैं, जो कि एक ही तारीख नहीं है। तो यह एक फर्क पड़ता है कि आप किस समय क्षेत्र चुनते हैं। यदि आप केवल कंप्यूटर के डिफ़ॉल्ट पर भरोसा करते हैं, तो आप इस आश्चर्यजनक दुनिया में किसी अन्य स्थान पर कंप्यूटर पर अपना कोड चलाने का प्रयास करते समय आश्चर्यचकित हो सकते हैं।

संपर्क

लिंक टू थ्रीटेन बैकपोर्ट, जावा 6 दिनांक और टाइम क्लास का बैकपोर्ट जावा 6 और 7: ThreeTen-Backport


DateUtil.daysBetween() कैसे DateUtil.daysBetween() । यह जावा है और यह एक संख्या (दिनों में अंतर) देता है।



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

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

इससे आपको समय पर विचार किए बिना तिथियों की तुलना करने में मदद मिलेगी।








java