नए दिनांक समय API का उपयोग करके एक दिनांक प्रारूपित करें


118

मैं नई तारीख समय एपीआई के साथ खेल रहा था लेकिन जब यह चल रहा था:

public class Test {         
    public static void main(String[] args){
        String dateFormatted = LocalDate.now()
                                        .format(DateTimeFormatter
                                              .ofPattern("yyyy-MM-dd HH:mm:ss"));
        System.out.println(dateFormatted);
    }
}

यह फेंकता है:

Exception in thread "main" java.time.temporal.UnsupportedTemporalTypeException: Unsupported field: HourOfDay
    at java.time.LocalDate.get0(LocalDate.java:680)
    at java.time.LocalDate.getLong(LocalDate.java:659)
    at java.time.format.DateTimePrintContext.getValue(DateTimePrintContext.java:298)
    at java.time.format.DateTimeFormatterBuilder$NumberPrinterParser.format(DateTimeFormatterBuilder.java:2543)
    at java.time.format.DateTimeFormatterBuilder$CompositePrinterParser.format(DateTimeFormatterBuilder.java:2182)
    at java.time.format.DateTimeFormatter.formatTo(DateTimeFormatter.java:1745)
    at java.time.format.DateTimeFormatter.format(DateTimeFormatter.java:1719)
    at java.time.LocalDate.format(LocalDate.java:1685)
    at Test.main(Test.java:23)

जब मैं LocalDate वर्ग के स्रोत कोड को देख रहा हूं, तो मैं देखता हूं:

  private int get0(TemporalField field) {
        switch ((ChronoField) field) {
            case DAY_OF_WEEK: return getDayOfWeek().getValue();
            case ALIGNED_DAY_OF_WEEK_IN_MONTH: return ((day - 1) % 7) + 1;
            case ALIGNED_DAY_OF_WEEK_IN_YEAR: return ((getDayOfYear() - 1) % 7) + 1;
            case DAY_OF_MONTH: return day;
            case DAY_OF_YEAR: return getDayOfYear();
            case EPOCH_DAY: throw new UnsupportedTemporalTypeException("Invalid field 'EpochDay' for get() method, use getLong() instead");
            case ALIGNED_WEEK_OF_MONTH: return ((day - 1) / 7) + 1;
            case ALIGNED_WEEK_OF_YEAR: return ((getDayOfYear() - 1) / 7) + 1;
            case MONTH_OF_YEAR: return month;
            case PROLEPTIC_MONTH: throw new UnsupportedTemporalTypeException("Invalid field 'ProlepticMonth' for get() method, use getLong() instead");
            case YEAR_OF_ERA: return (year >= 1 ? year : 1 - year);
            case YEAR: return year;
            case ERA: return (year >= 1 ? 1 : 0);
        }
        throw new UnsupportedTemporalTypeException("Unsupported field: " + field);
    }

जैसा कि यह डॉक्टर में वर्णित है:

यह विधि वर्णों और प्रतीकों के एक साधारण पैटर्न के आधार पर एक फॉर्मेटर बनाएगी जैसा कि कक्षा प्रलेखन में वर्णित है।

और ये सभी अक्षर परिभाषित हैं

तो क्यों DateTimeFormatter.ofPatternहम कुछ पैटर्न पत्र का उपयोग करने की अनुमति नहीं देता है?

जवाबों:


219

LocalDateकेवल दिनांक का प्रतिनिधित्व करता है, दिनांक का नहीं। इसलिए "HH: mm: ss" फॉर्मेट करते समय कोई मतलब नहीं रखता है LocalDateLocalDateTimeइसके बजाय, यह सुनिश्चित करें कि आप एक तिथि और समय दोनों का प्रतिनिधित्व करना चाहते हैं।


3
मैं इस उत्तर को कैसे बढ़ा सकता हूं और इस तथ्य को कम कर सकता हूं कि लोकलडेट और लोकलडेटेट ऑब्जेक्ट दोनों हैं ...
एक्सलिस

मैं सिर्फ LocalTime के साथ काम करना चाहूँगा, आप इस अपवाद में भागे बिना कैसे फॉर्मेटिंग कर सकते हैंjava.time.temporal.UnsupportedTemporalTypeException: Unsupported field: DayOfWeek
samuel owino

कोई बात नहीं: यह काम करता हैDateTimeFormatter.ofPattern("HH:mm:ss")
samuel Owino

36

मैं @James_D के सही उत्तर के लिए निम्नलिखित विवरण जोड़ना चाहूंगा:

पृष्ठभूमि: अधिकांश दिनांक-और-समय-पुस्तकालय ( java.util.Calendarजावा में, यह भी देखें। नेट-डेटटाइम या Dateजावास्क्रिप्ट या DateTimeपर्ल में) एक सार्वभौमिक सर्व-उद्देश्य अद्वितीय लौकिक प्रकार की अवधारणा पर आधारित हैं (जर्मन में काव्य अभिव्यक्ति है) eierlegende Wollmilchsau ")। इस डिज़ाइन में असमर्थित फ़ील्ड नहीं हो सकता है। लेकिन कीमत अधिक है: कई बार समस्याओं को इस तरह के अनम्य दृष्टिकोण के साथ पर्याप्त रूप से नियंत्रित नहीं किया जा सकता है क्योंकि सभी प्रकार की लौकिक वस्तुओं के लिए एक सामान्य भाजक को खोजना असंभव है।

JSR-310 ने एक और तरीका चुना है , अर्थात् अलग-अलग लौकिक प्रकारों की अनुमति देने के लिए जो समर्थित अंतर्निहित फ़ील्ड्स के प्रकार-विशिष्ट सेटों से मिलकर होते हैं। स्वाभाविक परिणाम यह है कि हर प्रकार के संभावित क्षेत्र को हर प्रकार से समर्थन नहीं मिलता है (और उपयोगकर्ता अपने स्वयं के विशेष क्षेत्रों को भी परिभाषित कर सकते हैं)। यह समर्थित फ़ील्ड के विशिष्ट सेट के लिए प्रोग्राम के प्रत्येक ऑब्जेक्ट को प्रोग्रामेटिक रूप से पूछना भी संभव है TemporalAccessor। के लिए LocalDateहम पाते हैं:

DAY_OF_WEEK 
ALIGNED_DAY_OF_WEEK_IN_MONTH 
ALIGNED_DAY_OF_WEEK_IN_YEAR 
DAY_OF_MONTH 
DAY_OF_YEAR 
EPOCH_DAY 
ALIGNED_WEEK_OF_MONTH 
ALIGNED_WEEK_OF_YEAR 
MONTH_OF_YEAR 
PROLEPTIC_MONTH 
YEAR_OF_ERA 
YEAR 
ERA 

कोई HOUR_OF_DAY- फ़ील्ड नहीं है जो की समस्या की व्याख्या करता है UnsupportedTemporalTypeException। और यदि हम JSR-310- पैटर्न प्रतीकों के मानचित्रण को ऐसे क्षेत्रों में देखते हैं, जो देखते हैं कि प्रतीक H को असमर्थित HOUR_OF_DAY के लिए मैप किया गया है:

/** Map of letters to fields. */  
private static final Map<Character, TemporalField> FIELD_MAP = new HashMap<>();
static {
  FIELD_MAP.put('G', ChronoField.ERA);
  FIELD_MAP.put('y', ChronoField.YEAR_OF_ERA);
  FIELD_MAP.put('u', ChronoField.YEAR);
  FIELD_MAP.put('Q', IsoFields.QUARTER_OF_YEAR);
  FIELD_MAP.put('q', IsoFields.QUARTER_OF_YEAR);
  FIELD_MAP.put('M', ChronoField.MONTH_OF_YEAR);
  FIELD_MAP.put('L', ChronoField.MONTH_OF_YEAR);
  FIELD_MAP.put('D', ChronoField.DAY_OF_YEAR);
  FIELD_MAP.put('d', ChronoField.DAY_OF_MONTH);
  FIELD_MAP.put('F', ChronoField.ALIGNED_DAY_OF_WEEK_IN_MONTH);
  FIELD_MAP.put('E', ChronoField.DAY_OF_WEEK);
  FIELD_MAP.put('c', ChronoField.DAY_OF_WEEK);
  FIELD_MAP.put('e', ChronoField.DAY_OF_WEEK);
  FIELD_MAP.put('a', ChronoField.AMPM_OF_DAY);
  FIELD_MAP.put('H', ChronoField.HOUR_OF_DAY);
  FIELD_MAP.put('k', ChronoField.CLOCK_HOUR_OF_DAY);
  FIELD_MAP.put('K', ChronoField.HOUR_OF_AMPM);
  FIELD_MAP.put('h', ChronoField.CLOCK_HOUR_OF_AMPM);
  FIELD_MAP.put('m', ChronoField.MINUTE_OF_HOUR);
  FIELD_MAP.put('s', ChronoField.SECOND_OF_MINUTE);
  FIELD_MAP.put('S', ChronoField.NANO_OF_SECOND);
  FIELD_MAP.put('A', ChronoField.MILLI_OF_DAY);
  FIELD_MAP.put('n', ChronoField.NANO_OF_SECOND);
  FIELD_MAP.put('N', ChronoField.NANO_OF_DAY);    
}

इस फ़ील्ड मैपिंग का मतलब यह नहीं है कि फ़ील्ड कंक्रीट प्रकार द्वारा समर्थित है। पार्सिंग कई चरणों में होता है। फ़ील्ड मैपिंग केवल पहला चरण है। दूसरा चरण फिर प्रकार की एक कच्ची वस्तु के लिए पार्सिंग है TemporalAccessor। और अंत में टार्गेट टाइप (यहाँ:) को डेलिगेट करते हैं LocalDateऔर यह तय करते हैं कि यह पार्स इंटरमीडिएट ऑब्जेक्ट में सभी फील्ड वैल्यूज़ को स्वीकार करता है या नहीं।


4
en.wiktionary.org/wiki/eierlegende_Wollmilchsau (शाब्दिक रूप से "अंडे देने वाला ऊन-दूध-बोना") एक ऐसा सभी उपकरण या व्यक्ति जिसके पास (या दावा है कि केवल सकारात्मक गुण हैं और जो कर सकते हैं या (या प्रयास कर सकते हैं) कई विशेष उपकरणों का काम करते हैं। :-)
ट्रेवर रॉबिन्सन

6

मेरे लिए सही क्लास थी ZonedDateTimeजिसमें टाइम और टाइम ज़ोन दोनों शामिल थे।

LocalDateआपके पास समय की जानकारी नहीं है इसलिए आपको ए UnsupportedTemporalTypeException: Unsupported field: HourOfDay

आप उपयोग कर सकते हैं, LocalDateTimeलेकिन तब आपके पास टाइम ज़ोन की जानकारी नहीं होती है, इसलिए यदि आप उस तक पहुँचने की कोशिश करते हैं (यहां तक ​​कि पूर्वनिर्धारित प्रारूपकों में से एक का उपयोग करके) आपको ए UnsupportedTemporalTypeException: Unsupported field: OffsetSeconds

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