Java SimpleDateFormat ("yyyy-MM-dd'T'HH: mm: ss'Z '") memberikan zona waktu sebagai IST

148

Saya memiliki konstruktor SimpleDateFormat sebagai

SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'")

dan saya parsing string "2013-09-29T18:46:19Z".

Saya telah membaca bahwa di sini Z mewakili GMT/UTCzona waktu. tetapi ketika saya mencetak tanggal ini di konsol, ia mencetak IST timezne untuk tanggal yang dikembalikan.

Sekarang pertanyaan saya adalah apakah output saya benar atau salah?

Pradip Borde
sumber
3
ya itulah yang diwakili 'Z'. Z- Zona Waktu
Woody
5
Z = Zulu waktu => GMT + 0, Anda jelas tidak melayani negara Anda;)
MushyPeas

Jawaban:

251

Anda belum menetapkan zona waktu hanya menambahkan a Zke akhir tanggal / waktu, sehingga akan terlihat seperti tanggal / waktu GMT tetapi ini tidak mengubah nilai.

Atur zona waktu ke GMT dan itu akan benar.

SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'");
sdf.setTimeZone(TimeZone.getTimeZone("GMT"));
Peter Lawrey
sumber
3
Jika Anda memiliki tanggal, katakanlah 2012-12-06T06: 00: 00 tanpa Z, apakah itu mewakili GMT?
binarygiant
3
@ binarygiant Anda harus bertanya kepada mereka yang mengirimnya. Ini bisa jadi waktu lokal pengirim.
Peter Lawrey
2
Zona waktu dapat diatur ke "UTC"
Prashanth
2
Alih-alih mengatur zona waktu di banyak tempat untuk pustaka yang berbeda dan menghindari konflik dengan zona waktu mesin / laptop Anda, Anda harus selalu mengatur zona waktu default JVM dengan mengatur properti sistem user.timezone: java -Duser.timezone = GMT ...
kisna
100

'T'dan 'Z'dianggap di sini sebagai konstanta. Anda harus lulus Ztanpa tanda kutip. Selain itu, Anda perlu menentukan zona waktu dalam string input.

Contoh: 2013-09-29T18:46:19-0700 Dan format sebagai"yyyy-MM-dd'T'HH:mm:ssZ"

Subir Kumar Sao
sumber
Subir, Terima kasih atas jawaban Anda, tetapi apakah "0700" ditambahkan ke input string ??
Pradip Borde
-0700adalah zona waktu yaitu -7: 00 Jam
Subir Kumar Sao
12
untuk -07: 00 jam dan bukan -0700 akan menjadi sebagai berikut: yyyy-MM-dd'T'HH: mm: ss.SSSXXX
Tastybrownies
48

Dari ISO 8601 String ke Java Date Object

SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'");
sdf.setTimeZone(TimeZone.getTimeZone("GMT"));
sdf.parse("2013-09-29T18:46:19Z"); //prints-> Mon Sep 30 02:46:19 CST 2013

jika Anda tidak mengatur TimeZone.getTimeZone("GMT")maka itu akan ditampilkanSun Sep 29 18:46:19 CST 2013

Dari Java Date Object ke ISO 8601 String

Dan untuk mengkonversi Dateobjek ke ISO 8601 Standard ( yyyy-MM-dd'T'HH:mm:ss'Z') gunakan kode berikut

SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'", Locale.US);
sdf.setTimeZone(TimeZone.getTimeZone("GMT"));           
System.out.println(sdf.format(new Date())); //-prints-> 2015-01-22T03:23:26Z

Perhatikan juga bahwa tanpa ' 'pada Z yyyy-MM-dd'T'HH:mm:ssZmencetak2015-01-22T03:41:02+0000

AZ_
sumber
2
Ini memberi saya java.text.ParseException: Tanggal tidak dapat diparsing: "2018-05-01T18: 30: 00.000Z" @AZ_
Mansuu ....
41

JIKA Anda ingin menangani ' standar ' JSON representasi Tanggal kemudian lebih baik menggunakan pola ini: "yyyy-MM-dd'T'HH:mm:ssX".

Perhatikan Xbagian akhir. Ini akan menangani zona waktu dalam standar ISO 8601 , dan ISO 8601 adalah persis apa yang menghasilkan pernyataan ini dalam Javascriptnew Date().toJSON()

Dibandingkan dengan jawaban lain, ada beberapa manfaatnya:

  1. Anda tidak perlu meminta klien Anda untuk mengirim tanggal dalam GMT
  2. Anda tidak perlu secara eksplisit mengonversi objek Tanggal Anda ke GMT menggunakan ini: sdf.setTimeZone(TimeZone.getTimeZone("GMT"));
MyTitle
sumber
1
Saya menggunakan playpenjilidan formulir otomatis, dan menggunakan @Format.DateTimeanotasi. Gunakan pola default dengan Zdi akhir tampaknya tidak benar. Setelah diubah menjadi X, itu berfungsi. Terima kasih banyak
transang
Jika tanggal Anda menentukan zona waktu dengan cara yang sesuai dengan RFC822 seperti "-0500", ini berfungsi dengan baik. Tetapi untuk tanggal seperti "2013-07-15T10: 22: 17-05: 00" (juga berlaku ISO8601 TZ) istirahat ini. Dalam hal ini Anda perlu menggunakan "yyyy-MM-dd'T'HH: mm: ssXXX".
Lambart
23

tl; dr

Jawaban lainnya sudah ketinggalan zaman pada Java 8.

Instant                           // Represent a moment in UTC. 
.parse( "2013-09-29T18:46:19Z" )  // Parse text in standard ISO 8601 format where the `Z` means UTC, pronounces “Zulu”.
.atZone(                          // Adjust from UTC to a time zone. 
    ZoneId.of( "Asia/Kolkata" )
)                                 // Returns a `ZonedDateTime` object. 

ISO 8601

Format string Anda kebetulan mematuhi standar ISO 8601 . Standar ini mendefinisikan format yang masuk akal untuk mewakili berbagai nilai waktu tanggal sebagai teks.

waktu java

Kelas lama java.util.Date/ .Calendardan java.text.SimpleDateFormattelah digantikan oleh kerangka java.time dibangun ke dalam Java 8 dan yang lebih baru. Lihat Tutorial . Hindari kelas lama karena terbukti tidak dirancang, membingungkan, dan merepotkan.

Bagian dari desain yang buruk di kelas lama telah menggigit Anda, di mana toStringmetode ini menerapkan zona waktu default JVM saat ini ketika menghasilkan representasi teks dari nilai tanggal-waktu yang sebenarnya dalam UTC (GMT); bermaksud baik tetapi membingungkan.

Kelas java.time menggunakan format ISO 8601 secara default ketika mem-parsing / menghasilkan representasi tekstual dari nilai-nilai tanggal-waktu. Jadi tidak perlu menentukan pola penguraian.

Suatu Instantsaat di timeline di UTC .

Instant instant = Instant.parse( "2013-09-29T18:46:19Z" );

Anda dapat menerapkan zona waktu sesuai kebutuhan untuk menghasilkan ZonedDateTimeobjek.

ZoneId zoneId = ZoneId.of( "America/Montreal" );
ZonedDateTime zdt = instant.atZone( zoneId );

Tabel tipe waktu-tanggal di Jawa, baik yang modern maupun yang lama

Basil Bourque
sumber
22

dan jika Anda tidak memiliki opsi untuk menggunakan java8 lebih baik gunakan 'yyyy-MM-dd'T'HH: mm: ssX XX ' karena ini akan diuraikan dengan benar lagi (sementara dengan hanya satu X ini mungkin tidak demikian. ..tergantung pada fungsi parsing Anda)

X menghasilkan: +01

XXX menghasilkan: +01: 00

Orang ketiga
sumber
0

Untuk Java 8: Anda dapat menggunakan inbuilt java.time.format.DateTimeFormatteruntuk mengurangi kemungkinan kesalahan pengetikan

DateTimeFormatter formatter = DateTimeFormatter.ISO_ZONED_DATE_TIME;

ISO_ZONED_DATE_TIME mewakili 2011-12-03T10:15:30+01:00[Europe/Paris]adalah salah satu format DateTime standar yang disediakan oleh tautan Oracle

niraj
sumber