Bagaimana saya bisa mendapatkan tanggal dan waktu saat ini dalam UTC atau GMT di Jawa?
479
Ketika saya membuat Dateobjek baru , itu diinisialisasi ke waktu saat ini tetapi di zona waktu lokal. Bagaimana saya bisa mendapatkan tanggal dan waktu saat ini dalam GMT?
Saya tahu jenis-jenis topik ini sudah sepenuhnya dibahas, tetapi saya menemukan paket commons-lang benar-benar menangani masalah-masalah umum java ini dengan baik. commons.apache.org/lang/api-2.5/org/apache/commons/lang/time Lihat berbagai paket yang mereka miliki.
Waktu setempat mana yang Anda inginkan, dan seberapa presisi. Sebagian besar zona waktu didefinisikan relatif terhadap UTC dengan offset tetap yang diukur dalam SI detik, tetapi hubungan GMT yang didasarkan pada pengamatan matahari dan panjang variabel (sedikit) lebih kompleks. Keduanya berbeda hingga 0,9 detik.
mc0e
1
A Datetidak memiliki zona waktu, jadi "tetapi di zona waktu lokal" tidak benar (atau paling tidak akurat). Lihat Semua tentang java.util.Date .
Ole VV
Jawaban:
409
java.util.Datetidak memiliki zona waktu tertentu, meskipun nilainya paling umum dipikirkan sehubungan dengan UTC. Apa yang membuat Anda berpikir ini waktu setempat?
Lebih tepatnya: nilai dalam a java.util.Dateadalah jumlah milidetik sejak zaman Unix, yang terjadi pada tengah malam 1 Januari 1970, UTC. Zaman yang sama juga bisa dijelaskan di zona waktu lain, tetapi deskripsi tradisional dalam istilah UTC. Karena beberapa milidetik sejak zaman yang tetap, nilai di dalamnya java.util.Datesama di seluruh dunia pada saat tertentu, terlepas dari zona waktu setempat.
Saya menduga masalahnya adalah Anda menampilkannya melalui instance Kalender yang menggunakan zona waktu lokal, atau mungkin menggunakan Date.toString()yang juga menggunakan zona waktu lokal, atau sebuah SimpleDateFormatinstance, yang, secara default, juga menggunakan zona waktu lokal.
Jika ini bukan masalahnya, silakan kirim beberapa kode sampel.
Namun, saya sarankan Anda tetap menggunakan Joda-Time , yang menawarkan API yang jauh lebih jelas.
Maka itu mungkin masalah driver. Anda mungkin perlu mengatur koneksi Anda ke UTC, atau sesuatu seperti itu. Saya pernah melihat masalah seperti ini sebelumnya, tetapi masalahnya bukan di java.util.Date.
Jon Skeet
13
Behrang, menurut stackoverflow.com/questions/4123534/… , driver MySQL JDBC mengubah yang diberikan java.util.Timestamp(atau java.util.Date) ke zona waktu server.
Derek Mahar
5
@Pak. Kucing: Bagaimana Anda menentukannya? Apakah dengan menulis System.out.println(new Date())? Jika demikian, Anda harus menyadari bahwa itu adalah toString()metode yang menerapkan zona waktu di sana ... jika bukan itu, tolong berikan detail lebih lanjut.
Jon Skeet
8
@ KanagaveluSugumar: toString()selalu menggunakan zona waktu default. date.getTime()pasti mengembalikan milidetik sejak zaman Unix, di UTC. Paling akurat untuk mengatakan bahwa Dateitu sendiri tidak memiliki zona waktu sama sekali - ini hanya sesaat, yang dapat dianggap dalam beberapa zona waktu. Tetapi ketika Anda membuat sebuah instance, itu tidak tergantung pada zona waktu Anda.
Jon Skeet
6
@ Jonake: Sebenarnya itu tidak terjadi ketika itu tengah malam di Greenwich, karena Inggris berada di UTC +1 pada saat itu. Hanya salah satu bagian sejarah yang aneh. Tapi saya ambil poin Anda - lebih baik mengatakan "Tanggal baru (). GetTime () mengembalikan milidetik sejak zaman Unix, yang tengah malam pada awal 1 Januari 1970, UTC". Jadi UTC adalah bagian dari menentukan zaman pada saat tertentu, bukan bagian dari hasilnya.
Jon Skeet
325
tl; dr
Instant.now()// Capture the current moment in UTC.
Hasilkan sebuah String untuk mewakili nilai itu:
Instant.now().toString()
2016-09-13T23: 30: 52.123Z
Detail
Seperti yang dinyatakan oleh Jon Skeet , objek java.util.Date tidak memiliki zona waktu † . Tetapi toStringimplementasinya menerapkan zona waktu default JVM ketika menghasilkan representasi String dari nilai tanggal-waktu itu. Yang membingungkan bagi programmer naif, Date tampaknya memiliki zona waktu tetapi tidak.
Kelas java.util.Date,, j.u.Calendardan yang java.text.SimpleDateFormatdibundel dengan Java terkenal merepotkan. Hindari mereka. Alih-alih, gunakan salah satu dari perpustakaan waktu-waktu yang kompeten ini:
Java 8 menghadirkan paket java.time baru . * Untuk menggantikan kelas java.util.Date/Calendar yang lama.
Mendapatkan waktu saat ini dalam UTC / GMT adalah satu garis sederhana ...
Instant instant =Instant.now();
Bahwa Instantkelas adalah blok bangunan dasar dalam java.time, mewakili sejenak di timeline di UTC dengan resolusi nanodetik .
Di Java 8, momen saat ini ditangkap hanya dengan resolusi hingga milidetik. Java 9 membawa implementasi segar dari Clockmenangkap momen saat ini dalam hingga kemampuan nanodetik penuh kelas ini, tergantung pada kemampuan jam komputer host Anda hardware.
Hal ini toStringmetode menghasilkan representasi String dari nilainya menggunakan satu tertentu format ISO 8601 . Format itu menghasilkan nol, tiga, enam atau sembilan digit digit ( milidetik , mikrodetik , atau nanodetik ) seperlunya untuk merepresentasikan fraksi detik.
Jika Anda ingin pemformatan yang lebih fleksibel, atau fitur tambahan lainnya, maka terapkan offset-from-UTC dari nol, untuk UTC itu sendiri ( ZoneOffset.UTCkonstan ) untuk mendapatkan a OffsetDateTime.
OffsetDateTime now =OffsetDateTime.now(ZoneOffset.UTC );
Anda dapat bertukar objek java.time secara langsung dengan database Anda. Gunakan driver JDBC yang sesuai dengan JDBC 4.2 atau yang lebih baru. Tidak perlu untuk string, tidak perlu untuk java.sql.*kelas.
Proyek ThreeTen-Extra memperpanjang java.time dengan kelas tambahan. Proyek ini adalah ajang pembuktian untuk kemungkinan penambahan masa depan ke java.time. Anda mungkin menemukan beberapa kelas berguna di sini seperti Interval, YearWeek, YearQuarter, dan lebih .
Dengan menggunakan pustaka bebas-sumber terbuka sumber terbuka Joda-Time pihak ke-3, Anda bisa mendapatkan tanggal-waktu saat ini hanya dalam satu baris kode.
Joda-Time menginspirasi kelas java.time. * Baru di Java 8, tetapi memiliki arsitektur yang berbeda. Anda dapat menggunakan Joda-Time di versi Java yang lebih lama. Joda-Time terus bekerja di Jawa 8 dan terus dipelihara secara aktif (per 2014). Namun, tim Joda-Time tidak menyarankan migrasi ke java.time.
System.out.println("UTC/GMT date-time in ISO 8601 format: "+new org.joda.time.DateTime( org.joda.time.DateTimeZone.UTC ));
Kode contoh yang lebih rinci (Joda-Time 2.3) ...
org.joda.time.DateTime now =new org.joda.time.DateTime();// Default time zone.
org.joda.time.DateTime zulu = now.toDateTime( org.joda.time.DateTimeZone.UTC );
Dump untuk menghibur ...
System.out.println("Local time in ISO 8601 format: "+ now );System.out.println("Same moment in UTC (Zulu): "+ zulu );
Saat dijalankan ...
Local time in ISO 8601 format: 2014-01-21T15:34:29.933-08:00
Same moment in UTC (Zulu): 2014-01-21T23:34:29.933Z
Untuk lebih banyak contoh kode melakukan pekerjaan zona waktu, lihat jawaban saya untuk pertanyaan serupa.
Zona waktu
Saya sarankan Anda selalu menentukan zona waktu daripada bergantung secara implisit pada zona waktu default JVM saat ini (yang dapat berubah setiap saat!). Ketergantungan seperti itu tampaknya menjadi penyebab umum kebingungan dan bug dalam pekerjaan berkencan.
Saat menelepon now()lewat zona waktu yang diinginkan / diharapkan untuk ditugaskan. Gunakan DateTimeZonekelas.
DateTimeZone zoneMontréal =DateTimeZone.forID("America/Montreal");DateTime now =DateTime.now( zoneMontréal );
Baca tentang format ISO 8601 . Baik java.time dan Joda-Time menggunakan format masuk akal standar itu sebagai default untuk parsing dan menghasilkan string.
† Sebenarnya, java.util.Date memang memiliki zona waktu, terkubur dalam-dalam di bawah lapisan kode sumber. Untuk tujuan paling praktis, zona waktu itu diabaikan. Jadi, sebagai singkatan, kita katakan java.util.Date tidak memiliki zona waktu. Lebih jauh, zona waktu yang terkubur itu bukan zona yang digunakan oleh toStringmetode Date ; metode itu menggunakan zona waktu default JVM saat ini. Semua alasan untuk menghindari kelas yang membingungkan ini dan tetap dengan Joda-Time dan java.time.
DateTime.now().toDateTime(DateTimeZone.UTC)adalah apa yang saya cari! Terima kasih!
Managarm
1
@Managarm Anda dapat mempersingkat menjadi: DateTime nowUtc = DateTime.now ( DateTimeZone.UTC ) ;
Basil Bourque
Cara mendapatkan ini dengan Pure Java 8 2014-01-21T15:34:29.933-08:00dalam contoh yang Anda gunakannew org.joda.time.DateTime()
GOXR3PLUS
1
@ GOXR3PLUS ZonedDateTime.now( ZoneId.of( "America/Los_Angeles" ) ).truncatedTo( ChronoUnit.MILLIS ).toOffsetDateTime().toString() Kami mendapatkan momen saat ini untuk zona waktu yang ditentukan. Selanjutnya, lepaskan semua micros / nanos. Kemudian kami mengonversi untuk hanya memiliki offset-dari-UTC (jumlah jam-menit-detik) daripada zona waktu penuh (sejarah perubahan masa lalu, sekarang, dan masa depan dalam offset yang digunakan oleh orang-orang dari wilayah tertentu). Terakhir, kami membuat teks yang mewakili nilai dalam OffsetDateTimeformat ISO 8601 standar yang digunakan secara default dalam toStringmetodenya.
Basil Bourque
Terima kasih telah memberikan penjelasan terperinci ini, juga +1 untuk dukungan android :) @BasilBourque
mochadwi
271
SimpleDateFormat dateFormatGmt =newSimpleDateFormat("yyyy-MMM-dd HH:mm:ss");
dateFormatGmt.setTimeZone(TimeZone.getTimeZone("GMT"));//Local time zone SimpleDateFormat dateFormatLocal =newSimpleDateFormat("yyyy-MMM-dd HH:mm:ss");//Time in GMTreturn dateFormatLocal.parse( dateFormatGmt.format(newDate()));
Mengapa Anda melakukan parse dengan dateFormatLocal setelah menggunakan format dateFormatGmt ... tidak masuk akal dengan membacanya. Saya yakin itu berhasil, tetapi hanya ingin tahu?
MindWire
2
setTimeZone melakukannya (saya kira Anda juga dapat menggunakan getTimeZone ("UTC") sama seperti GMT?)
rogerdpack
6
tetapi waktu tergantung pada waktu yang ditentukan perangkat. Jika pengguna mengatur waktu yang salah pada perangkatnya maka Anda akan mendapatkan UTC salah. Perbaiki saya jika saya salah
Basavaraj Hampali
@BasavarajHampali tetapi di dunia sekarang ini sebagian besar perangkat terhubung ke internet yang mengoreksi waktu yang salah
Akshat Agarwal
3
Tidak ada perbedaan waktu antara Coordinated Universal Time (UTC) dan Greenwich Mean Time (GMT)
slott
86
Ini pasti mengembalikan waktu UTC: sebagai objek String dan Date!
Dalam jawaban saya, saya lupa menunjukkan bagaimana DATEFORMAT didefinisikan: static final String DATEFORMAT = "yyyy-MM-dd HH:mm:ss";
Seseorang di suatu tempat
21
Harap hindari memulai nama metode dengan huruf besar di Jawa. Lihat konvensi kode Java untuk nama metode.
Florian Schrofner
2
Sebagaimana diarahkan ke jawaban ini, Panggilan new Date()tidak akan pernah mengembalikan waktu UTC yang benar, jika waktu perangkat salah.
Sanoop
apakah metode ini mendapatkan waktu tergantung pada kalender perangkat?
Arnold Brown
Satu hal yang perlu diperhatikan. Solusi apa pun yang perlu mendapatkan Date atau Timestamp di UTC, sepertinya kuncinya adalah untuk tidak menggunakan kembali SimpleDateFormat, melainkan menggunakan satu untuk mendapatkan UTC ke dalam sebuah string, kemudian buat UTC lain ketika mengkonversi string ke salah satu Date. atau Obyek Timestamp. Saya perhatikan bahwa jika Anda mencoba menggunakan kembali SimpleDateFormat yang sama maka Objek Tanggal / Timestamp yang dihasilkan akan kembali ke zona waktu lokal, bukan UTC.
Yap, solusi yang bagus dan bersih. Itu hanya membuat saya khawatir, apakah itu tidak efektif untuk membuat objek Date baru alih-alih hanya mendapatkan instance Calendar?
Beemo
Ini akan dioptimalkan oleh JVM dan HotSpot akan mengeksekusi kode x86 seefektif mungkin
Antonio
17
Kalender aGMTCalendar = Calendar.getInstance (TimeZone.getTimeZone ("GMT")); Kemudian semua operasi yang dilakukan dengan menggunakan objek aGMTCalendar akan dilakukan dengan zona waktu GMT dan tidak akan memiliki daylight saving time atau offset tetap yang diterapkan
java.util.Dateselalu dalam UTC. Apa yang membuat Anda berpikir ini waktu setempat? Saya menduga masalahnya adalah Anda menampilkannya melalui instance Kalender yang menggunakan zona waktu lokal, atau mungkin menggunakan
Date.toString()yang juga menggunakan zona waktu lokal.
menunjukkan jam GMT bukan jam lokal - catatan yang getTime.getHours()hilang karena itu akan membuat Date()objek, yang secara teoritis menyimpan tanggal dalam GMT, tetapi mengembalikan jam di zona waktu lokal.
Saya belum pernah melihat jawaban ini sebelumnya, tetapi jika Anda membaca dokumentasi untuk Date.getHours()metode yang sudah usang , itu membuatnya sangat jelas: "Nilai yang dikembalikan adalah angka (0 hingga 23) yang mewakili jam dalam hari yang berisi atau dimulai dengan waktu instan diwakili oleh objek Tanggal ini, sebagaimana ditafsirkan dalam zona waktu lokal . " (Penekanan tambang.) Ini adalah getHours()metode yang menafsirkan nilai dalam zona waktu lokal - itu bukan bagian dari keadaan Dateobjek itu sendiri.
Jon Skeet
2
Seperti yang dinyatakan Jon Skeet dengan benar, objek java.util.Date tidak memiliki zona waktu . Tetapi membingungkan, metode toStringdan getHoursmenerapkan zona waktu default untuk output mereka. Jadi, programmer naif mudah tertipu karena tampaknya Date memiliki zona waktu tetapi sebenarnya tidak.
Basil Bourque
7
Jika Anda ingin objek Date dengan bidang yang disesuaikan dengan UTC Anda dapat melakukannya seperti ini dengan Joda Time :
import org.joda.time.DateTimeZone;import java.util.Date;...Date local =newDate();System.out.println("Local: "+ local);DateTimeZone zone =DateTimeZone.getDefault();long utc = zone.convertLocalToUTC(local.getTime(),false);System.out.println("UTC: "+newDate(utc));
Anda bekerja terlalu keras. Joda-Time dapat melakukan ini dalam satu baris kode. Lihat jawaban saya sendiri pada pertanyaan ini. Panggil .toDateTimemetode dan berikan konstanta untuk zona waktu UTC.
Basil Bourque
1
DateTime utcDate = DateTime baru (). ToDateTime (DateTimeZone.UTC)
Kemudian semua operasi yang dilakukan menggunakan objek aGMTCalendar akan dilakukan dengan zona waktu GMT dan tidak akan memiliki waktu musim panas atau offset tetap yang diterapkan. Saya pikir poster sebelumnya benar bahwa objek Date () selalu mengembalikan GMT itu tidak sampai Anda pergi untuk melakukan sesuatu dengan objek tanggal bahwa ia akan dikonversi ke zona waktu lokal.
Anda bisa bertanya cal.get(Calendar.DATE);atau Kalender konstan lainnya tentang detail orang lain.
Tanggal dan Stempel Waktu sudah tidak digunakan lagi di Jawa. Kelas kalender bukan.
Kode sampel untuk membuat waktu sistem dalam zona waktu tertentu dan format tertentu.
import java.text.SimpleDateFormat;import java.util.Calendar;import java.util.Date;import java.util.TimeZone;publicclassTimZoneTest{publicstaticvoid main (String[] args){//<GMT><+/-><hour>:<minutes>// Any screw up in this format, timezone defaults to GMT QUIETLY. So test your format a few times.System.out.println(my_time_in("GMT-5:00","MM/dd/yyyy HH:mm:ss"));System.out.println(my_time_in("GMT+5:30","'at' HH:mm a z 'on' MM/dd/yyyy"));System.out.println("---------------------------------------------");// Alternate format System.out.println(my_time_in("America/Los_Angeles","'at' HH:mm a z 'on' MM/dd/yyyy"));System.out.println(my_time_in("America/Buenos_Aires","'at' HH:mm a z 'on' MM/dd/yyyy"));}publicstaticString my_time_in(String target_time_zone,String format){TimeZone tz =TimeZone.getTimeZone(target_time_zone);Date date =Calendar.getInstance().getTime();SimpleDateFormat date_format_gmt =newSimpleDateFormat(format);
date_format_gmt.setTimeZone(tz);return date_format_gmt.format(date);}}
Keluaran
10/08/201121:07:21
at 07:37 AM GMT+05:30 on 10/09/2011
at 19:07 PM PDT on 10/08/2011
at 23:07 PM ART on 10/08/2011
Memanggil getTime () pada ini menyebabkannya kehilangan informasi zona waktu dan mengembalikan waktu setempat.
RealCasually
3
Mengonversi DateTime Saat Ini di UTC:
DateTimeFormatter formatter =DateTimeFormat.forPattern("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'");DateTimeZone dateTimeZone =DateTimeZone.getDefault();//Default Time ZoneDateTime currDateTime =newDateTime();//Current DateTimelong utcTime = dateTimeZone.convertLocalToUTC(currDateTime .getMillis(),false);String currTime = formatter.print(utcTime);//UTC time converted to string from long in format of formatter
currDateTime = formatter.parseDateTime(currTime);//Converted to DateTime in UTC
Anda melakukan terlalu banyak pekerjaan di sini. (a) Patter formatter yang Anda tetapkan sudah dibangun menjadi DateTime secara default; panggil toStringDateTime untuk mendapatkan pola string ISO 8601 itu . (B) Terlalu banyak kode untuk mengkonversi antara zona waktu. Cukup panggil "toDateTime" dan berikan objek zona waktu. Seperti ini: myDateTime.toDateTime( DateTimeZone.UTC ). Untuk zona waktu tertentu, instantiate dan berikan objek zona waktu berdasarkan nama yang tepat , panggil myDateTime.toDateTime( DateTimeZone.forID( "Asia/Tehran" ) ).
Basil Bourque
2
Ini bekerja untuk saya, mengembalikan stempel waktu dalam GMT!
Gunakan Kelas ini untuk mendapatkan Waktu UTC yang tepat dari Server NTP Online:
import java.net.DatagramPacket;import java.net.DatagramSocket;import java.net.InetAddress;class NTP_UTC_Time
{privatestaticfinalString TAG ="SntpClient";privatestaticfinalint RECEIVE_TIME_OFFSET =32;privatestaticfinalint TRANSMIT_TIME_OFFSET =40;privatestaticfinalint NTP_PACKET_SIZE =48;privatestaticfinalint NTP_PORT =123;privatestaticfinalint NTP_MODE_CLIENT =3;privatestaticfinalint NTP_VERSION =3;// Number of seconds between Jan 1, 1900 and Jan 1, 1970// 70 years plus 17 leap daysprivatestaticfinallong OFFSET_1900_TO_1970 =((365L*70L)+17L)*24L*60L*60L;privatelong mNtpTime;publicboolean requestTime(String host,int timeout){try{DatagramSocket socket =newDatagramSocket();
socket.setSoTimeout(timeout);InetAddress address =InetAddress.getByName(host);byte[] buffer =newbyte[NTP_PACKET_SIZE];DatagramPacket request =newDatagramPacket(buffer, buffer.length, address, NTP_PORT);
buffer[0]= NTP_MODE_CLIENT |(NTP_VERSION <<3);
writeTimeStamp(buffer, TRANSMIT_TIME_OFFSET);
socket.send(request);// read the responseDatagramPacket response =newDatagramPacket(buffer, buffer.length);
socket.receive(response);
socket.close();
mNtpTime = readTimeStamp(buffer, RECEIVE_TIME_OFFSET);}catch(Exception e){// if (Config.LOGD) Log.d(TAG, "request time failed: " + e);returnfalse;}returntrue;}publiclong getNtpTime(){return mNtpTime;}/**
* Reads an unsigned 32 bit big endian number from the given offset in the buffer.
*/privatelong read32(byte[] buffer,int offset){byte b0 = buffer[offset];byte b1 = buffer[offset+1];byte b2 = buffer[offset+2];byte b3 = buffer[offset+3];// convert signed bytes to unsigned valuesint i0 =((b0 &0x80)==0x80?(b0 &0x7F)+0x80: b0);int i1 =((b1 &0x80)==0x80?(b1 &0x7F)+0x80: b1);int i2 =((b2 &0x80)==0x80?(b2 &0x7F)+0x80: b2);int i3 =((b3 &0x80)==0x80?(b3 &0x7F)+0x80: b3);return((long)i0 <<24)+((long)i1 <<16)+((long)i2 <<8)+(long)i3;}/**
* Reads the NTP time stamp at the given offset in the buffer and returns
* it as a system time (milliseconds since January 1, 1970).
*/privatelong readTimeStamp(byte[] buffer,int offset){long seconds = read32(buffer, offset);long fraction = read32(buffer, offset +4);return((seconds - OFFSET_1900_TO_1970)*1000)+((fraction *1000L)/0x100000000L);}/**
* Writes 0 as NTP starttime stamp in the buffer. --> Then NTP returns Time OFFSET since 1900
*/privatevoid writeTimeStamp(byte[] buffer,int offset){int ofs = offset++;for(int i=ofs;i<(ofs+8);i++)
buffer[i]=(byte)(0);}}
Dan gunakan dengan:
long now =0;
NTP_UTC_Time client =new NTP_UTC_Time();if(client.requestTime("pool.ntp.org",2000)){
now = client.getNtpTime();}
Jika Anda membutuhkan Waktu UTC "sekarang" sebagai fungsi penggunaan DateTimeString:
Sederhananya. Objek kalender menyimpan informasi tentang zona waktu tetapi ketika Anda melakukan cal.getTime () maka informasi zona waktu akan hilang. Jadi untuk konversi Timezone saya akan menyarankan untuk menggunakan kelas DateFormat ...
publicstaticStringGetCurrentTimeStamp(){Calendar cal=Calendar.getInstance();long offset = cal.getTimeZone().getOffset(System.currentTimeMillis());//if you want in UTC else remove it .returnnew java.sql.Timestamp(System.currentTimeMillis()+offset).toString();}
publicclassCurrentUtcDate{publicstaticvoid main(String[] args){Date date =newDate();SimpleDateFormat dateFormat =newSimpleDateFormat("dd-MM-yyyy HH:mm:ss");
dateFormat.setTimeZone(TimeZone.getTimeZone("UTC"));System.out.println("UTC Time is: "+ dateFormat.format(date));}}
Keluaran:
UTC Time is:22-01-201813:14:35
Anda dapat mengubah format tanggal sesuai kebutuhan.
Tolong jangan mengajari anak-anak untuk menggunakan yang lama dan terkenal merepotkan SimpleDateFormat. Hari ini kita memiliki java.timeAPI tanggal dan waktu Java yang jauh lebih baik . Juga apa yang Anda berikan yang belum ada dalam jawaban oleh Dan, Antonio, dan lainnya?
Ole VV
2
(a) Bagaimana Jawaban ini menambah nilai atas puluhan Jawaban yang ada? (B) kelas merepotkan yang digunakan di sini digantikan tahun yang lalu oleh kelas java.time modern . Menyarankan penggunaannya pada 2018 adalah saran yang buruk.
Basil Bourque
0
Gunakan paket java.time dan sertakan di bawah kode-
ZonedDateTime now = ZonedDateTime.now( ZoneOffset.UTC );
(A) Jika menggunakan offset ( ZoneOffset) daripada zona waktu ( ZoneId), OffsetDateTimeitu lebih tepat daripada ZonedDateTime. (B) LocalDateTimetidak boleh digunakan untuk mengabadikan momen saat ini karena tidak memiliki konsep zona waktu atau offset-dari-UTC. (C) Jawaban lain yang sudah ada sebelumnya telah membahas materi ini dan melakukan pekerjaan yang lebih baik. Saya tidak melihat bagaimana Jawaban ini menambah nilai.
Date
tidak memiliki zona waktu, jadi "tetapi di zona waktu lokal" tidak benar (atau paling tidak akurat). Lihat Semua tentang java.util.Date .Jawaban:
java.util.Date
tidak memiliki zona waktu tertentu, meskipun nilainya paling umum dipikirkan sehubungan dengan UTC. Apa yang membuat Anda berpikir ini waktu setempat?Lebih tepatnya: nilai dalam a
java.util.Date
adalah jumlah milidetik sejak zaman Unix, yang terjadi pada tengah malam 1 Januari 1970, UTC. Zaman yang sama juga bisa dijelaskan di zona waktu lain, tetapi deskripsi tradisional dalam istilah UTC. Karena beberapa milidetik sejak zaman yang tetap, nilai di dalamnyajava.util.Date
sama di seluruh dunia pada saat tertentu, terlepas dari zona waktu setempat.Saya menduga masalahnya adalah Anda menampilkannya melalui instance Kalender yang menggunakan zona waktu lokal, atau mungkin menggunakan
Date.toString()
yang juga menggunakan zona waktu lokal, atau sebuahSimpleDateFormat
instance, yang, secara default, juga menggunakan zona waktu lokal.Jika ini bukan masalahnya, silakan kirim beberapa kode sampel.
Namun, saya sarankan Anda tetap menggunakan Joda-Time , yang menawarkan API yang jauh lebih jelas.
sumber
java.util.Timestamp
(ataujava.util.Date
) ke zona waktu server.System.out.println(new Date())
? Jika demikian, Anda harus menyadari bahwa itu adalahtoString()
metode yang menerapkan zona waktu di sana ... jika bukan itu, tolong berikan detail lebih lanjut.toString()
selalu menggunakan zona waktu default.date.getTime()
pasti mengembalikan milidetik sejak zaman Unix, di UTC. Paling akurat untuk mengatakan bahwaDate
itu sendiri tidak memiliki zona waktu sama sekali - ini hanya sesaat, yang dapat dianggap dalam beberapa zona waktu. Tetapi ketika Anda membuat sebuah instance, itu tidak tergantung pada zona waktu Anda.tl; dr
Hasilkan sebuah String untuk mewakili nilai itu:
Detail
Seperti yang dinyatakan oleh Jon Skeet , objek java.util.Date tidak memiliki zona waktu † . Tetapi
toString
implementasinya menerapkan zona waktu default JVM ketika menghasilkan representasi String dari nilai tanggal-waktu itu. Yang membingungkan bagi programmer naif, Date tampaknya memiliki zona waktu tetapi tidak.Kelas
java.util.Date
,,j.u.Calendar
dan yangjava.text.SimpleDateFormat
dibundel dengan Java terkenal merepotkan. Hindari mereka. Alih-alih, gunakan salah satu dari perpustakaan waktu-waktu yang kompeten ini:java.time (Java 8)
Java 8 menghadirkan paket java.time baru . * Untuk menggantikan kelas java.util.Date/Calendar yang lama.
Mendapatkan waktu saat ini dalam UTC / GMT adalah satu garis sederhana ...
Bahwa
Instant
kelas adalah blok bangunan dasar dalam java.time, mewakili sejenak di timeline di UTC dengan resolusi nanodetik .Di Java 8, momen saat ini ditangkap hanya dengan resolusi hingga milidetik. Java 9 membawa implementasi segar dari
Clock
menangkap momen saat ini dalam hingga kemampuan nanodetik penuh kelas ini, tergantung pada kemampuan jam komputer host Anda hardware.Hal ini
toString
metode menghasilkan representasi String dari nilainya menggunakan satu tertentu format ISO 8601 . Format itu menghasilkan nol, tiga, enam atau sembilan digit digit ( milidetik , mikrodetik , atau nanodetik ) seperlunya untuk merepresentasikan fraksi detik.Jika Anda ingin pemformatan yang lebih fleksibel, atau fitur tambahan lainnya, maka terapkan offset-from-UTC dari nol, untuk UTC itu sendiri (
ZoneOffset.UTC
konstan ) untuk mendapatkan aOffsetDateTime
.Dump untuk menghibur ...
Saat dijalankan ...
Tentang java.time
The java.time kerangka dibangun ke Jawa 8 dan kemudian. Kelas-kelas ini menggantikan tua merepotkan warisan kelas tanggal-waktu seperti
java.util.Date
,Calendar
, &SimpleDateFormat
.Untuk mempelajari lebih lanjut, lihat Tutorial Oracle . Dan cari Stack Overflow untuk banyak contoh dan penjelasan. Spesifikasi adalah JSR 310 .
Proyek Joda-Time , sekarang dalam mode pemeliharaan , menyarankan migrasi ke kelas java.time .
Anda dapat bertukar objek java.time secara langsung dengan database Anda. Gunakan driver JDBC yang sesuai dengan JDBC 4.2 atau yang lebih baru. Tidak perlu untuk string, tidak perlu untuk
java.sql.*
kelas.Di mana mendapatkan kelas java.time?
Proyek ThreeTen-Extra memperpanjang java.time dengan kelas tambahan. Proyek ini adalah ajang pembuktian untuk kemungkinan penambahan masa depan ke java.time. Anda mungkin menemukan beberapa kelas berguna di sini seperti
Interval
,YearWeek
,YearQuarter
, dan lebih .Joda-Time
UPDATE: Proyek Joda-Time , sekarang dalam mode pemeliharaan , menyarankan migrasi ke kelas java.time .
Dengan menggunakan pustaka bebas-sumber terbuka sumber terbuka Joda-Time pihak ke-3, Anda bisa mendapatkan tanggal-waktu saat ini hanya dalam satu baris kode.
Joda-Time menginspirasi kelas java.time. * Baru di Java 8, tetapi memiliki arsitektur yang berbeda. Anda dapat menggunakan Joda-Time di versi Java yang lebih lama. Joda-Time terus bekerja di Jawa 8 dan terus dipelihara secara aktif (per 2014). Namun, tim Joda-Time tidak menyarankan migrasi ke java.time.
Kode contoh yang lebih rinci (Joda-Time 2.3) ...
Dump untuk menghibur ...
Saat dijalankan ...
Untuk lebih banyak contoh kode melakukan pekerjaan zona waktu, lihat jawaban saya untuk pertanyaan serupa.
Zona waktu
Saya sarankan Anda selalu menentukan zona waktu daripada bergantung secara implisit pada zona waktu default JVM saat ini (yang dapat berubah setiap saat!). Ketergantungan seperti itu tampaknya menjadi penyebab umum kebingungan dan bug dalam pekerjaan berkencan.
Saat menelepon
now()
lewat zona waktu yang diinginkan / diharapkan untuk ditugaskan. GunakanDateTimeZone
kelas.Kelas itu memiliki konstanta untuk zona waktu UTC .
Jika Anda benar-benar ingin menggunakan zona waktu default JVM saat ini, buat panggilan eksplisit sehingga kode Anda bisa didokumentasikan sendiri.
ISO 8601
Baca tentang format ISO 8601 . Baik java.time dan Joda-Time menggunakan format masuk akal standar itu sebagai default untuk parsing dan menghasilkan string.
† Sebenarnya, java.util.Date memang memiliki zona waktu, terkubur dalam-dalam di bawah lapisan kode sumber. Untuk tujuan paling praktis, zona waktu itu diabaikan. Jadi, sebagai singkatan, kita katakan java.util.Date tidak memiliki zona waktu. Lebih jauh, zona waktu yang terkubur itu bukan zona yang digunakan oleh
toString
metode Date ; metode itu menggunakan zona waktu default JVM saat ini. Semua alasan untuk menghindari kelas yang membingungkan ini dan tetap dengan Joda-Time dan java.time.sumber
DateTime.now().toDateTime(DateTimeZone.UTC)
adalah apa yang saya cari! Terima kasih!DateTime nowUtc = DateTime.now ( DateTimeZone.UTC ) ;
2014-01-21T15:34:29.933-08:00
dalam contoh yang Anda gunakannew org.joda.time.DateTime()
ZonedDateTime.now( ZoneId.of( "America/Los_Angeles" ) ).truncatedTo( ChronoUnit.MILLIS ).toOffsetDateTime().toString()
Kami mendapatkan momen saat ini untuk zona waktu yang ditentukan. Selanjutnya, lepaskan semua micros / nanos. Kemudian kami mengonversi untuk hanya memiliki offset-dari-UTC (jumlah jam-menit-detik) daripada zona waktu penuh (sejarah perubahan masa lalu, sekarang, dan masa depan dalam offset yang digunakan oleh orang-orang dari wilayah tertentu). Terakhir, kami membuat teks yang mewakili nilai dalamOffsetDateTime
format ISO 8601 standar yang digunakan secara default dalamtoString
metodenya.sumber
Ini pasti mengembalikan waktu UTC: sebagai objek String dan Date!
sumber
static final String DATEFORMAT = "yyyy-MM-dd HH:mm:ss";
new Date()
tidak akan pernah mengembalikan waktu UTC yang benar, jika waktu perangkat salah.sumber
Sebenarnya bukan waktu, tapi representasi itu bisa diubah.
Waktu sama di setiap titik di Bumi, tetapi persepsi kita tentang waktu bisa berbeda tergantung pada lokasi.
sumber
Salah!
dan
akan kembali bersamaan. Idem untuk
sumber
Kode ini mencetak waktu UTC saat ini.
Hasil
sumber
Ini berfungsi untuk mendapatkan UTC dalam milidetik di Android.
sumber
c.add(Calendar.MILLISECOND, (-utcOffset))
untuk mendapatkan Kalender dengan utc timezoneInilah yang tampaknya salah dalam jawaban Jon Skeet . Dia berkata:
Namun, kodenya:
memberikan jam lokal, bukan GMT (jam UTC), menggunakan tidak
Calendar
dan tidakSimpleDateFormat
sama sekali.Itu sebabnya sepertinya ada sesuatu yang salah.
Menyatukan respons, kode:
menunjukkan jam GMT bukan jam lokal - catatan yang
getTime.getHours()
hilang karena itu akan membuatDate()
objek, yang secara teoritis menyimpan tanggal dalam GMT, tetapi mengembalikan jam di zona waktu lokal.sumber
Date.getHours()
metode yang sudah usang , itu membuatnya sangat jelas: "Nilai yang dikembalikan adalah angka (0 hingga 23) yang mewakili jam dalam hari yang berisi atau dimulai dengan waktu instan diwakili oleh objek Tanggal ini, sebagaimana ditafsirkan dalam zona waktu lokal . " (Penekanan tambang.) Ini adalahgetHours()
metode yang menafsirkan nilai dalam zona waktu lokal - itu bukan bagian dari keadaanDate
objek itu sendiri.toString
dangetHours
menerapkan zona waktu default untuk output mereka. Jadi, programmer naif mudah tertipu karena tampaknya Date memiliki zona waktu tetapi sebenarnya tidak.Jika Anda ingin objek Date dengan bidang yang disesuaikan dengan UTC Anda dapat melakukannya seperti ini dengan Joda Time :
sumber
.toDateTime
metode dan berikan konstanta untuk zona waktu UTC.Kamu bisa menggunakan:
Kemudian semua operasi yang dilakukan menggunakan objek aGMTCalendar akan dilakukan dengan zona waktu GMT dan tidak akan memiliki waktu musim panas atau offset tetap yang diterapkan. Saya pikir poster sebelumnya benar bahwa objek Date () selalu mengembalikan GMT itu tidak sampai Anda pergi untuk melakukan sesuatu dengan objek tanggal bahwa ia akan dikonversi ke zona waktu lokal.
sumber
sumber
Anda bisa langsung menggunakan ini
sumber
Dengan:
Kemudian
cal
miliki tanggal dan waktu saat ini.Anda juga bisa mendapatkan Tanggal dan Waktu saat ini untuk zona waktu dengan:
Anda bisa bertanya
cal.get(Calendar.DATE);
atau Kalender konstan lainnya tentang detail orang lain.Tanggal dan Stempel Waktu sudah tidak digunakan lagi di Jawa. Kelas kalender bukan.
sumber
Berikut saran lain untuk mendapatkan objek GMT Timestamp:
sumber
Berikut ini cara lain untuk mendapatkan waktu GMT dalam format String
sumber
Inilah implementasi toUTC saya:
Mungkin ada beberapa cara untuk memperbaikinya, tetapi itu berhasil untuk saya.
sumber
Kode sampel untuk membuat waktu sistem dalam zona waktu tertentu dan format tertentu.
Keluaran
sumber
Hanya untuk membuat ini lebih sederhana, untuk membuat
Date
dalamUTC
Anda dapat menggunakanCalendar
:Yang akan membangun contoh baru untuk
Calendar
menggunakan "UTC"TimeZone
.Jika Anda memerlukan
Date
objek dari kalender itu, Anda bisa menggunakannyagetTime()
.sumber
Mengonversi DateTime Saat Ini di UTC:
sumber
toString
DateTime untuk mendapatkan pola string ISO 8601 itu . (B) Terlalu banyak kode untuk mengkonversi antara zona waktu. Cukup panggil "toDateTime" dan berikan objek zona waktu. Seperti ini:myDateTime.toDateTime( DateTimeZone.UTC )
. Untuk zona waktu tertentu, instantiate dan berikan objek zona waktu berdasarkan nama yang tepat , panggilmyDateTime.toDateTime( DateTimeZone.forID( "Asia/Tehran" ) )
.Ini bekerja untuk saya, mengembalikan stempel waktu dalam GMT!
sumber
Gunakan Kelas ini untuk mendapatkan Waktu UTC yang tepat dari Server NTP Online:
Dan gunakan dengan:
Jika Anda membutuhkan Waktu UTC "sekarang" sebagai fungsi penggunaan DateTimeString:
dan gunakan dengan:
sumber
sumber
Sederhananya. Objek kalender menyimpan informasi tentang zona waktu tetapi ketika Anda melakukan cal.getTime () maka informasi zona waktu akan hilang. Jadi untuk konversi Timezone saya akan menyarankan untuk menggunakan kelas DateFormat ...
sumber
ini implementasi saya:
sumber
Jika Anda ingin menghindari penguraian tanggal dan hanya ingin cap waktu dalam GMT, Anda dapat menggunakan:
sumber
Jika Anda menggunakan waktu joda dan ingin waktu saat ini dalam milidetik tanpa offset lokal, Anda dapat menggunakan ini:
sumber
Keluaran:
Anda dapat mengubah format tanggal sesuai kebutuhan.
sumber
SimpleDateFormat
. Hari ini kita memilikijava.time
API tanggal dan waktu Java yang jauh lebih baik . Juga apa yang Anda berikan yang belum ada dalam jawaban oleh Dan, Antonio, dan lainnya?Gunakan paket java.time dan sertakan di bawah kode-
ZonedDateTime now = ZonedDateTime.now( ZoneOffset.UTC );
atau
LocalDateTime now2 = LocalDateTime.now( ZoneOffset.UTC );
tergantung pada kebutuhan aplikasi Anda.
sumber
ZoneOffset
) daripada zona waktu (ZoneId
),OffsetDateTime
itu lebih tepat daripadaZonedDateTime
. (B)LocalDateTime
tidak boleh digunakan untuk mengabadikan momen saat ini karena tidak memiliki konsep zona waktu atau offset-dari-UTC. (C) Jawaban lain yang sudah ada sebelumnya telah membahas materi ini dan melakukan pekerjaan yang lebih baik. Saya tidak melihat bagaimana Jawaban ini menambah nilai.