Konversi cap waktu dalam milidetik ke string yang diformat waktu di Jawa

126

Saya mencoba untuk mengkonversi nilai panjang ( jumlah milidetik berlalu dari 1/1/1970 yaitu Epoch ) ke waktu format h:m:s:ms.

Nilai panjang yang saya gunakan sebagai cap waktu, saya dapatkan dari bidang timestampacara logging dari log4j.

Sejauh ini saya sudah mencoba yang berikut dan gagal:

logEvent.timeStamp/ (1000*60*60)
TimeUnit.MILLISECONDS.toMinutes(logEvent.timeStamp)

tapi saya mendapatkan nilai yang salah:

1289375173771 for logEvent.timeStamp
358159  for logEvent.timeStamp/ (1000*60*60) 
21489586 for TimeUnit.MILLISECONDS.toMinutes(logEvent.timeStamp)

Bagaimana saya melakukannya?

Cratylus
sumber

Jawaban:

188

Coba ini:

Date date = new Date(logEvent.timeSTamp);
DateFormat formatter = new SimpleDateFormat("HH:mm:ss.SSS");
formatter.setTimeZone(TimeZone.getTimeZone("UTC"));
String dateFormatted = formatter.format(date);

Lihat SimpleDateFormat untuk deskripsi string format lain yang diterima kelas.

Lihat contoh runnable menggunakan input 1200 ms.

manolowar
sumber
8
Komentar: HH akan mencetak jam pada tanggal tersebut (0-23), bukan jumlah total jam yang telah berlalu sejak tahun 1970. Katakan saja.
JohnyTex
4
Dan jangan lupa. SimpleDateFormat lama tidak dapat digunakan multithreaded.
keiki
untuk mengimpor SimpleDateFormat, gunakan impor sebagai berikut:import java.text.*;
Naveen Kumar RB
1
FYI, 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 . Lihat: stackoverflow.com/a/4142428/642706
Basil Bourque
1
apa jenis logevent? Bisakah Anda memasukkan Pertanyaan?
Raulp
127
long millis = durationInMillis % 1000;
long second = (durationInMillis / 1000) % 60;
long minute = (durationInMillis / (1000 * 60)) % 60;
long hour = (durationInMillis / (1000 * 60 * 60)) % 24;

String time = String.format("%02d:%02d:%02d.%d", hour, minute, second, millis);
Brajendra Pandey
sumber
13
Saya menyukai solusi Anda lebih baik daripada jawaban yang diterima karena sedikit lebih eksplisit dan tidak mengalami masalah dengan lokal. Meskipun Anda melewatkan bagian terakhir: milis = milis% 1000, yang akan menempatkan milidetik di akhir string yang diformat.
Ondrej Burkert
7
@WesleyDeKeirsmaeker, secara umum, keterbacaan lebih penting daripada keringkasan.
Alphaaa
2
mengapa sisanya dengan 24 jam?
baboo
2
Divisi tidak asosiatif: 50000 / (1000 * 60) = 0,8333333333 sedangkan 50000/1000 * 60 = 3000.
farnett
3
'millis = millis% 1000' tidak ada: D \ n dan jika Anda perlu berhari-hari, ini dia: 'hari yang panjang = (milis / (1000 * 60 * 60 * 24));'
Adreamus
38

Saya akan menunjukkan kepada Anda tiga cara untuk (a) mendapatkan bidang menit dari nilai yang panjang, dan (b) mencetaknya menggunakan format Tanggal yang Anda inginkan. Satu menggunakan java.util.Calendar , yang lain menggunakan Joda-Time , dan yang terakhir menggunakan kerangka java.time yang dibangun ke dalam Java 8 dan yang lebih baru.

Kerangka java.time menggantikan kelas tanggal-waktu yang dibundel lama, dan terinspirasi oleh Joda-Time, didefinisikan oleh JSR 310, dan diperpanjang oleh proyek ThreeTen-Extra.

Kerangka java.time adalah cara untuk pergi ketika menggunakan Java 8 dan yang lebih baru. Kalau tidak, seperti Android, gunakan Joda-Time. Kelas java.util.Date/.Calendar terkenal merepotkan dan harus dihindari.

java.util.Date & .Calendar

final long timestamp = new Date().getTime();

// with java.util.Date/Calendar api
final Calendar cal = Calendar.getInstance();
cal.setTimeInMillis(timestamp);
// here's how to get the minutes
final int minutes = cal.get(Calendar.MINUTE);
// and here's how to get the String representation
final String timeString =
    new SimpleDateFormat("HH:mm:ss:SSS").format(cal.getTime());
System.out.println(minutes);
System.out.println(timeString);

Joda-Time

// with JodaTime 2.4
final DateTime dt = new DateTime(timestamp);
// here's how to get the minutes
final int minutes2 = dt.getMinuteOfHour();
// and here's how to get the String representation
final String timeString2 = dt.toString("HH:mm:ss:SSS");
System.out.println(minutes2);
System.out.println(timeString2);

Keluaran:

24
09: 24: 10: 254
24
09: 24: 10: 254

waktu java

long millisecondsSinceEpoch = 1289375173771L;
Instant instant = Instant.ofEpochMilli ( millisecondsSinceEpoch );
ZonedDateTime zdt = ZonedDateTime.ofInstant ( instant , ZoneOffset.UTC );

DateTimeFormatter formatter = DateTimeFormatter.ofPattern ( "HH:mm:ss:SSS" );
String output = formatter.format ( zdt );

System.out.println ( "millisecondsSinceEpoch: " + millisecondsSinceEpoch + " instant: " + instant + " output: " + output );

millisecondsSejakEpoch: 1289375173771 instan: 2010-11-10T07: 46: 13.771Z output: 07: 46: 13: 771

Sean Patrick Floyd
sumber
1
Apakah ada alasan kinerja atau alasan lain, saya harus lebih memilih Joda daripada Kalender?
Cratylus
1
dalam kasus sederhana seperti ini, tidak. Secara umum: api Joda dirancang lebih baik. misal Tanggal java tidak bisa diubah Joda DateTimes tidak. Joda juga lebih ramah terhadap programmer, Anda dapat mengakses hampir semua fungsi dari kelas DateTime tanpa harus mengonversi bolak-balik antara Date dan Calendar
Sean Patrick Floyd
apakah ada dependensi yang harus saya ketahui?
Cratylus
2
Jawaban yang bagus, tetapi saya sarankan juga menentukan zona waktu daripada bergantung secara implisit pada zona waktu default JVM saat ini. Jadi panggilan ke konstruktor DateTime akan memiliki argumen kedua, sebuah DateTimeZoneobjek. Seperti ini:new DateTime( timestamp, DateTimeZone.forID( "America/Montreal" ) )
Basil Bourque
2
@Cratylus Kelas java.time menggantikan kedua Joda-Time dan kelas lama tanggal-waktu lama yang digabungkan dengan Java. Joda-Time menginspirasi kelas java.time, kedua proyek dipimpin oleh orang yang sama, Stephen Colbourne.
Basil Bourque
22

Dimungkinkan untuk menggunakan apache commons (commons-lang3) dan kelas DurationFormatUtils nya.

<dependency>
  <groupId>org.apache.commons</groupId>
  <artifactId>commons-lang3</artifactId>
  <version>3.1</version>
</dependency>

Sebagai contoh:

String formattedDuration = DurationFormatUtils.formatDurationHMS(12313152);
// formattedDuration value is "3:25:13.152"
String otherFormattedDuration = DurationFormatUtils.formatDuration(12313152, DurationFormatUtils.ISO_EXTENDED_FORMAT_PATTERN);
// otherFormattedDuration value is "P0000Y0M0DT3H25M13.152S"

Semoga bisa membantu ...

YoCha
sumber
8
long second = TimeUnit.MILLISECONDS.toSeconds(millis);
long minute = TimeUnit.MILLISECONDS.toMinutes(millis);
long hour = TimeUnit.MILLISECONDS.toHours(millis);
millis -= TimeUnit.SECONDS.toMillis(second);
return String.format("%02d:%02d:%02d:%d", hour, minute, second, millis);
Lo Ka
sumber
2
Ini sepertinya tidak benar. ApakahTimeUnit.MILLISECONDS.toSeconds() , misalnya, mengonversi milidetik ke durasi yang sama dalam detik atau sisa detik setelah mengurangi jam dan menit? Solusinya membutuhkan yang terakhir.
Derek Mahar
Metode ini tidak benar, ia kembali 431220: 25873204: 1552392282: 0 jika saya ingin mengonversi tanggal 12 maret 2019 pada 13h04 42s
0ddlyoko
6
public static String timeDifference(long timeDifference1) {
long timeDifference = timeDifference1/1000;
int h = (int) (timeDifference / (3600));
int m = (int) ((timeDifference - (h * 3600)) / 60);
int s = (int) (timeDifference - (h * 3600) - m * 60);

return String.format("%02d:%02d:%02d", h,m,s);
Vivek Pal
sumber
4

Perbuatan

logEvent.timeStamp / (1000*60*60)

akan memberi Anda jam, bukan menit. Mencoba:

logEvent.timeStamp / (1000*60)

dan Anda akan berakhir dengan jawaban yang sama dengan

TimeUnit.MILLISECONDS.toMinutes(logEvent.timeStamp)
Nico Huysamen
sumber
Tetapi TimeUnit.MILLISECONDS.toMinutes (logEvent.timeStamp) juga memberikan sampah saya. 21489586 bukan menit!
Cratylus
1
Ini adalah jumlah menit yang berlalu sejak 01/01/1970.
Nico Huysamen
Ok, jadi bagaimana cara mendapatkan format yang saya inginkan? Yaitu 10: 50: 40: 450? Saya tidak tahu bagaimana menggunakan jumlah menit sejak 1970.
Cratylus
O maaf, hanya berpikir Anda ingin tahu bagaimana cara memahaminya. Lihat posting oleh seanizer, yang harus menutupinya.
Nico Huysamen
3

Coba ini:

    String sMillis = "10997195233";
    double dMillis = 0;

    int days = 0;
    int hours = 0;
    int minutes = 0;
    int seconds = 0;
    int millis = 0;

    String sTime;

    try {
        dMillis = Double.parseDouble(sMillis);
    } catch (Exception e) {
        System.out.println(e.getMessage());
    }


    seconds = (int)(dMillis / 1000) % 60;
    millis = (int)(dMillis % 1000);

    if (seconds > 0) {
        minutes = (int)(dMillis / 1000 / 60) % 60;
        if (minutes > 0) {
            hours = (int)(dMillis / 1000 / 60 / 60) % 24;
            if (hours > 0) {
                days = (int)(dMillis / 1000 / 60 / 60 / 24);
                if (days > 0) {
                    sTime = days + " days " + hours + " hours " + minutes + " min " + seconds + " sec " + millis + " millisec";
                } else {
                    sTime = hours + " hours " + minutes + " min " + seconds + " sec " + millis + " millisec";
                }
            } else {
                sTime = minutes + " min " + seconds + " sec " + millis + " millisec";
            }
        } else {
            sTime = seconds + " sec " + millis + " millisec";
        }
    } else {
        sTime = dMillis + " millisec";
    }

    System.out.println("time: " + sTime);
LeoZao
sumber
0
    long hours = TimeUnit.MILLISECONDS.toHours(timeInMilliseconds);
    long minutes = TimeUnit.MILLISECONDS.toMinutes(timeInMilliseconds - TimeUnit.HOURS.toMillis(hours));
    long seconds = TimeUnit.MILLISECONDS
            .toSeconds(timeInMilliseconds - TimeUnit.HOURS.toMillis(hours) - TimeUnit.MINUTES.toMillis(minutes));
    long milliseconds = timeInMilliseconds - TimeUnit.HOURS.toMillis(hours)
            - TimeUnit.MINUTES.toMillis(minutes) - TimeUnit.SECONDS.toMillis(seconds);
    return String.format("%02d:%02d:%02d:%d", hours, minutes, seconds, milliseconds);
Joel Richard Koett
sumber