2014-10-15 10 views
10

करने के लिए नए जावा 8 डेटटाइमफॉर्मेटर का उपयोग करना मुझे एक साधारण समस्या है: मैं जावा स्ट्रिंग को "yyyyMMdd" प्रारूप में पार्स करना चाहता हूं, ताकि "19800229" मान्य दिनांक हो, लेकिन "19820229" नहीं है। मान लें कि ये सामान्य ग्रेगोरियन कैलेंडर से एडी तिथियां हैं।सख्त तारीख पार्सिंग

मैं इस समस्या को हल करने के लिए जेडीके 8 से नए java.time पैकेज का उपयोग करने की कोशिश कर रहा हूं, लेकिन यह आशा से अधिक जटिल साबित हो रहा है। मेरे वर्तमान कोड है:

private static final DateTimeFormatter FORMAT = DateTimeFormatter 
     .ofPattern("yyyyMMdd").withChronology(IsoChronology.INSTANCE) 
     .withResolverStyle(STRICT); 

public static LocalDate parse(String yyyyMMdd) { 
    return LocalDate.parse(yyyyMMdd, FORMAT); 
} 

हालांकि, इस तरह के रूप में "19,800,228" पैदा करता है कि मुझे क्या करने के लिए एक समझ से बाहर त्रुटि है कोई मान्य दिनांक को पार्स:

java.time.format.DateTimeParseException: Text '19820228' could not be parsed: Unable to obtain LocalDate from TemporalAccessor: {MonthOfYear=2, DayOfMonth=28, YearOfEra=1982},ISO of type java.time.format.Parsed

मैं java.time.format.DateTimeFormatter का उपयोग अपने सरल उपयोग के मामले को सुलझाने के लिए है ?

उत्तर

2

मैं संपादित करने के लिए संपादन कर रहा हूं कि किस प्रकार की स्ट्रिंग को डेटटाइमफॉर्मेटरबिल्डर के साथ बनाए गए कस्टम फॉर्मेटर का उपयोग करके मान्य माना जाएगा।

public class DateFormmaterTest { 

    static DateTimeFormatter CUSTOM_BASIC_ISO_DATE = new DateTimeFormatterBuilder() 
      .parseCaseInsensitive().appendValue(YEAR, 4) 
      .appendValue(MONTH_OF_YEAR, 2).appendValue(DAY_OF_MONTH, 2) 
      .optionalStart().toFormatter() 
      .withResolverStyle(ResolverStyle.STRICT) 
      .withChronology(IsoChronology.INSTANCE); 

    public static void main(String[] args) { 

     LocalDate date1 = LocalDate.parse("19800228-5000", 
       CUSTOM_BASIC_ISO_DATE); 

     System.out.println(date1); 

    } 
} 

2/29/1982 अमान्य है और फेंक निम्नलिखित:

Caused by: java.time.DateTimeException: Invalid date 'February 29' as '1982' is not a leap year 
    at java.time.LocalDate.create(LocalDate.java:429) 

19800228-5000 की तारीख BASIC_ISO_DATE साथ काम करेगा, क्योंकि यह वैकल्पिक ऑफसेट आप अनुमति नहीं चाहते जो की अनुमति देता है । मेरे CUSTOM_BASIC_ISO_DATE फ़ॉर्मेटर कि अनुमति नहीं दी जाएगी और निम्नलिखित फेंक:

Exception in thread "main" java.time.format.DateTimeParseException: Text '19800228-5000' could not be parsed, unparsed text found at index 8. 

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

+0

धन्यवाद @ टेक यात्रा। क्षमा करें, मेरा मतलब है कि दोनों मामलों में 2/2 9, जैसा कि आपने बताया था। 'DateTimeFormatter.BASIC_ISO_DATE' से बचने का कारण यह है कि इसका एक वैकल्पिक हिस्सा है कि मैं पारदर्शी नहीं होना चाहता हूं। क्या मैं वैकल्पिक भाग के बिना समकक्ष फॉर्मेटर बना सकता हूं? – 0xbe5077ed

+0

मैंने आपकी आखिरी टिप्पणी को ध्यान में रखते हुए जवाब में संशोधन किया। कृपया इसे देखो! – TechTrip

+0

काफी अच्छा, @ टेक ट्रिप। यही मैंने भी खोजा। ध्यान दें कि आप 'parseCaseInsensitive()' - अनावश्यक को बंद कर सकते हैं क्योंकि yyyyMMdd में कोई केस समस्या नहीं है - और 'startOptional()' क्योंकि आप कुछ भी वैकल्पिक नहीं शुरू कर रहे हैं। – 0xbe5077ed

1

इसके बजाय प्रारूप "uuuuMMdd" का उपयोग करने का प्रयास करें।

12

जावा 8 वर्ष के लिए uuuu का उपयोग करता है, yyyy नहीं। जावा 8 में, yyyy का मतलब है "युग का वर्ष" (बीसी या एडी) और त्रुटि संदेश शिकायत करता है कि MonthOfYear, DayOfMonth और YearOfEra तारीख बनाने के लिए पर्याप्त जानकारी नहीं है क्योंकि युग ज्ञात नहीं है।

इसे ठीक करने के लिए, अपने प्रारूप स्ट्रिंग में uuuu का उपयोग करें, उदा। DateTimeFormatter.ofPattern("uuuuMMdd")

या, यदि आप yyyy का उपयोग करना जारी रखना चाहते हैं, तो आप डिफ़ॉल्ट युग सेट कर सकते हैं, उदा।

new DateTimeFormatterBuilder() 
     .appendPattern("yyyyMMdd") 
     .parseDefaulting(ChronoField.ERA, 1 /* era is AD */) 
     .toFormatter() 
संबंधित मुद्दे