سؤال

هذا السؤال لديه بالفعل إجابة هنا:

أحاول تحليل موعد يشبه هذا:

2010-04-05T17:16:00Z

هذا تاريخ صالح لكل http://www.ietf.org/rfc/rfc3339.txt. يعني "Z" الحرفي "أن UTC هو النقطة المرجعية المفضلة للوقت المحدد."

إذا حاولت تحليله باستخدام SimpleDateFormat وهذا النمط:

yyyy-MM-dd'T'HH:mm:ss

سيتم تحليله على أنه الاثنين الاثنين 05 17:16:00 بتوقيت شرق الولايات المتحدة 2010

SimpleDateFormat غير قادر على تحليل السلسلة مع هذه الأنماط:

yyyy-MM-dd'T'HH:mm:ssz
yyyy-MM-dd'T'HH:mm:ssZ

يمكنني ضبط المنطقة الزمنية بشكل صريح لاستخدامها على SimpledAteFormat للحصول على الإخراج المتوقع ، لكنني لا أعتقد أن هذا يجب أن يكون ضروريًا. هل هناك شيء أفتقده؟ هل يوجد محلل بديل للتاريخ؟

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

المحلول

في النمط ، يشير إدراج مكون وقت "z" إلى أن تنسيق المنطقة الزمنية يحتاج إلى أن يتوافق مع المنطقة الزمنية العامة "المعيار" ، أمثلة عليها Pacific Standard Time; PST; GMT-08:00.

يشير A 'Z' إلى أن المنطقة الزمنية تتوافق مع RFC 822 المنطقة الزمنية المعيار ، على سبيل المثال -0800.

أعتقد أنك بحاجة إلى datatypeconverter ...

@Test
public void testTimezoneIsGreenwichMeanTime() throws ParseException {
    final Calendar calendar = javax.xml.bind.DatatypeConverter.parseDateTime("2010-04-05T17:16:00Z");
    TestCase.assertEquals("gotten timezone", "GMT+00:00", calendar.getTimeZone().getID());
}

نصائح أخرى

Java لا تحليل التواريخ ISO بشكل صحيح.

على غرار إجابة ماكنزي.

فقط إصلاح Z قبل التحليل.

شفرة

String string = "2013-03-05T18:05:05.000Z";
String defaultTimezone = TimeZone.getDefault().getID();
Date date = (new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ")).parse(string.replaceAll("Z$", "+0000"));

System.out.println("string: " + string);
System.out.println("defaultTimezone: " + defaultTimezone);
System.out.println("date: " + (new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ")).format(date));

نتيجة

string: 2013-03-05T18:05:05.000Z
defaultTimezone: America/New_York
date: 2013-03-05T13:05:05.000-0500

تاريخ التحليل هو في تنسيق ISO8601.

في Java 7 ، يجب قراءة النمط لقراءة وتطبيق لاحقة TimeZone yyyy-MM-dd'T'HH:mm:ssX

TL ؛ د

Instant.parse ( "2010-04-05T17:16:00Z" )

ISO 8601 معيار

تتوافق السلسلة الخاصة بك مع ISO 8601 المعيار (الذي ذكره RFC 3339 هو ملف تعريف).

تجنب الحرف

فصول java.util.date و .calendar المجمعة مع Java مزعجة للغاية. تجنبهم.

بدلا من ذلك استخدم إما وقت جودا مكتبة أو حزمة java.time الجديدة في Java 8. يستخدم كلا ISO 8601 كإعدادات افتراضية لتحليل وتوليد تمثيلات سلسلة وقت التاريخ.

Java.Time

ال Java.Time الإطار المدمج في Java 8 ويضرب لاحقًا فصول Java.util.date/.calendar المزعجة. الطبقات الجديدة مستوحاة من النجاح للغاية وقت جودا الإطار ، المقصود خلفه ، مماثل في المفهوم ولكن أعيد تصويره. حددها JSR 310. امتدت من قبل Threeten-extra مشروع. انظر درس تعليمي.

ال Instant يمثل الفصل في Java.time لحظة على الجدول الزمني في التوقيت العالمي وحدة زمنية.

ال Z في نهاية سلسلة الإدخال الخاصة بك يعني Zulu و التي تعني UTC. مثل هذه السلسلة يمكن تحليلها مباشرة بواسطة Instant الفصل ، مع عدم وجود حاجة لتحديد التنسيق.

String input = "2010-04-05T17:16:00Z";
Instant instant = Instant.parse ( input );

تفريغ إلى وحدة التحكم.

System.out.println ( "instant: " + instant );

اللحظة: 2010-04-05T17: 16: 00z

من هناك يمكنك تطبيق منطقة زمنية (ZoneId) لضبط هذا Instant الى ZonedDateTime. Search Stack Overflow للمناقشة والأمثلة.

إذا كان يجب عليك استخدام أ java.util.Date كائن ، يمكنك التحويل عن طريق استدعاء طرق التحويل الجديدة التي تمت إضافتها إلى الفئات القديمة مثل الطريقة الثابتة java.util.Date.from( Instant ).

java.util.Date date = java.util.Date.from( instant );

وقت جودا

مثال في Joda-time 2.5.

DateTimeZone timeZone = DateTimeZone.forID( "Europe/Paris" ):
DateTime dateTime = new DateTime( "2010-04-05T17:16:00Z", timeZone );

تحويل إلى UTC.

DateTime dateTimeUtc = dateTime.withZone( DateTimeZone.UTC );

تحويل إلى java.util.date إذا لزم الأمر.

java.util.Date date = dateTime.toDate();

وفقا للصف الأخير على أنماط التاريخ والوقت جدول Java 7 API

x Zone Zone ISO 8601 Zone -08 ؛ -0800 ؛ -08: 00

للمنطقة الزمنية ISO 8601 يجب استخدامك:

  • x لـ (-08 أو Z) ،
  • xx لـ (-0800 أو Z) ،
  • xxx لـ (-08: 00 أو Z) ؛

لذا ، لتحليل "2010-04-05T17: 16: 00z" يمكنك استخدام أيضًا "yyyy-mm-dd't'hh: mm: ssx" أو "yyyy-mm-dd't'hh: mm: ssxx" أو "yyyy-mm-dd't'h: mm: ssxxx" .

    System.out.println(new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssX").parse("2010-04-05T17:16:00Z"));
    System.out.println(new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssXX").parse("2010-04-05T17:16:00Z"));
    System.out.println(new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssXXX").parse("2010-04-05T17:16:00Z"));

سوف يطبع بشكل صحيح "الاثنين 05 أبريل 13:16:00 بتوقيت شرق الولايات المتحدة 2010"

يعمل "X" فقط إذا لم تكن الثواني الجزئية موجودة: أي نمط SimpleDateFormat

"yyyy-mm-dd't'hh: mm: ssx"

سوف تحليل بشكل صحيح

"2008-01-31T00: 00: 00Z"

لكن

"yyyy-mm-dd't'hh: mm: ss.sx"

لن تحليل

"2008-01-31T00: 00: 00.000Z"

حزين ولكن صحيح ، لا يبدو أن وقت الموعد مع الثواني الجزئية هو تاريخ ISO صالح: http://en.wikipedia.org/wiki/iso_8601

يجب أن تكون المنطقة الزمنية مثل "GMT+00: 00" أو 0000 حتى يتم تحليلها بشكل صحيح بواسطة SimpleDateFormat - يمكنك استبدال Z بهذا البناء.

يتضمن مشروع Restlet فئة InternetDateFormat يمكنها تحليل تواريخ RFC 3339.

Restlet InternetDateFormat

على الرغم من أنك قد ترغب فقط في استبدال "Z" المتخلف بـ "UTC" قبل تحليله.

أقدم إجابة أخرى وجدتها api-client-library بواسطة Google

try {
    DateTime dateTime = DateTime.parseRfc3339(date);
    dateTime = new DateTime(new Date(dateTime.getValue()), TimeZone.getDefault());
    long timestamp = dateTime.getValue();  // get date in timestamp
    int timeZone = dateTime.getTimeZoneShift();  // get timezone offset
} catch (NumberFormatException e) {
    e.printStackTrace();
}

دليل التثبيت ،
https://developers.google.com/API-client-library/java/google-api-java-client/setup#download

هنا مرجع API ،
https://developers.google.com/api-client-library/java/google-http-java-client/reference/1.20.0/com/google/api/client/util/datetime

رمز المصدر DateTime فصل،
https://github.com/google/google-http-java-laient/blob/master/google-http-client/src/main/java/com/google/api/client/util/datetime.java

DateTime اختبارات الوحدة ،
https://github.com/google/google-http-java-laient/blob/master/google-http-client/src/test/java/com/google/api/client/util/datetimetest.java#l121

فيما يتعلق بـ JSR-310 ، قد يكون مشروع آخر يهمه Threetenbp.

يوفر JSR-310 مكتبة تاريخ ووقت جديد لـ Java SE 8. هذا المشروع هو Backport to Java SE 6 و 7.

في حال كنت تعمل على ذكري المظهر المشروع قد ترغب في الخروج مكتبة Threetenabp.

compile "com.jakewharton.threetenabp:threetenabp:${version}"

تم تضمين JSR-310 في Java 8 كحزمة Java.Time.*. إنه بديل كامل لتاريخ المريض وواجهة برمجة التطبيقات التقويمية في كل من Java و Android. تم ترحيل JSR-310 إلى Java 6 من قبل منشئها ، ستيفن كولبورن ، والتي تم تكييف هذه المكتبة منها.

تحت Java 8 استخدم DateTimeFormatter.iso_date_time

 DateTimeFormatter formatter = DateTimeFormatter.ISO_DATE_TIME;
 ZonedDateTime result = ZonedDateTime.parse("2010-04-05T17:16:00Z", formatter);

أعتقد أنها أسهل طريقة

منذ Java 8 فقط استخدم ZonedDateTime.parse("2010-04-05T17:16:00Z")

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