2014-05-06 12 views
8

मेरा प्रोग्राम LocalDate ऑब्जेक्ट में इनपुट स्ट्रिंग को पार्स कर रहा है। ज्यादातर समय स्ट्रिंग 30.03.2014 जैसा दिखता है, लेकिन कभी-कभी यह 3/30/2014 जैसा दिखता है। जिसके आधार पर, मुझे DateTimeFormatter.ofPattern(String pattern) पर कॉल करने के लिए एक अलग पैटर्न का उपयोग करने की आवश्यकता है। असल में, मुझे यह जांचने की आवश्यकता है कि स्ट्रिंग पार्सिंग करने से पहले पैटर्न dd.MM.yyyy या M/dd/yyyy से मेल खाती है या नहीं।टाइम एपीआई का उपयोग कर स्ट्रिंग मैचों की तारीख पैटर्न को जांचने के लिए कैसे करें?

regex दृष्टिकोण होगा कुछ की तरह:

LocalDate date; 
if (dateString.matches("^\\d?\\d/\\d{2}/\\d{4}$")) { 
    date = LocalDate.parse(dateString, DateTimeFormatter.ofPattern("M/dd/yyyy")); 
} else { 
    date = LocalDate.parse(dateString, DateTimeFormatter.ofPattern("dd.MM.yyyy")); 
} 

यह काम करता है, लेकिन यह तारीख पैटर्न स्ट्रिंग जब स्ट्रिंग भी मिलान उपयोग करने के लिए अच्छा होगा।

क्या रीगाक्स मिलान का उपयोग किए बिना नए जावा 8 टाइम एपीआई के साथ ऐसा करने के लिए कोई मानक तरीका है? मैंने DateTimeFormatter के लिए दस्तावेज़ों में देखा है लेकिन मुझे कुछ भी नहीं मिला।

+0

क्यों आप 'प्रतिस्थापन' (// // ","। ") 'स्ट्रिंग नहीं करते हैं? –

+0

मुझे नहीं लगता कि यह निर्धारित करने के लिए एक विशिष्ट विधि है कि कोई दिनांक किसी दिए गए पैटर्न का पालन करता है या नहीं। मैं SimpleDateFormat.parse विधि का उपयोग करता हूं और ParseException की जांच करता हूं। यदि आप सुनिश्चित हैं कि तिथि सही है और यह दो पैटर्न में से एक में है, तो आप जांच सकते हैं कि '।' स्ट्रिंग में – maxvv

+2

@RobertNiestroj क्योंकि महीने और दिन दोनों पैटर्न में एक ही स्थान पर नहीं हैं। –

उत्तर

8

ठीक है मैं आगे बढ़ रहा हूं और इसे उत्तर के रूप में पोस्ट कर रहा हूं। एक तरीका वह वर्ग बनाना है जो पैटर्न रखेगा।

public class Test { 
    public static void main(String[] args){ 
     MyFormatter format = new MyFormatter("dd.MM.yyyy", "M/dd/yyyy"); 
     LocalDate date = format.parse("3/30/2014"); //2014-03-30 
     LocalDate date2 = format.parse("30.03.2014"); //2014-03-30 
    } 
} 

class MyFormatter { 
    private final String[] patterns; 

    public MyFormatter(String... patterns){ 
     this.patterns = patterns; 
    } 

    public LocalDate parse(String text){ 
     for(int i = 0; i < patterns.length; i++){ 
      try{ 
       return LocalDate.parse(text, DateTimeFormatter.ofPattern(patterns[i])); 
      }catch(DateTimeParseException excep){} 
     } 
     throw new IllegalArgumentException("Not able to parse the date for all patterns given"); 
    } 
} 

आप इस में सुधार के रूप में @MenoHochschild सीधे String की सरणी आप निर्माता में पास से DateTimeFormatter की एक सरणी बनाने के द्वारा किया जा सकता था।


एक और तरीका है एक DateTimeFormatterBuilder उपयोग करने के लिए, प्रारूपों आप चाहते हैं जोड़कर किया जाएगा। ऐसा करने के कुछ अन्य तरीके मौजूद हो सकते हैं, मैं दस्तावेज़ीकरण के माध्यम से गहराई से नहीं गया :-)

DateTimeFormatter dfs = new DateTimeFormatterBuilder() 
          .appendOptional(DateTimeFormatter.ofPattern("yyyy-MM-dd"))                 
          .appendOptional(DateTimeFormatter.ofPattern("dd.MM.yyyy"))                      
          .toFormatter(); 
LocalDate d = LocalDate.parse("2014-05-14", dfs); //2014-05-14 
LocalDate d2 = LocalDate.parse("14.05.2014", dfs); //2014-05-14 
0

@ZouZou का दृष्टिकोण एक संभावित समाधान है।

क्रम कार्यक्रम तर्क के लिए अपवाद का उपयोग कर से बचने के लिए जितना हो (यह भी बहुत अच्छा performancewise नहीं) निम्नलिखित alternative माना जा सकता है के रूप में में:

static final String[] PATTERNS = {"dd.MM.yyyy", "M/dd/yyyy"}; 
static final DateTimeFormatter[] FORMATTERS = new DateTimeFormatter[PATTERNS.length]; 

static { 
    for (int i = 0; i < PATTERNS.length; i++) { 
    FORMATTERS[i] = DateTimeFormatter.ofPattern(PATTERNS[i]); 
    } 
} 

public static LocalDate parse(String input) { 
    ParsePosition pos = new ParsePosition(); 
    for (int i = 0; i < patterns.length; i++) { 
    try { 
     TemporalAccessor tacc = FORMATTERS[i].parseUnresolved(input, pos); 
     if (pos.getErrorIndex < 0) { 
     return LocalDate.from(tacc); // possibly throwing DateTimeException => validation failure 
     } 
    } catch (DateTimeException ex) { // catches also possible DateTimeParseException 
     // go to next pattern 
    } 
    pos.setIndex(0); 
    pos.setErrorIndex(-1); 
    } 
    throw new IllegalArgumentException("Input does not match any pattern: " + input); 
} 

विधि parseUnresolved() के बारे में अधिक विवरण:

यह विधि केवल पार्सिंग का पहला चरण है, इसलिए कोई दूसरा चरण नहीं है जिसमें प्रारंभिक सत्यापन या पार्स किए गए फ़ील्ड के प्रयास शामिल हैं। हालांकि, LocalDate.from() प्रत्येक इनपुट को मान्य करता है, इसलिए मुझे लगता है कि यह अभी भी पर्याप्त है। और लाभ यह है कि parseUnresolved()ParsePosition की त्रुटि अनुक्रमणिका का उपयोग करता है। यह परंपरागत java.text.Format -बेवियर के साथ समझौते में है।

दुर्भाग्य से वैकल्पिक और अधिक सहज ज्ञान युक्त विधि DateTimeFormater.parse() पहले DateTimeParseException बनाता है और फिर इस अपवाद में त्रुटि अनुक्रमणिका संग्रहीत करता है। तो मैंने एक अनावश्यक अपवाद के निर्माण से बचने के लिए इस विधि का उपयोग न करने का फैसला किया। मेरे लिए, यह एपीआई-विवरण एक संदिग्ध डिजाइन निर्णय है।

संबंधित मुद्दे