تاريخ تحليل SimpleDateFormat مع "Z" الحرفي [مكرر
-
24-09-2019 - |
سؤال
هذا السؤال لديه بالفعل إجابة هنا:
أحاول تحليل موعد يشبه هذا:
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.
على الرغم من أنك قد ترغب فقط في استبدال "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")