Java.util.Date को दिनांक स्ट्रिंग पार्स करते समय अवैध पैटर्न चरित्र 'T'


181

मेरे पास एक तारीख स्ट्रिंग है और मैं इसे सामान्य तिथि तक जावा तिथि एपीआई का उपयोग करने के लिए पार्स करना चाहता हूं, निम्नलिखित मेरा कोड है:

public static void main(String[] args) {
    String date="2010-10-02T12:23:23Z";
    String pattern="yyyy-MM-ddThh:mm:ssZ";
    SimpleDateFormat sdf=new SimpleDateFormat(pattern);
    try {
        Date d=sdf.parse(date);
        System.out.println(d.getYear());
    } catch (ParseException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
}

हालाँकि मुझे एक अपवाद मिला: java.lang.IllegalArgumentException: Illegal pattern character 'T'

तो मुझे आश्चर्य है कि क्या मुझे स्ट्रिंग को विभाजित करना होगा और इसे मैन्युअल रूप से पार्स करना होगा?

BTW, मैंने T के दोनों ओर एक एकल उद्धरण वर्ण जोड़ने की कोशिश की है:

String pattern="yyyy-MM-dd'T'hh:mm:ssZ";

यह भी काम नहीं करता है।


1
क्या आप जानते हैं कि इस "टी" का क्या अर्थ है? जहां तक ​​मुझे लगता है कि 'टी' के साथ-साथ पूरी तारीख को डेट में बदल दिया जाना चाहिए (इसे 'सिंगल कोट्स' के माध्यम से नहीं
छोड़ना चाहिए

9
Tके लिए खड़ा है समय और का हिस्सा है ISO8601 अंतर्राष्ट्रीय दिनांक समय फ़ॉर्मेट करने के लिए मानक।

1
अजीब है कि। Tएकल उद्धरणों में लपेटकर मेरे लिए काम किया (कम से कम पार्स त्रुटि को हल करने के मामले में)।
एजी हैमर्थीफ

जवाबों:


203

जावा 8 और उच्चतर के लिए अद्यतन

आप अब बस कर सकते हैं Instant.parse("2015-04-28T14:23:38.521Z")और अब सही चीज़ प्राप्त कर सकते हैं , खासकर जब से आप जावा के सबसे हाल के संस्करणों के साथ Instantटूटने के बजाय उपयोग करना चाहिए java.util.Date

आपको DateTimeFormatterइसके बजाय उपयोग करना चाहिए SimpleDateFormatter

मूल उत्तर:

नीचे दिया गया विवरण अभी भी मान्य है कि प्रारूप क्या दर्शाता है। लेकिन यह जावा 8 के सर्वव्यापी होने से पहले लिखा गया था इसलिए यह पुरानी कक्षाओं का उपयोग करता है जो कि आप जावा 8 या उच्चतर का उपयोग नहीं कर रहे हैं।

यह अनुगामी के साथ इनपुट के साथ काम करता है Zके रूप में प्रदर्शन किया:

पैटर्न में दोनों तरफ Tसे बच जाता है '

Zअंत में पैटर्न के लिए वास्तव XXXमें JavaDoc में प्रलेखित किया गया है SimpleDateFormat, यह वास्तव में बहुत स्पष्ट नहीं है कि इसका उपयोग कैसे करें क्योंकि यह Zपुरानी TimeZoneजानकारी के लिए भी मार्कर है ।

Q2597083.java

import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.TimeZone;

public class Q2597083
{
    /**
     * All Dates are normalized to UTC, it is up the client code to convert to the appropriate TimeZone.
     */
    public static final TimeZone UTC;

    /**
     * @see <a href="http://en.wikipedia.org/wiki/ISO_8601#Combined_date_and_time_representations">Combined Date and Time Representations</a>
     */
    public static final String ISO_8601_24H_FULL_FORMAT = "yyyy-MM-dd'T'HH:mm:ss.SSSXXX";

    /**
     * 0001-01-01T00:00:00.000Z
     */
    public static final Date BEGINNING_OF_TIME;

    /**
     * 292278994-08-17T07:12:55.807Z
     */
    public static final Date END_OF_TIME;

    static
    {
        UTC = TimeZone.getTimeZone("UTC");
        TimeZone.setDefault(UTC);
        final Calendar c = new GregorianCalendar(UTC);
        c.set(1, 0, 1, 0, 0, 0);
        c.set(Calendar.MILLISECOND, 0);
        BEGINNING_OF_TIME = c.getTime();
        c.setTime(new Date(Long.MAX_VALUE));
        END_OF_TIME = c.getTime();
    }

    public static void main(String[] args) throws Exception
    {

        final SimpleDateFormat sdf = new SimpleDateFormat(ISO_8601_24H_FULL_FORMAT);
        sdf.setTimeZone(UTC);
        System.out.println("sdf.format(BEGINNING_OF_TIME) = " + sdf.format(BEGINNING_OF_TIME));
        System.out.println("sdf.format(END_OF_TIME) = " + sdf.format(END_OF_TIME));
        System.out.println("sdf.format(new Date()) = " + sdf.format(new Date()));
        System.out.println("sdf.parse(\"2015-04-28T14:23:38.521Z\") = " + sdf.parse("2015-04-28T14:23:38.521Z"));
        System.out.println("sdf.parse(\"0001-01-01T00:00:00.000Z\") = " + sdf.parse("0001-01-01T00:00:00.000Z"));
        System.out.println("sdf.parse(\"292278994-08-17T07:12:55.807Z\") = " + sdf.parse("292278994-08-17T07:12:55.807Z"));
    }
}

निम्नलिखित उत्पादन करता है:

sdf.format(BEGINNING_OF_TIME) = 0001-01-01T00:00:00.000Z
sdf.format(END_OF_TIME) = 292278994-08-17T07:12:55.807Z
sdf.format(new Date()) = 2015-04-28T14:38:25.956Z
sdf.parse("2015-04-28T14:23:38.521Z") = Tue Apr 28 14:23:38 UTC 2015
sdf.parse("0001-01-01T00:00:00.000Z") = Sat Jan 01 00:00:00 UTC 1
sdf.parse("292278994-08-17T07:12:55.807Z") = Sun Aug 17 07:12:55 UTC 292278994

26

tl; डॉ

java.time.InstantUTC में एक पल का प्रतिनिधित्व करते हुए, मानक ISO 8601 प्रारूप में पाठ को पार्स करने के लिए कक्षा का उपयोग करें ।

Instant.parse( "2010-10-02T12:23:23Z" )

आईएसओ 8601

उस प्रारूप को तारीख-समय के स्ट्रिंग स्वरूपों के लिए आईएसओ 8601 मानक द्वारा परिभाषित किया गया है

दोनों:

... आईएसओ 8601 स्वरूपों का उपयोग डिफ़ॉल्ट रूप से पार्स करने और स्ट्रिंग उत्पन्न करने के लिए किया जाता है।

आपको आम तौर पर पुराने java.util.Date /.Calendar & java.text.SimpleDateFormat कक्षाओं का उपयोग करने से बचना चाहिए क्योंकि वे कुख्यात परेशान, भ्रमित और त्रुटिपूर्ण हैं। यदि इंटरऑपरेटिंग के लिए आवश्यक है, तो आप इसे मेंढक में बदल सकते हैं।

java.time

जावा 8 में निर्मित और बाद में नया जावा.टाइम फ्रेमवर्क है। जेएसआर 310 द्वारा परिभाषित, जोडा-टाइम से प्रेरित और थ्रीटेन-एक्स्ट्रा प्रोजेक्ट द्वारा विस्तारित ।

Instant instant = Instant.parse( "2010-10-02T12:23:23Z" );  // `Instant` is always in UTC.

पुरानी कक्षा में परिवर्तित करें।

java.util.Date date = java.util.Date.from( instant );  // Pass an `Instant` to the `from` method.

समय क्षेत्र

यदि आवश्यक हो, तो आप एक समय क्षेत्र असाइन कर सकते हैं।

ZoneId zoneId = ZoneId.of( "America/Montreal" ); // Define a time zone rather than rely implicitly on JVM’s current default time zone.
ZonedDateTime zdt = ZonedDateTime.ofInstant( instant , zoneId );  // Assign a time zone adjustment from UTC.

कनवर्ट करें।

java.util.Date date = java.util.Date.from( zdt.toInstant() );  // Extract an `Instant` from the `ZonedDateTime` to pass to the `from` method.

Joda समय

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

यहाँ कुछ उदाहरण कोड Joda-Time 2.8 में है।

org.joda.time.DateTime dateTime_Utc = new DateTime( "2010-10-02T12:23:23Z" , DateTimeZone.UTC );  // Specifying a time zone to apply, rather than implicitly assigning the JVM’s current default.

पुरानी कक्षा में परिवर्तित करें। ध्यान दें कि निर्धारित समय क्षेत्र रूपांतरण में खो गया है, क्योंकि juate को समय क्षेत्र नहीं सौंपा जा सकता है।

java.util.Date date = dateTime_Utc.toDate(); // The `toDate` method converts to old class.

समय क्षेत्र

यदि आवश्यक हो, तो आप एक समय क्षेत्र असाइन कर सकते हैं।

DateTimeZone zone = DateTimeZone.forID( "America/Montreal" );
DateTime dateTime_Montreal = dateTime_Utc.withZone ( zone );

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


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

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

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

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

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

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

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

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


1
@AalapPatel ध्यान रखें कि जोडा-टाइम परियोजना अब रखरखाव मोड में है। टीम java.time कक्षाओं में प्रवास की सलाह देती है। दोनों प्रयासों का नेतृत्व एक ही आदमी, स्टीफन कोलबोर्न कर रहे हैं।
तुलसी बोर्क

धन्यवाद, मैं इसे यूटीसी समय और / या स्थानीय समय से लौटाए गए सर्वर से मिलिसेकंड प्राप्त करने के लिए उपयोग करता हूं और इस मामले में मेरे लिए अच्छी तरह से काम करता है ..
आलाप पटेल

Instant.parse को android में min api level 26 की जरूरत है
Naveed Ahmad

1
@NaveedAhmad थ्रीटेन-बैकपोर्ट और थ्रीटेनाब परियोजनाओं के बारे में उत्तर के नीचे से गोलियां देखें ।
तुलसी बोरक

0

ऊपर-से-अब दो उत्तर हैं और वे दोनों लंबे (और टीएल; ड्र ; बहुत कम आईएमएचओ) हैं, इसलिए मैं अपने अनुभव से सारांश लिखता हूं नए java.time लाइब्रेरी का उपयोग करना शुरू करना (जैसा कि जावा संस्करण के अन्य उत्तरों में उल्लेखित है) 8)। आईएसओ 8601 दिनांक लिखने का मानक तरीका निर्धारित करता है: YYYY-MM-DDइसलिए दिनांक-समय का प्रारूप नीचे के रूप में है (मिलिसेकंड के लिए 0, 3, 6 या 9 अंक हो सकता है) और कोई प्रारूपण स्ट्रिंग आवश्यक नहीं है:

import java.time.Instant;
public static void main(String[] args) {
    String date="2010-10-02T12:23:23Z";
    try {
        Instant myDate = Instant.parse(date);
    } catch (ParseException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
}

मुझे इसकी आवश्यकता नहीं थी, लेकिन जैसा कि वर्ष प्रश्न से कोड में है, तब:
यह मुश्किल है, Instantसीधे से नहीं किया जा सकता है Calendar, सवालों के माध्यम से किया जा सकता है जावा और कन्वर्जिंग जावा में वर्तमान वर्ष के पूर्णांक मान प्राप्त करें । कैलेंडर का समय लेकिन प्रारूप तय होने के कारण IMHO का उपयोग करना अधिक सरल है:

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