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?

Behrang
sumber
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.

Jon Skeet
sumber
5
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.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 ...

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 );

Dump untuk menghibur ...

System.out.println( "now.toString(): " + now );

Saat dijalankan ...

now.toString(): 2014-01-21T23:42:03.522Z

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


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?

Tabel mana perpustakaan java.time untuk digunakan dengan versi Java atau Android

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.

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 );

Kelas itu memiliki konstanta untuk zona waktu UTC .

DateTime now = DateTime.now( DateTimeZone.UTC );

Jika Anda benar-benar ingin menggunakan zona waktu default JVM saat ini, buat panggilan eksplisit sehingga kode Anda bisa didokumentasikan sendiri.

DateTimeZone zoneDefault = DateTimeZone.getDefault();

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 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.

Basil Bourque
sumber
2
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 = new SimpleDateFormat("yyyy-MMM-dd HH:mm:ss");
dateFormatGmt.setTimeZone(TimeZone.getTimeZone("GMT"));

//Local time zone   
SimpleDateFormat dateFormatLocal = new SimpleDateFormat("yyyy-MMM-dd HH:mm:ss");

//Time in GMT
return dateFormatLocal.parse( dateFormatGmt.format(new Date()) );
Dan
sumber
11
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!

static final String DATE_FORMAT = "yyyy-MM-dd HH:mm:ss";

public static Date getUTCdatetimeAsDate() {
    // note: doesn't check for null
    return stringDateToDate(getUTCdatetimeAsString());
}

public static String getUTCdatetimeAsString() {
    final SimpleDateFormat sdf = new SimpleDateFormat(DATE_FORMAT);
    sdf.setTimeZone(TimeZone.getTimeZone("UTC"));
    final String utcTime = sdf.format(new Date());

    return utcTime;
}

public static Date stringDateToDate(String StrDate) {
    Date dateToReturn = null;
    SimpleDateFormat dateFormat = new SimpleDateFormat(DATEFORMAT);

    try {
        dateToReturn = (Date)dateFormat.parse(StrDate);
    }
    catch (ParseException e) {
        e.printStackTrace();
    }

    return dateToReturn;
}
Seseorang disuatu tempat
sumber
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.
Brian Begun
65
    Calendar c = Calendar.getInstance();
    System.out.println("current: "+c.getTime());

    TimeZone z = c.getTimeZone();
    int offset = z.getRawOffset();
    if(z.inDaylightTime(new Date())){
        offset = offset + z.getDSTSavings();
    }
    int offsetHrs = offset / 1000 / 60 / 60;
    int offsetMins = offset / 1000 / 60 % 60;

    System.out.println("offset: " + offsetHrs);
    System.out.println("offset: " + offsetMins);

    c.add(Calendar.HOUR_OF_DAY, (-offsetHrs));
    c.add(Calendar.MINUTE, (-offsetMins));

    System.out.println("GMT Time: "+c.getTime());
Ahmad Nadeem
sumber
52

Sebenarnya bukan waktu, tapi representasi itu bisa diubah.

SimpleDateFormat f = new SimpleDateFormat("yyyy-MMM-dd HH:mm:ss");
f.setTimeZone(TimeZone.getTimeZone("UTC"));
System.out.println(f.format(new Date()));

Waktu sama di setiap titik di Bumi, tetapi persepsi kita tentang waktu bisa berbeda tergantung pada lokasi.

Antonio
sumber
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

Salah!

Calendar aGMTCalendar = Calendar.getInstance(TimeZone.getTimeZone("GMT"));
aGMTCalendar.getTime(); //or getTimeInMillis()

dan

Calendar aNotGMTCalendar = Calendar.getInstance(TimeZone.getTimeZone("GMT-2"));aNotGMTCalendar.getTime();

akan kembali bersamaan. Idem untuk

new Date(); //it's not GMT.
simpatico
sumber
17

Kode ini mencetak waktu UTC saat ini.

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.TimeZone;


public class Test
{
    public static void main(final String[] args) throws ParseException
    {
        final SimpleDateFormat f = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss z");
        f.setTimeZone(TimeZone.getTimeZone("UTC"));
        System.out.println(f.format(new Date()));
    }
}

Hasil

2013-10-26 14:37:48 UTC
Adam
sumber
14

Ini berfungsi untuk mendapatkan UTC dalam milidetik di Android.

Calendar c = Calendar.getInstance();
int utcOffset = c.get(Calendar.ZONE_OFFSET) + c.get(Calendar.DST_OFFSET);  
Long utcMilliseconds = c.getTimeInMillis() + utcOffset;
moberme
sumber
7
hanya Anda yang perlu mengurangi offset?
tevch
c.add(Calendar.MILLISECOND, (-utcOffset))untuk mendapatkan Kalender dengan utc timezone
Shanavas M
10

Inilah yang tampaknya salah dalam jawaban Jon Skeet . Dia berkata:

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.

Namun, kodenya:

System.out.println(new java.util.Date().getHours() + " hours");

memberikan jam lokal, bukan GMT (jam UTC), menggunakan tidak Calendardan tidak SimpleDateFormatsama sekali.

Itu sebabnya sepertinya ada sesuatu yang salah.

Menyatukan respons, kode:

System.out.println(Calendar.getInstance(TimeZone.getTimeZone("GMT"))
                           .get(Calendar.HOUR_OF_DAY) + " Hours");

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.

Dana Wilson
sumber
6
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 = new Date();
System.out.println("Local: " + local);
DateTimeZone zone = DateTimeZone.getDefault();
long utc = zone.convertLocalToUTC(local.getTime(), false);
System.out.println("UTC: " + new Date(utc));
huljas
sumber
1
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)
Maciej Miklas
6

Kamu bisa menggunakan:

Calendar aGMTCalendar = Calendar.getInstance(TimeZone.getTimeZone("GMT"));

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.

mjh2007
sumber
6
SimpleDateFormat dateFormatGmt = new SimpleDateFormat("yyyy-MM-dd");
dateFormatGmt.setTimeZone(TimeZone.getTimeZone("GMT"));
System.out.println(dateFormatGmt.format(date));
Justin
sumber
Harap tambahkan beberapa penjelasan pada jawaban Anda, bagaimana bedanya dengan begitu banyak jawaban lainnya?
akjoshi
apakah metode ini mendapatkan waktu tergantung pada kalender perangkat?
Arnold Brown
6

Anda bisa langsung menggunakan ini

SimpleDateFormat dateFormatGmt = new SimpleDateFormat("dd:MM:yyyy HH:mm:ss");
dateFormatGmt.setTimeZone(TimeZone.getTimeZone("GMT"));
System.out.println(dateFormatGmt.format(new Date())+"");
nithinreddy
sumber
5

Dengan:

Calendar cal = Calendar.getInstance();

Kemudian calmiliki tanggal dan waktu saat ini.
Anda juga bisa mendapatkan Tanggal dan Waktu saat ini untuk zona waktu dengan:

Calendar cal2 = Calendar.getInstance(TimeZone.getTimeZone("GMT-2"));

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.

pengguna2427
sumber
6
Metode dan konstruktor tertentu dari Date dan Timestamp sudah usang, tetapi kelas itu sendiri tidak.
Powerlord
5

Berikut saran lain untuk mendapatkan objek GMT Timestamp:

import java.sql.Timestamp;
import java.util.Calendar;

...

private static Timestamp getGMT() {
   Calendar cal = Calendar.getInstance();
   return new Timestamp(cal.getTimeInMillis()
                       -cal.get(Calendar.ZONE_OFFSET)
                       -cal.get(Calendar.DST_OFFSET));
}
Ren
sumber
5

Berikut ini cara lain untuk mendapatkan waktu GMT dalam format String

String DATE_FORMAT = "EEE, dd MMM yyyy HH:mm:ss z" ;
final SimpleDateFormat sdf = new SimpleDateFormat(DATE_FORMAT);
sdf.setTimeZone(TimeZone.getTimeZone("GMT"));
String dateTimeString =  sdf.format(new Date());
shahtapa
sumber
5

Inilah implementasi toUTC saya:

    public static Date toUTC(Date date){
    long datems = date.getTime();
    long timezoneoffset = TimeZone.getDefault().getOffset(datems);
    datems -= timezoneoffset;
    return new Date(datems);
}

Mungkin ada beberapa cara untuk memperbaikinya, tetapi itu berhasil untuk saya.

Ashallar
sumber
3

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;

public class TimZoneTest {
    public static void 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") );


    }

    public static String 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 = new SimpleDateFormat(format);
        date_format_gmt.setTimeZone(tz);
        return date_format_gmt.format(date);
    }

}

Keluaran

10/08/2011 21: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
so_mv
sumber
3

Hanya untuk membuat ini lebih sederhana, untuk membuat Datedalam UTCAnda dapat menggunakan Calendar:

Calendar.getInstance(TimeZone.getTimeZone("UTC"));

Yang akan membangun contoh baru untuk Calendarmenggunakan "UTC" TimeZone.

Jika Anda memerlukan Dateobjek dari kalender itu, Anda bisa menggunakannya getTime().

Ovidiu Latcu
sumber
5
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 Zone

DateTime currDateTime = new DateTime(); //Current DateTime

long 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
Tuhanku
sumber
1
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!

    Date currDate;
    SimpleDateFormat dateFormatGmt = new SimpleDateFormat("yyyy-MMM-dd HH:mm:ss");
    dateFormatGmt.setTimeZone(TimeZone.getTimeZone("GMT"));
    SimpleDateFormat dateFormatLocal = new SimpleDateFormat("yyyy-MMM-dd HH:mm:ss");

    long currTime = 0;
    try {

        currDate = dateFormatLocal.parse( dateFormatGmt.format(new Date()) );
        currTime = currDate.getTime();
    } catch (ParseException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
Bogdan
sumber
2

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
{
private static final String TAG = "SntpClient";

private static final int RECEIVE_TIME_OFFSET = 32;
private static final int TRANSMIT_TIME_OFFSET = 40;
private static final int NTP_PACKET_SIZE = 48;

private static final int NTP_PORT = 123;
private static final int NTP_MODE_CLIENT = 3;
private static final int NTP_VERSION = 3;

// Number of seconds between Jan 1, 1900 and Jan 1, 1970
// 70 years plus 17 leap days
private static final long OFFSET_1900_TO_1970 = ((365L * 70L) + 17L) * 24L * 60L * 60L;

private long mNtpTime;

public boolean requestTime(String host, int timeout) {
    try {
        DatagramSocket socket = new DatagramSocket();
        socket.setSoTimeout(timeout);
        InetAddress address = InetAddress.getByName(host);
        byte[] buffer = new byte[NTP_PACKET_SIZE];
        DatagramPacket request = new DatagramPacket(buffer, buffer.length, address, NTP_PORT);

        buffer[0] = NTP_MODE_CLIENT | (NTP_VERSION << 3);

        writeTimeStamp(buffer, TRANSMIT_TIME_OFFSET);

        socket.send(request);

        // read the response
        DatagramPacket response = new DatagramPacket(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);
        return false;
    }

    return true;
}


public long getNtpTime() {
    return mNtpTime;
}


/**
 * Reads an unsigned 32 bit big endian number from the given offset in the buffer.
 */
private long 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 values
    int 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).
 */    
private long 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
 */    
private void 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:

private String get_UTC_Datetime_from_timestamp(long timeStamp){

    try{

        Calendar cal = Calendar.getInstance();
        TimeZone tz = cal.getTimeZone();

        int tzt = tz.getOffset(System.currentTimeMillis());

        timeStamp -= tzt;

        // DateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss",Locale.getDefault());
        DateFormat sdf = new SimpleDateFormat();
        Date netDate = (new Date(timeStamp));
        return sdf.format(netDate);
    }
    catch(Exception ex){
        return "";
     }
    } 

dan gunakan dengan:

String UTC_DateTime = get_UTC_Datetime_from_timestamp(now);
Ingo
sumber
Dalam satu baris <br/> <pre> <code> Kalender utcTime = Calendar.getInstance (). Tambahkan (Calendar.MILLISECOND, -time.getTimeZone (). GetOffset (time.getTimeInMillis ())); </pre> < / code>
Harun
1
Ya, tetapi ini memanggil Waktu Perangkat lokal, yang dapat diubah secara manual dari pengguna ke DateTime yang salah
Ingo
2
public static void main(String args[]){
    LocalDate date=LocalDate.now();  
    System.out.println("Current date = "+date);
}
Arjun Singh
sumber
1

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 ...

Hitesh
sumber
1

ini implementasi saya:

public static String GetCurrentTimeStamp()
{
    Calendar cal=Calendar.getInstance();
    long offset = cal.getTimeZone().getOffset(System.currentTimeMillis());//if you want in UTC else remove it .
    return new java.sql.Timestamp(System.currentTimeMillis()+offset).toString();    
}
Gal Rom
sumber
1

Jika Anda ingin menghindari penguraian tanggal dan hanya ingin cap waktu dalam GMT, Anda dapat menggunakan:

final Date gmt = new Timestamp(System.currentTimeMillis()
            - Calendar.getInstance().getTimeZone()
                    .getOffset(System.currentTimeMillis()));
Matthias van der Vlies
sumber
0

Jika Anda menggunakan waktu joda dan ingin waktu saat ini dalam milidetik tanpa offset lokal, Anda dapat menggunakan ini:

long instant = DateTimeZone.UTC.getMillisKeepLocal(DateTimeZone.getDefault(), System.currentTimeMillis());
Managarm
sumber
0
public class CurrentUtcDate 
{
    public static void main(String[] args) {
        Date date = new Date();
        SimpleDateFormat dateFormat = new SimpleDateFormat("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-2018 13:14:35

Anda dapat mengubah format tanggal sesuai kebutuhan.

santoshlokhande
sumber
1
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 );

atau

LocalDateTime now2 = LocalDateTime.now( ZoneOffset.UTC );

tergantung pada kebutuhan aplikasi Anda.

Seolah-olah
sumber
(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.
Basil Bourque