कैसे जावा में एक तारीख को पवित्रता की जाँच करें [बंद]


83

मुझे यह उत्सुक लगता है कि Dateजावा में वस्तुओं को बनाने का सबसे स्पष्ट तरीका हटा दिया गया है और ऐसा लगता है कि "वैकल्पिक रूप से प्रतिस्थापित" किया गया है ताकि लिनेन कैलेंडर का उपयोग न किया जा सके।

आप कैसे जांचते हैं कि दिन, महीने और वर्ष के संयोजन के रूप में दी गई तारीख एक वैध तिथि है?

उदाहरण के लिए, 2008-02-31 (जैसा कि yyyy-mm-dd में) एक अमान्य तारीख होगी।


एक समान प्रश्न वाले किसी के लिए, कृपया विचार करें कि क्या आपको गैर-ग्रेगोरियन कैलेंडर समर्थन की आवश्यकता है।
एमएसल्टर्स

@ जेसन मैं पूरी तरह से आपके साथ सहमत हूं, उन्हें विलय करना सबसे अच्छा तरीका है।
एसीएम

जवाबों:


37

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

जोड़ना भूल गए: यदि आपको कैलेंडर का उदाहरण मिलता है और अपनी तिथि का उपयोग करने का समय निर्धारित है, तो यह है कि आपको सत्यापन कैसे मिलेगा।

Calendar cal = Calendar.getInstance();
cal.setLenient(false);
cal.setTime(yourDate);
try {
    cal.getTime();
}
catch (Exception e) {
  System.out.println("Invalid date");
}

2
लगता है कि यह बिल्कुल काम नहीं करता है। Calendar.setTime java.util.Date लेता है, इसलिए स्ट्रिंग से रूपांतरण तब तक हो चुका होता है, जब तक आपको "आपका" ऑब्जेक्ट नहीं मिल जाता।
tardate

33
उदाहरण कोड के साथ 3 समस्याएं: 1. कैलेंडर उदाहरण प्राप्त करने के बाद, आपको cal.setLenient (झूठी) कॉल करना होगा। अन्यथा 31 फरवरी 2007 की तारीख को वैध माना जाएगा। 2. एक अपवाद cal.setTime () द्वारा फेंका नहीं जाता है। आपको सेटटाइम () कॉल के बाद cal.getTime () कॉल करना होगा, जो अमान्य दिनांक पर एक अपवाद फेंकता है। 3. टाइपो: कैच से पहले '}' मिस करना।
लिरॉन याहदाव

यह भी अन्य तरीकों की तुलना में धीमी है। देखें stackoverflow.com/questions/2149680/…
despot

5
FYI करें, पुराने समय की परेशान करने वाली पुरानी कक्षाएं जैसे कि java.util.Date, java.util.Calendarऔर java.text.SimpleDateFormatअब विरासत है , जावा 8 और बाद में निर्मित java.time कक्षाओं द्वारा ली गई है । ओरेकल द्वारा ट्यूटोरियल देखें ।
बेसिल बोर्क

3
31 फरवरी की तारीखों को मान्य नहीं करता
शिखा सिंह

78

कुंजी df.setLenient (झूठी) है; । यह साधारण मामलों के लिए पर्याप्त से अधिक है। यदि आप अधिक मजबूत (मुझे संदेह है) और / या वैकल्पिक लाइब्रेरियों जैसे जॉडा-टाइम की तलाश कर रहे हैं, तो उपयोगकर्ता "टार्डेट" के उत्तर को देखें।

final static String DATE_FORMAT = "dd-MM-yyyy";

public static boolean isDateValid(String date) 
{
        try {
            DateFormat df = new SimpleDateFormat(DATE_FORMAT);
            df.setLenient(false);
            df.parse(date);
            return true;
        } catch (ParseException e) {
            return false;
        }
}

2
"09-04-201a" के साथ प्रयास करें। यह एक पागल तारीख पैदा करेगा।
केकेल

@ इस्कॉक वह तरीका है जो काम करता है, भले ही आप उपयोग करें setLenientया न करें: SimpleDateFormatपैटर्न के मिलान होने तक हमेशा पार्स रहेगा और बाकी स्ट्रिंग को अनदेखा करें, इस प्रकार आपको 201वर्ष मिलता है ।
डैनियल नबेर

@ इस्कलॉक मैंने इसे अपने समाधान में संबोधित किया । यह किसी के लिए एक या दो मिनट बचा सकता है।
सूफियान

1
अपवाद को शामिल करने से एक बड़ा प्रदर्शन प्रभावित होता है, इसलिए यह संभवतः एक खराब डिज़ाइन है यदि आप सामान्य ऑपरेशन में विकृत इनपुट की उम्मीद करते हैं (जैसे उपयोगकर्ता इनपुट को मान्य करना)। लेकिन अगर विधि का उपयोग इनपुट के खिलाफ दोहरे-चेक के रूप में किया जाता है जो कि हर समय (बग को छोड़कर) मान्य होते हैं, तो यह ठीक है।
एरोन

2
FYI करें, इस तरह के रूप में बहुत परेशानी पुराने तिथि-समय कक्षाएं java.util.Date, java.util.Calendarऔर java.text.SimpleDateFormatअब कर रहे हैं विरासत , द्वारा का स्थान ले लिया java.time जावा 8 और बाद में बनाया गया वर्गों। ओरेकल द्वारा ट्यूटोरियल देखें ।
तुलसी Bourque

48

जैसा कि @ मैग्लोब द्वारा दिखाया गया है, मूल दृष्टिकोण सिंपलडेटफार्मैट.पर्स का उपयोग करके स्ट्रिंग से तारीख तक रूपांतरण का परीक्षण करना है । यह 2008-02-31 जैसे अमान्य दिन / महीने के संयोजन को पकड़ लेगा।

हालाँकि, SimpleDateFormat.parse के बाद से शायद ही कभी पर्याप्त रूप से उदार है। आप के साथ संबंध हो सकता है दो व्यवहार कर रहे हैं:

दिनांक स्ट्रिंग में अमान्य वर्ण आश्चर्यजनक रूप से, 2008-02-2x उदाहरण के लिए स्थानीय प्रारूप = "yyyy-MM-dd" के साथ एक वैध तारीख के रूप में "पास" होगा। यहाँ तक कि जब।

वर्ष: 2, 3 या 4 अंक? आप डिफ़ॉल्ट SimpleDateFormat व्यवहार (जो "12-02-31" की व्याख्या अलग-अलग करने की अनुमति देने के बजाय 4-अंकीय वर्ष लागू करना चाह सकते हैं, यह निर्भर करता है कि आपका प्रारूप "yyyy-MM-dd" या "yy-MM-dd" है) )

मानक पुस्तकालय के साथ एक सख्त समाधान

तो एक पूरी स्ट्रिंग टू डेट टेस्ट इस तरह दिख सकता है: रेगेक्स मैच का एक संयोजन, और फिर एक मजबूर तारीख रूपांतरण। रेगेक्स के साथ चाल इसे स्थानीय रूप से अनुकूल बनाने के लिए है।

  Date parseDate(String maybeDate, String format, boolean lenient) {
    Date date = null;

    // test date string matches format structure using regex
    // - weed out illegal characters and enforce 4-digit year
    // - create the regex based on the local format string
    String reFormat = Pattern.compile("d+|M+").matcher(Matcher.quoteReplacement(format)).replaceAll("\\\\d{1,2}");
    reFormat = Pattern.compile("y+").matcher(reFormat).replaceAll("\\\\d{4}");
    if ( Pattern.compile(reFormat).matcher(maybeDate).matches() ) {

      // date string matches format structure, 
      // - now test it can be converted to a valid date
      SimpleDateFormat sdf = (SimpleDateFormat)DateFormat.getDateInstance();
      sdf.applyPattern(format);
      sdf.setLenient(lenient);
      try { date = sdf.parse(maybeDate); } catch (ParseException e) { }
    } 
    return date;
  } 

  // used like this:
  Date date = parseDate( "21/5/2009", "d/M/yyyy", false);

ध्यान दें कि रेगेक्स मानता है कि प्रारूप स्ट्रिंग में केवल दिन, महीने, वर्ष और विभाजक वर्ण होते हैं। इसके अलावा, प्रारूप किसी भी स्थानीय प्रारूप में हो सकता है: "d / MM / yy", "yyyy-MM-dd", और इसी तरह। वर्तमान लोकेल के लिए प्रारूप स्ट्रिंग इस तरह प्राप्त की जा सकती है:

Locale locale = Locale.getDefault();
SimpleDateFormat sdf = (SimpleDateFormat)DateFormat.getDateInstance(DateFormat.SHORT, locale );
String format = sdf.toPattern();

Joda समय - बेहतर वैकल्पिक?

मैं हाल ही में joda समय के बारे में सुन रहा हूं और सोचा था कि मैं तुलना करूंगा। दो बिंदु:

  1. SimpleDateFormat के विपरीत, दिनांक स्ट्रिंग में अमान्य वर्णों के बारे में बेहतर लगता है
  2. अभी तक इसके साथ 4-अंकीय वर्षों को लागू करने का एक तरीका नहीं देख सकता (लेकिन मुझे लगता है कि आप इस कार्य के लिए अपना खुद का DateTimeFormatter बना सकते हैं )

यह उपयोग करने के लिए काफी सरल है:

import org.joda.time.format.*;
import org.joda.time.DateTime;

org.joda.time.DateTime parseDate(String maybeDate, String format) {
  org.joda.time.DateTime date = null;
  try {
    DateTimeFormatter fmt = DateTimeFormat.forPattern(format);
    date =  fmt.parseDateTime(maybeDate);
  } catch (Exception e) { }
  return date;
}

मैंने जोडा विकल्प के साथ समाप्त किया और जांच की कि मूल्य पैटर्न की लंबाई से खुद मेल खाता है ...
Xtreme बाइकर

अद्यतन: भयानक पुरानी विरासत कक्षाएं ( Dateऔर SimpleDateFormat, आदि) अब आधुनिक java.time कक्षाओं द्वारा दबा दी जाती हैं। इसी तरह, जोडा-टाइम परियोजना रखरखाव मोड में है, और java.time कक्षाओं में प्रवास की सलाह देती है ।
तुलसी Bourque

39

आप SimpleDateFormat का उपयोग कर सकते हैं

उदाहरण के लिए कुछ इस तरह:

boolean isLegalDate(String s) {
    SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
    sdf.setLenient(false);
    return sdf.parse(s, new ParsePosition(0)) != null;
}

2
इस दृष्टिकोण के साथ समस्याओं में से एक यह है कि इसकी 0003-0002-001 स्वीकार करने वाली है।
despot

1
एक और मुद्दा यह है कि महीने में 13 सेट करने से एक तारीख वापस आ जाती है जहां अगले वर्ष माह 01 होता है।
8bitjunkie

FYI करें, इस तरह के रूप में बहुत परेशानी पुराने तिथि-समय कक्षाएं java.util.Date, java.util.Calendarऔर java.text.SimpleDateFormatअब कर रहे हैं विरासत , द्वारा का स्थान ले लिया java.time जावा 8 और बाद में बनाया गया वर्गों। ओरेकल द्वारा ट्यूटोरियल देखें ।
तुलसी Bourque

29

tl; डॉ

का प्रयोग करें सख्त मोड पर java.time.DateTimeFormatterपार्स एक करने के लिए LocalDate। के लिए ट्रैप DateTimeParseException

LocalDate.parse(                   // Represent a date-only value, without time-of-day and without time zone.
    "31/02/2000" ,                 // Input string.
    DateTimeFormatter              // Define a formatting pattern to match your input string.
    .ofPattern ( "dd/MM/uuuu" )
    .withResolverStyle ( ResolverStyle.STRICT )  // Specify leniency in tolerating questionable inputs.
)

पार्स करने के बाद, आप उचित मूल्य की जांच कर सकते हैं। उदाहरण के लिए, पिछले एक सौ वर्षों के भीतर एक जन्म तिथि।

birthDate.isAfter( LocalDate.now().minusYears( 100 ) )

विरासत की तारीखों की कक्षाओं से बचें

जावा के शुरुआती संस्करणों के साथ शिप किए गए परेशान पुराने दिनांक-समय वर्गों का उपयोग करने से बचें। अब java.time कक्षाओं द्वारा इसे दबा दिया गया ।

LocalDateऔर DateTimeFormatter&ResolverStyle

LocalDateवर्ग समय के दिन और समय क्षेत्र के बिना बिना एक दिनांक-केवल मूल्य का प्रतिनिधित्व करता।

String input = "31/02/2000";
DateTimeFormatter f = DateTimeFormatter.ofPattern ( "dd/MM/uuuu" );
try {
    LocalDate ld = LocalDate.parse ( input , f );
    System.out.println ( "ld: " + ld );
} catch ( DateTimeParseException e ) {
    System.out.println ( "ERROR: " + e );
}

java.time.DateTimeFormatterकक्षा में परिभाषित तीन उदारता मोड से किसी के साथ तार पार्स करने के लिए सेट किया जा सकता ResolverStyleenum। हम प्रत्येक कोड को आजमाने के लिए उपरोक्त कोड में एक लाइन डालते हैं।

f = f.withResolverStyle ( ResolverStyle.LENIENT );

परिणाम:

  • ResolverStyle.LENIENT
    ld: 2000-03-02
  • ResolverStyle.SMART
    ld: 2000-02-29
  • ResolverStyle.STRICT
    त्रुटि: java.time.format.DateTimeParseException: पाठ '31 / 02/2000 'को पार्स नहीं किया जा सकता: अमान्य दिनांक' FEBRUARY 31 '

हम देख सकते हैं कि ResolverStyle.LENIENTमोड में, अमान्य दिनांक को समतुल्य दिनों के लिए आगे ले जाया जाता है। में ResolverStyle.SMARTमोड (डिफ़ॉल्ट), एक तार्किक निर्णय महीने के भीतर और महीने के अंतिम दिन संभव के साथ जा रहा तारीख को रखने के लिए किया जाता है, एक लीप वर्ष में 29 फ़रवरी, वहाँ के रूप में उस महीने में कोई 31 दिन है। ResolverStyle.STRICTमोड एक अपवाद शिकायत ऐसी कोई तारीख है कि वहाँ फेंकता है।

ये तीनों आपकी व्यावसायिक समस्या और नीतियों के आधार पर उचित हैं। आपके मामले में लगता है कि आप सख्त मोड को समायोजित करने के बजाय अमान्य दिनांक को अस्वीकार करना चाहते हैं।


जावा में सभी तिथि-समय प्रकारों की तालिका, दोनों आधुनिक और विरासत।


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

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

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

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

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

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

जावा या एंड्रॉइड के किस संस्करण के साथ उपयोग करने के लिए java.time लाइब्रेरी की तालिका

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


ठीक है, मान लें कि परियोजना को 8+ जावा के साथ संकलित किया जा रहा है, तो आपका उत्तर सही है। मैं इन कक्षाओं का उपयोग तब भी कर रहा हूँ जब परियोजना जावा 8 में है। लेकिन कभी-कभी मुझे उन बदसूरत प्राचीन jsp स्क्रिप्टलेट को छूना पड़ता है (जो कि java 7 का समर्थन नहीं करता है)। तारीखों को मान्य करने से दर्द होता है। इसलिए मैं यहां हूं। फिर भी आपका जवाब सबसे सही दृष्टिकोण है ... निष्कर्ष: मैं खराब हूँ।
कर्लग

@KarelG ने जावा 6 और जावा 7 में बैक-पोर्ट के बारे में दूसरा-से-अंतिम पैराग्राफ पढ़ा । मैंने इस व्यवहार को बैक-पोर्ट में सत्यापित नहीं किया है, लेकिन मेरा सुझाव है कि आप इसे आज़माएं।
तुलसी बॉर्क

13

java.time

साथ दिनांक और समय एपीआई ( java.time वर्ग) जावा 8 में बनाया गया और बाद में, आप उपयोग कर सकते LocalDateवर्ग।

public static boolean isDateValid(int year, int month, int day) {
    boolean dateIsValid = true;
    try {
        LocalDate.of(year, month, day);
    } catch (DateTimeException e) {
        dateIsValid = false;
    }
    return dateIsValid;
}

2
डिफ़ॉल्ट रूप से, यह कोड उपयोग करता है ResolverStyle.SMARTजो एक अपवाद को फेंकने के बजाय परिणामी मान को एक मान्य दिनांक पर समायोजित करता है। इसलिए यह कोड प्रश्न के लक्ष्य को पूरा नहीं करेगा। उदाहरण के लिए और समाधान का उपयोग करने के लिए मेरा उत्तर देखें ResolverStyle.STRICT
तुलसी बॉर्क

7

मानक पुस्तकालय का उपयोग कर एक वैकल्पिक सख्त समाधान निम्नलिखित कार्य करना है:

1) अपने पैटर्न का उपयोग करके एक सख्त SimpleDateFormat बनाएं

2) प्रारूप ऑब्जेक्ट का उपयोग करके उपयोगकर्ता द्वारा दर्ज मूल्य को पार्स करने का प्रयास

3) यदि सफल, एक ही तिथि प्रारूप ((1) से) का उपयोग करके परिणाम (2) से सुधार

4) मूल, उपयोगकर्ता द्वारा दर्ज मूल्य के खिलाफ सुधारित तारीख की तुलना करें। यदि वे समान हैं तो दर्ज किया गया मान आपके पैटर्न से सख्ती से मेल खाता है।

इस तरह, आपको जटिल नियमित अभिव्यक्तियाँ बनाने की ज़रूरत नहीं है - मेरे मामले में मुझे सिंपलडेटाफोर्मैट के सभी पैटर्न सिंटैक्स का समर्थन करने की आवश्यकता है, बजाय कुछ दिनों, महीनों और वर्षों जैसे कुछ प्रकारों तक सीमित रहने की।


यह निश्चित रूप से जाने का रास्ता है, dreamincode.net/forums/topic/…
विक्टर Ionescu

7

अपनी टिप्पणी में ceklock द्वारा बताई गई समस्या को ठीक करने के लिए अरविंद के उत्तर पर बिल्डिंग , मैंने यह सत्यापित करने के लिए एक विधि जोड़ी कि इसमें कोई अमान्य वर्ण नहीं है।dateString

यहाँ है मैं कैसे:

private boolean isDateCorrect(String dateString) {
    try {
        Date date = mDateFormatter.parse(dateString);
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        return matchesOurDatePattern(dateString);    //added my method
    }
    catch (ParseException e) {
        return false;
    }
}

/**
 * This will check if the provided string matches our date format
 * @param dateString
 * @return true if the passed string matches format 2014-1-15 (YYYY-MM-dd)
 */
private boolean matchesDatePattern(String dateString) {
    return dateString.matches("^\\d+\\-\\d+\\-\\d+");
}

5

मुझे लगता है कि सबसे सरल एक स्ट्रिंग को डेट ऑब्जेक्ट में बदलने और इसे वापस स्ट्रिंग में बदलने के लिए है। यदि दोनों तार अभी भी मेल खाते हैं तो दी गई तारीख स्ट्रिंग ठीक है।

public boolean isDateValid(String dateString, String pattern)
{   
    try
    {
        SimpleDateFormat sdf = new SimpleDateFormat(pattern);
        if (sdf.format(sdf.parse(dateString)).equals(dateString))
            return true;
    }
    catch (ParseException pe) {}

    return false;
}

4

मैं आपको org.apache.commons.validator.GenericValidatorअपाचे से कक्षा का उपयोग करने का सुझाव देता हूं ।

GenericValidator.isDate(String value, String datePattern, boolean strict);

नोट: सख्त - तारीख का सटीक मिलान होना या न होना।


2

यह मानते हुए कि वे दोनों स्ट्रिंग्स हैं (अन्यथा वे पहले से ही वैध दिनांक होंगे), यहां एक तरीका है:

package cruft;

import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;

public class DateValidator
{
    private static final DateFormat DEFAULT_FORMATTER;

    static
    {
        DEFAULT_FORMATTER = new SimpleDateFormat("dd-MM-yyyy");
        DEFAULT_FORMATTER.setLenient(false);
    }

    public static void main(String[] args)
    {
        for (String dateString : args)
        {
            try
            {
                System.out.println("arg: " + dateString + " date: " + convertDateString(dateString));
            }
            catch (ParseException e)
            {
                System.out.println("could not parse " + dateString);
            }
        }
    }

    public static Date convertDateString(String dateString) throws ParseException
    {
        return DEFAULT_FORMATTER.parse(dateString);
    }
}

यहाँ मैं प्राप्त उत्पादन है:

java cruft.DateValidator 32-11-2010 31-02-2010 04-01-2011
could not parse 32-11-2010
could not parse 31-02-2010
arg: 04-01-2011 date: Tue Jan 04 00:00:00 EST 2011

Process finished with exit code 0

जैसा कि आप देख सकते हैं, यह आपके दोनों मामलों को अच्छी तरह से संभालता है।


@duffymo दूसरा बयान अपवाद नहीं फेंक रहा है: ...(
अधिकतम

@ पैंगिया वास्तव में नहीं .... इस तिथि को "31-01-2010" की कोशिश करें, यह कोई अपवाद नहीं फेंकेगा .......... बस इसे अपनी मशीन पर चलाएं और देखें ... यह नहीं है काम ....
शशिधर

मेरी गलती। मैंने अपनी टिप्पणी हटा दी। हालांकि दूसरा बयान मेरे लिए अपवाद फेंक रहा है। @duffymo - आप किस jvm का उपयोग कर रहे हैं?
अरविंद यारम

@Pangea मैं jdk1.6.0_23 का उपयोग कर रहा हूं, मैंने इसके साथ joda-time.sourceforge.net की भी कोशिश की, लेकिन यहां तक ​​कि यह काम नहीं किया ....
sasidhar

1
मैं समझता हूं कि यह केवल एक साधारण परीक्षण है, लेकिन यह सुनिश्चित करने के लिए कि लोग इस क्रिया को कॉपी नहीं करते हैं, मैं "DateFormat" कहना चाहता हूं कि यह सुरक्षित नहीं है। इसलिए हमेशा इसे एक स्थानीय चर के रूप में बनाएं या इसे थ्रेड स्थानीय के साथ उपयोग करें।
अरविन्द यारम

2

यह मेरे लिए बहुत अच्छा काम कर रहा है। बेन द्वारा ऊपर सुझाया गया दृष्टिकोण।

private static boolean isDateValid(String s) {
    SimpleDateFormat sdf = new SimpleDateFormat("dd/MM/yyyy");
    try {
        Date d = asDate(s);
        if (sdf.format(d).equals(s)) {
            return true;
        } else {
            return false;
        }
    } catch (ParseException e) {
        return false;
    }
}

1
asDate को पहचान नहीं सकते। वो क्या है?
सुशील

2

SimpleDateFormat की तरह लग रहा है सेटलाइनेंट (झूठा) के बाद भी पैटर्न की सख्ती से जाँच नहीं कर रहा है ; विधि इस पर लागू होती है, इसलिए मैंने नीचे दी गई पद्धति का उपयोग यह प्रमाणित करने के लिए किया है कि इनपुट तिथि मान्य तिथि है या आपूर्ति किए गए पैटर्न के अनुसार नहीं।

import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeParseException;
public boolean isValidFormat(String dateString, String pattern) {
    boolean valid = true;
    DateTimeFormatter formatter = DateTimeFormatter.ofPattern(pattern);
    try {
        formatter.parse(dateString);
    } catch (DateTimeParseException e) {
        valid = false;
    }
    return valid;
}

1

SimpleDateFormat के उपयोग पर दो टिप्पणियाँ।

इसे स्थिर उदाहरण के रूप में घोषित किया जाना चाहिए, यदि स्थिर पहुंच के रूप में घोषित किया जाना चाहिए, क्योंकि यह थ्रेड सुरक्षित नहीं है

IME जो कि बेहतर है कि किसी तिथि के प्रत्येक पारे के लिए एक इंस्टेंटिंग को इंस्टेंट करना।


अच्छा बिंदु टॉम। मैंने स्थिर उदाहरण का उपयोग करके लगातार सुनिश्चित करने के लिए मेरे द्वारा दिए गए उदाहरण को अद्यतन किया।
tardate

एक सिंक्रनाइज़ फ़ंक्शन का उपयोग करना कुछ परियोजनाओं के लिए पैमाने नहीं हो सकता है। मैं SimpleDateFormat को थ्रेडलोकल वैरिएबल में डालने की सिफारिश करूंगा, क्योंकि स्टैटिक वेरिएबल को सिंक्रोनाइज़ फंक्शन के जरिए एक्सेस किया जाएगा।
user327961

0

डेट पार्सिंग के उपरोक्त तरीके अच्छे हैं, मैंने मौजूदा तरीकों में नया चेक जोड़ा है जो कि फॉर्मेटर का उपयोग करके मूल तिथि के साथ परिवर्तित तिथि की दोहरी जांच करता है, इसलिए यह लगभग हर मामले के लिए काम करता है जैसा कि मैंने सत्यापित किया है। जैसे 02/29/2013 अमान्य दिनांक है। दिए गए फ़ंक्शन को वर्तमान स्वीकार्य दिनांक प्रारूपों के अनुसार दिनांक पार्स करें। यह सच है अगर तारीख को सफलतापूर्वक पारस नहीं किया जाता है।

 public final boolean validateDateFormat(final String date) {
        String[] formatStrings = {"MM/dd/yyyy"};
        boolean isInvalidFormat = false;
        Date dateObj;
        for (String formatString : formatStrings) {
            try {
                SimpleDateFormat sdf = (SimpleDateFormat) DateFormat.getDateInstance();
                sdf.applyPattern(formatString);
                sdf.setLenient(false);
                dateObj = sdf.parse(date);
                System.out.println(dateObj);
                if (date.equals(sdf.format(dateObj))) {
                    isInvalidFormat = false;
                    break;
                }
            } catch (ParseException e) {
                isInvalidFormat = true;
            }
        }
        return isInvalidFormat;
    }

0

यहां मैंने बाहरी पुस्तकालयों का उपयोग करते हुए नोड पर्यावरण के लिए किया है:

Date.prototype.yyyymmdd = function() {
   var yyyy = this.getFullYear().toString();
   var mm = (this.getMonth()+1).toString(); // getMonth() is zero-based
   var dd  = this.getDate().toString();
   return zeroPad([yyyy, mm, dd].join('-'));  
};

function zeroPad(date_string) {
   var dt = date_string.split('-');
   return dt[0] + '-' + (dt[1][1]?dt[1]:"0"+dt[1][0]) + '-' + (dt[2][1]?dt[2]:"0"+dt[2][0]);
}

function isDateCorrect(in_string) {
   if (!matchesDatePattern) return false;
   in_string = zeroPad(in_string);
   try {
      var idate = new Date(in_string);
      var out_string = idate.yyyymmdd();
      return in_string == out_string;
   } catch(err) {
      return false;
   }

   function matchesDatePattern(date_string) {
      var dateFormat = /[0-9]+-[0-9]+-[0-9]+/;
      return dateFormat.test(date_string); 
   }
}

और यहाँ इसका उपयोग कैसे करना है:

isDateCorrect('2014-02-23')
true

0
// to return valid days of month, according to month and year
int returnDaysofMonth(int month, int year) {
    int daysInMonth;
    boolean leapYear;
    leapYear = checkLeap(year);
    if (month == 4 || month == 6 || month == 9 || month == 11)
        daysInMonth = 30;
    else if (month == 2)
        daysInMonth = (leapYear) ? 29 : 28;
    else
        daysInMonth = 31;
    return daysInMonth;
}

// to check a year is leap or not
private boolean checkLeap(int year) {
    Calendar cal = Calendar.getInstance();
    cal.set(Calendar.YEAR, year);
    return cal.getActualMaximum(Calendar.DAY_OF_YEAR) > 365;
}

0

यहाँ मैं तारीख प्रारूप की जाँच करेगा:

 public static boolean checkFormat(String dateTimeString) {
    return dateTimeString.matches("^\\d{4}-\\d{2}-\\d{2}") || dateTimeString.matches("^\\d{4}-\\d{2}-\\d{2}\\s\\d{2}:\\d{2}:\\d{2}")
            || dateTimeString.matches("^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}") || dateTimeString
            .matches("^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}Z") ||
            dateTimeString.matches("^\\d{4}-\\d{2}-\\d{2}\\s\\d{2}:\\d{2}:\\d{2}Z");
}

इस काम के लिए हमारे पास आधुनिक जावा.टाइम कक्षाएं हैं। जटिल रेगेक्स लिखना आपके समय का सबसे अच्छा उपयोग होने की संभावना नहीं है। मेरे उत्तर में वन-लाइनर देखें ।
बेसिल बोर्क

0
        public static String detectDateFormat(String inputDate, String requiredFormat) {
        String tempDate = inputDate.replace("/", "").replace("-", "").replace(" ", "");
        String dateFormat;

        if (tempDate.matches("([0-12]{2})([0-31]{2})([0-9]{4})")) {
            dateFormat = "MMddyyyy";
        } else if (tempDate.matches("([0-31]{2})([0-12]{2})([0-9]{4})")) {
            dateFormat = "ddMMyyyy";
        } else if (tempDate.matches("([0-9]{4})([0-12]{2})([0-31]{2})")) {
            dateFormat = "yyyyMMdd";
        } else if (tempDate.matches("([0-9]{4})([0-31]{2})([0-12]{2})")) {
            dateFormat = "yyyyddMM";
        } else if (tempDate.matches("([0-31]{2})([a-z]{3})([0-9]{4})")) {
            dateFormat = "ddMMMyyyy";
        } else if (tempDate.matches("([a-z]{3})([0-31]{2})([0-9]{4})")) {
            dateFormat = "MMMddyyyy";
        } else if (tempDate.matches("([0-9]{4})([a-z]{3})([0-31]{2})")) {
            dateFormat = "yyyyMMMdd";
        } else if (tempDate.matches("([0-9]{4})([0-31]{2})([a-z]{3})")) {
            dateFormat = "yyyyddMMM";
        } else {
            return "Pattern Not Added";
//add your required regex
        }
        try {
            String formattedDate = new SimpleDateFormat(requiredFormat, Locale.ENGLISH).format(new SimpleDateFormat(dateFormat).parse(tempDate));

            return formattedDate;
        } catch (Exception e) {
            //
            return "";
        }

    }

0

Result विरासत ’तिथि प्रारूप के साथ, हम परिणाम को प्रारूपित कर सकते हैं और स्रोत से इसकी तुलना कर सकते हैं।

    public boolean isValidFormat(String source, String pattern) {
    SimpleDateFormat sd = new SimpleDateFormat(pattern);
    sd.setLenient(false);
    try {
        Date date = sd.parse(source);
        return date != null && sd.format(date).equals(source);
    } catch (Exception e) {
        return false;
    }
}

यह क्रियान्वयन स्रोत को 'झूठा' कहता है = 01.01.04 पैटर्न '01 .01.2004 'के साथ


-1

यदि आप एक सख्त सत्यापन पसंद करते हैं तो झूठा

public boolean isThisDateValid(String dateToValidate, String dateFromat){

    if(dateToValidate == null){
        return false;
    }

    SimpleDateFormat sdf = new SimpleDateFormat(dateFromat);
    sdf.setLenient(false);

    try {

        //if not valid, it will throw ParseException
        Date date = sdf.parse(dateToValidate);
        System.out.println(date);

    } catch (ParseException e) {

        e.printStackTrace();
        return false;
    }

    return true;
}
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.