Bagaimana cara mengubah currentTimeMillis menjadi tanggal di Jawa?

140

Saya memiliki milidetik di file log tertentu yang dihasilkan di server, saya juga tahu lokal dari mana file log dihasilkan, masalah saya adalah mengkonversi milidetik ke tanggal dalam format yang ditentukan. Pemrosesan log itu terjadi di server yang terletak di zona waktu berbeda. Saat mengonversi ke program "SimpleDateFormat" berarti mengambil tanggal mesin karena tanggal yang diformat seperti itu tidak mewakili waktu server yang benar. Apakah ada cara untuk menangani ini dengan elegan?

long yourmilliseconds = 1322018752992l;
        //1322018752992-Nov 22, 2011 9:25:52 PM 

SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss,SSS",Locale.US);

GregorianCalendar calendar = new GregorianCalendar(TimeZone.getTimeZone("US/Central"));
calendar.setTimeInMillis(yourmilliseconds);

System.out.println("GregorianCalendar -"+sdf.format(calendar.getTime()));

DateTime jodaTime = new DateTime(yourmilliseconds, 
                    DateTimeZone.forTimeZone(TimeZone.getTimeZone("US/Central")));
DateTimeFormatter parser1 = DateTimeFormat.forPattern("yyyy-MM-dd HH:mm:ss,SSS");

System.out.println("jodaTime "+parser1.print(jodaTime));

Keluaran:

Gregorian Calendar -2011-11-23 08:55:52,992
jodaTime 2011-11-22 21:25:52,992
Amit
sumber
Jangan bingung Lokal dengan zona waktu. Benar-benar terpisah. Lokal menentukan bahasa manusia untuk nama bulan dan hari, dan norma budaya seperti urutan bagian seperti bulan, hari, dll. Zona waktu diimbangi-dari-UTC plus aturan untuk menangani anomali seperti Waktu Hemat Siang Hari.
Basil Bourque
Apakah masalah bahwa jumlah milidetik adalah hitungan bukan dari 1970-01-01T00: 00: 00Z tetapi dari saat lain?
Basil Bourque
FYI, kedua kelas tanggal-waktu lama yang mengerikan ( GregorianCalendar,, SimpleDateFormatdll.) Dan perpustakaan Joda-Time yang sangat baik sekarang digantikan oleh kelas java.time modern .
Basil Bourque

Jawaban:

115
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(timeStamp);

int mYear = calendar.get(Calendar.YEAR);
int mMonth = calendar.get(Calendar.MONTH);
int mDay = calendar.get(Calendar.DAY_OF_MONTH);
Faisal Ashraf
sumber
Saya harus menetapkan Kalender sebagai final untuk membuatnya berfungsi. final Calendar calendar = Calendar.getInstance();
Victor Augusto
4
Objek kalender umumnya dianggap cukup besar, jadi harus dihindari bila memungkinkan. Objek Date akan lebih baik dengan asumsi ia memiliki fungsi yang Anda butuhkan. "Tanggal tanggal = Tanggal baru (milis);" disediakan dalam jawaban lain oleh pengguna AVD akan menjadi rute terbaik :)
Dick Lucas
1
Entah bagaimana, untuk 1515436200000l, saya mendapatkan calendar.get(Calendar.MONTH))sebagai 0!
Sajib Acharya
FYI, sangat merepotkan tua kelas tanggal-waktu seperti java.util.Date, java.util.Calendar, dan java.text.SimpleDateFormatsekarang warisan , digantikan oleh java.time kelas dibangun ke Jawa 8 dan kemudian. Lihat Tutorial oleh Oracle .
Basil Bourque
2
@SajibAcharya Perhatikan bahwa instance untuk Calendar.MONTH mulai dari 0; Anda perlu menambahkan satu untuk mendapatkan bulan "nyata" seperti yang kita tahu. Contoh: 0 = Januari, 1 = Februari, 2 = Maret, dll.
shagberg
256

Anda dapat menggunakan java.util.Datekelas dan kemudian gunakan SimpleDateFormatuntuk memformat Date.

Date date=new Date(millis);

Kita bisa menggunakan paket java.time (tutorial) - API DateTime diperkenalkan di Java SE 8.

var instance = java.time.Instant.ofEpochMilli(millis);
var localDateTime = java.time.LocalDateTime
                        .ofInstant(instance, java.time.ZoneId.of("Asia/Kolkata"));
var zonedDateTime = java.time.ZonedDateTime
                            .ofInstant(instance,java.time.ZoneId.of("Asia/Kolkata"));

// Format the date

var formatter = java.time.format.DateTimeFormatter.ofPattern("u-M-d hh:mm:ss a O");
var string = zonedDateTime.format(formatter);
adatapost
sumber
2
Jauh lebih efisien.
Chad Bingham
2
Nggak. Tidak semua metode java.util.Datedisusutkan. (Ada API Tanggal & Waktu yang diperbaiki di JDK8 java.time)
adatapost
1
@RafaelZeffa, konstruktor '' 'Tanggal (tanggal lama)' '' tidak ditinggalkan
Gugelhupf
Objek Date disediakan untuk kompatibilitas ke belakang. Lebih baik gunakan Kalender seperti yang disarankan di atas.
Ton Snoei
2
FYI, sangat merepotkan tua kelas tanggal-waktu seperti java.util.Date, java.util.Calendar, dan java.text.SimpleDateFormatsekarang warisan , digantikan oleh java.time kelas dibangun ke Jawa 8 dan kemudian. Lihat Tutorial oleh Oracle .
Basil Bourque
24

tl; dr

Instant.ofEpochMilli( 1_322_018_752_992L )     // Parse count of milliseconds-since-start-of-1970-UTC into an `Instant`.
       .atZone( ZoneId.of( "Africa/Tunis" ) )  // Assign a time zone to the `Instant` to produce a `ZonedDateTime` object.

Detail

Jawaban lain menggunakan kelas yang ketinggalan zaman atau salah.

Hindari kelas tanggal-waktu lama seperti java.util.Date/.Calendar. Mereka terbukti dirancang dengan buruk, membingungkan, dan merepotkan.

waktu java

The java.time kerangka datang dibangun ke Jawa 8 dan kemudian. Banyak fungsi yang di- backport ke Java 6 & 7 dan selanjutnya diadaptasi ke Android . Dibuat oleh beberapa orang yang sama seperti yang dibuat Joda-Time .

An Instantadalah momen di timeline dalam UTC dengan resolusi nanodetik . Its zaman adalah saat pertama tahun 1970 di UTC.

Dengan asumsi data input Anda adalah hitungan milidetik dari 1970-01-01T00: 00: 00Z (tidak jelas dalam Pertanyaan), maka kita dapat dengan mudah membuat contoh Instant.

Instant instant = Instant.ofEpochMilli( 1_322_018_752_992L );

instant.toString (): 2011-11-23T03: 25: 52.992Z

The Zdalam standar ISO 8601 string yang diformat adalah singkatan Zuludan sarana UTC .

Terapkan zona waktu menggunakan nama zona waktu yang tepat , untuk mendapatkan a ZonedDateTime.

ZoneId zoneId = ZoneId.of( "Asia/Kolkata" ) ;
ZonedDateTime zdt = instant.atZone( zoneId );

Lihat kode ini berjalan langsung di IdeOne.com .

Asia/Kolkata zona waktu ?

Saya menduga Anda memiliki zona waktu India yang memengaruhi kode Anda. Kami melihat di sini bahwa penyesuaian ke Asia/Kolkatazona waktu membuat waktu yang sama dengan yang Anda laporkan, 08:55yaitu lima setengah jam lebih awal dari nilai UTC kami 03:25.

2011-11-23T08: 55: 52.992 + 05: 30 [Asia / Kolkata]

Zona default

Anda dapat menerapkan zona waktu default JVM saat ini. Hati-hati karena default dapat berubah kapan saja selama runtime . Kode apa pun di utas aplikasi mana pun dalam JVM dapat mengubah default saat ini. Jika penting, minta pengguna untuk zona waktu yang diinginkan / diharapkan.

ZoneId zoneId = ZoneId.systemDefault();
ZonedDateTime zdt = ZonedDateTime.ofInstant( instant , zoneId );

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.

Proyek Joda-Time , sekarang dalam mode pemeliharaan , menyarankan migrasi ke kelas java.time .

Untuk mempelajari lebih lanjut, lihat Tutorial Oracle . Dan cari Stack Overflow untuk banyak contoh dan penjelasan. Spesifikasi adalah JSR 310 .

Dengan driver JDBC yang mematuhi JDBC 4.2 atau yang lebih baru, Anda dapat bertukar objek java.time secara langsung dengan database Anda. Tidak perlu untuk string atau kelas java.sql. *.

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 .

Basil Bourque
sumber
Apakah mudah untuk mengonversi Instan yang Anda rekomendasikan di atas ke zona waktu lokal yang merupakan default pada perangkat (misalnya, smartphone)?
AJW
1
@ AJW Ya. Panggil ZoneId.systemDefault(). Lihat bagian baru yang ditambahkan di akhir Jawaban saya.
Basil Bourque
Luar biasa, saya akan mencobanya.
AJW
14

Cara termudah untuk melakukan ini adalah dengan menggunakan kelas Joda DateTime dan tentukan cap waktu dalam milidetik dan DateTimeZone yang Anda inginkan.

Saya sangat menyarankan menghindari kelas Tanggal dan Kalender Java bawaan; mereka mengerikan.

Cameron Skinner
sumber
GorgianCalender tidak berfungsi ... untuk alasan apa pun butuh zona waktu standar sistem. Joda bekerja dengan sempurna.
Amit
Biarkan saya tahu melihat kode sampel jika kita dapat melakukan sesuatu yang berbeda dengan Gregorian
Amit
1
FYI, proyek Joda-Time sekarang dalam mode pemeliharaan , menyarankan migrasi ke kelas java.time . Lihat Tutorial oleh Oracle .
Basil Bourque
13

Jika nilai millis adalah jumlah millis sejak 1 Januari 1970 GMT, seperti standar untuk JVM, maka itu tidak tergantung pada zona waktu. Jika Anda ingin memformatnya dengan zona waktu tertentu, Anda cukup mengonversinya menjadi objek GregorianCalendar dan mengatur zona waktu. Setelah itu ada banyak cara untuk memformatnya.

Tagihan
sumber
1
Ini adalah kode contoh dengan GregorianCalendar dan Joda, saya mendapatkan hasil yang benar dengan Joda tetapi tidak dengan kalender Gregorian GregorianCalendar = kalender GregorianCalendar baru (TimeZone.getTimeZone ("US / Central")); calendar.setTimeInMillis (yourmilliseconds); DateTime jodaTime = DateTime baru (yourmilliseconds, DateTimeZone.forTimeZone (TimeZone.getTimeZone ("US / Central"))); DateTimeFormatter parser1 = DateTimeFormat.forPattern ("yyyy-MM-dd HH: mm: ss, SSS");
Amit
Mengatur zona waktu di objek kalender tidak berfungsi, tetapi pengaturannya di objek formatter tanggal tidak?
Bill
Apa itu DateTime dan DateTimeFormatter ??
SweetWisher ツ
11

Solusi saya

public class CalendarUtils {

    public static String dateFormat = "dd-MM-yyyy hh:mm";
    private static SimpleDateFormat simpleDateFormat = new SimpleDateFormat(dateFormat);

    public static String ConvertMilliSecondsToFormattedDate(String milliSeconds){
        Calendar calendar = Calendar.getInstance();
        calendar.setTimeInMillis(Long.parseLong(milliSeconds));
        return simpleDateFormat.format(calendar.getTime());
    }
}
Siddarth Kanted
sumber
6

Saya melakukannya seperti ini:

static String formatDate(long dateInMillis) {
    Date date = new Date(dateInMillis);
    return DateFormat.getDateInstance().format(date);
}

Anda juga dapat menggunakan getDateInstance(int style)dengan parameter berikut:

DateFormat.SHORT

DateFormat.MEDIUM

DateFormat.LONG

DateFormat.FULL

DateFormat.DEFAULT

Yogesh Umesh Vaity
sumber
5

Kelas SimpleDateFormat memiliki metode yang disebut SetTimeZone (TimeZone) yang diwarisi dari kelas DateFormat. http://docs.oracle.com/javase/6/docs/api/java/text/DateFormat.html

Jessica Brown
sumber
FYI, kelas-kelas yang mengerikan itu sekarang digantikan oleh kelas java.time modern sejak adopsi JSR 310.
Basil Bourque
5

Cara termudah:

private String millisToDate(long millis){

    return DateFormat.getDateInstance(DateFormat.SHORT).format(millis);
    //You can use DateFormat.LONG instead of SHORT

}
Joaquin Iurchuk
sumber
2

Di bawah ini adalah solusi saya untuk mendapatkan tanggal dari milidetik ke format tanggal. Anda harus menggunakan Perpustakaan Joda untuk menjalankan kode ini.

import java.util.GregorianCalendar;
import java.util.TimeZone;

import org.joda.time.DateTime;
import org.joda.time.DateTimeZone;
import org.joda.time.format.DateTimeFormat;
import org.joda.time.format.DateTimeFormatter;

public class time {

    public static void main(String args[]){

        String str = "1431601084000";
        long geTime= Long.parseLong(str);
        GregorianCalendar calendar = new GregorianCalendar(TimeZone.getTimeZone("US/Central"));
        calendar.setTimeInMillis(geTime);
        DateTime jodaTime = new DateTime(geTime, 
               DateTimeZone.forTimeZone(TimeZone.getTimeZone("US/Central")));
        DateTimeFormatter parser1 = DateTimeFormat.forPattern("yyyy-MM-dd");
        System.out.println("Get Time : "+parser1.print(jodaTime));

   }
}
Archit
sumber
1

Anda dapat mencoba java.time api;

        Instant date = Instant.ofEpochMilli(1549362600000l);
        LocalDateTime utc = LocalDateTime.ofInstant(date, ZoneOffset.UTC);
Narendar Reddy M
sumber