حرف نمط غير قانوني 't' عند تحليل سلسلة تاريخ إلى java.util.date

StackOverflow https://stackoverflow.com/questions/2597083

سؤال

لديّ سلسلة تاريخ وأريد تحليلها إلى التاريخ العادي ، استخدم واجهة برمجة تطبيقات تاريخ Java ، والما يلي هو رمزتي:

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'

لذلك أتساءل عما إذا كان عليّ تقسيم السلسلة وأحللها يدويًا؟

راجع للشغل ، لقد حاولت إضافة حرف اقتباس واحد على جانبي t:

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

كما أنه لا يعمل.

هل كانت مفيدة؟

المحلول

تحديث لجافا 8 وأعلى

يمكنك الآن القيام ببساطة Instant.parse("2015-04-28T14:23:38.521Z") واحصل على الشيء الصحيح الآن ، خاصة وأنك يجب أن تستخدم Instant بدلا من المكسور java.util.Date مع أحدث إصدارات جافا.

يجب أن تستخدم DateTimeFormatter بدلاً من SimpleDateFormatter أيضًا.

الإجابة الأصلية:

لا يزال التفسير أدناه صالحًا كما يمثل التنسيق. ولكن تم كتابتها قبل أن Java 8 كانت في كل مكان ، لذا فهي تستخدم الفئات القديمة التي يجب ألا تستخدمها إذا كنت تستخدم Java 8 أو أعلى.

هذا يعمل مع المدخلات مع Tralling Z كما هو مبين:

في النمط T هرب مع ' على أحد الجانبين.

نمط ل Z في النهاية في الواقع XXX كما هو موثق في جافادوك ل 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

نصائح أخرى

TL ؛ د

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

ISO 8601

يتم تعريف هذا التنسيق بواسطة ISO 8601 معيار لتنسيقات سلسلة الوقت.

كلاهما:

... استخدم تنسيقات ISO 8601 افتراضيًا لتحليل السلاسل وتوليدها.

يجب عليك عموما تجنب استخدام java.util.date القديم/. إذا لزم الأمر للتشغيل البيني ، يمكنك التحويل إلى جيئة وذهابا.

Java.Time

بنيت في Java 8 وبعد ذلك الجديد Java.Time إطار العمل. مستوحاة من وقت جودا, ، محددة من قبل JSR 310, ، وتمتد بواسطة Threeten-extra مشروع.

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-time هو الآن في وضع الصيانة. ينصح الفريق بالهجرة إلى 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.

تحويل إلى فئة قديمة. لاحظ أن المنطقة الزمنية المخصصة يتم فقدانها في التحويل ، حيث لا يمكن تعيين الحرف في منطقة زمنية.

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

ال Java.Time تم بناء إطار العمل في Java 8 وما بعده. هذه الفصول تحل محل القديم المزعج إرث فصول وقت التاريخ مثل java.util.Date, Calendar, & SimpleDateFormat.

ال وقت جودا مشروع ، الآن في نمط الصيانة, ، ينصح بالهجرة إلى Java.Time الطبقات.

لمعرفة المزيد ، انظر تعليمي أوراكل. والبحث في سعة مكدس للعديد من الأمثلة والتفسيرات. المواصفات JSR 310.

يمكنك التبادل Java.Time الكائنات مباشرة مع قاعدة البيانات الخاصة بك. إستخدم سائق JDBC متوافق مع JDBC 4.2 أو لاحقا. لا حاجة للسلاسل ، لا حاجة ل java.sql.* الطبقات.

من أين تحصل على فصول java.time؟

  • Java SE 8, Java SE 9, ، و لاحقا
    • مدمج.
    • جزء من واجهة برمجة تطبيقات Java القياسية مع تنفيذ مجمعة.
    • يضيف Java 9 بعض الميزات والإصلاحات البسيطة.
  • Java SE 6 و Java SE 7
    • يتم تشغيل الكثير من وظائف Java.time إلى Java 6 و 7 In Threeten-Backport.
  • ذكري المظهر
    • إصدارات لاحقة من تطبيقات حزمة Android لفصول Java.time.
    • لنظام Android في وقت سابق (<26) ، Threetenabp يتكيف المشروع Threeten-Backport (المذكور أعلاه). يرى كيفية استخدام threetenabp ....

ال Threeten-extra يمتد المشروع Java.time مع فصول إضافية. هذا المشروع هو أرضية إثبات للإضافات المستقبلية المحتملة إلى Java.time. قد تجد بعض الفصول المفيدة هنا مثل Interval, YearWeek, YearQuarter, ، و أكثر.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top