Chuyển đổi dấu thời gian tính bằng mili giây sang chuỗi thời gian được định dạng trong Java


125

Tôi đang cố gắng chuyển đổi một giá trị dài ( số mili giây trôi qua từ 1/1/1970 tức là Epoch ) sang thời gian định dạng h:m:s:ms.

Giá trị dài tôi sử dụng làm dấu thời gian, tôi nhận được từ trường timestampcủa một sự kiện đăng nhập từ log4j.

Cho đến nay tôi đã thử những điều sau đây và nó thất bại:

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

nhưng tôi nhận được giá trị không chính xác:

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

Làm thế nào để tôi đi về điều này?

Câu trả lời:


187

Thử cái này:

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

Xem SimpleDateFormat để biết mô tả về các chuỗi định dạng khác mà lớp chấp nhận.

Xem ví dụ có thể chạy bằng cách sử dụng đầu vào 1200 ms.


8
Nhận xét: HH sẽ in giờ vào ngày đó (0-23), không phải tổng số giờ đã trôi qua kể từ năm 1970. Chỉ cần nói.
JohnyTex

4
Và đừng quên. SimpleDateFormat cũ không thể được sử dụng đa luồng.
keiki

để nhập SimpleDateFormat, sử dụng nhập như sau:import java.text.*;
Naveen Kumar RB

1
FYI, người già lớp ngày thời gian phiền hà như java.util.Date, java.util.Calendarjava.text.SimpleDateFormatbây giờ là di sản , thay thế bởi sự java.time class built vào Java 8 và sau đó. Xem Hướng dẫn của Oracle . Xem: stackoverflow.com/a/4142428/642706
Basil Bourque

1
Loại logevent là gì? Bạn có thể vui lòng đặt câu hỏi không?
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);

13
Tôi thích giải pháp của bạn tốt hơn câu trả lời được chấp nhận vì nó rõ ràng hơn một chút và không gặp vấn đề với ngôn ngữ. Mặc dù bạn bỏ lỡ phần cuối cùng: millis = millis% 1000, điều này sẽ đặt đúng mili giây ở cuối chuỗi được định dạng.
Ondrej Burkert

7
@WesleyDeKeirsmaeker, nói chung, khả năng đọc quan trọng hơn sự đồng nhất.
Alphaaa

2
Tại sao còn lại với 24 giờ?
baboo

2
Bộ phận không liên kết: 50000 / (1000 * 60) = 0.8333333333 trong khi 50000/1000 * 60 = 3000.
farnett

3
'millis = millis% 1000' bị thiếu: D \ n và nếu bạn cần ngày, ở đây bạn đi: 'ngày dài = (millis / (1000 * 60 * 60 * 24));'
Adreamus

38

Tôi sẽ chỉ cho bạn ba cách để (a) lấy trường phút từ một giá trị dài và (b) in nó bằng định dạng Ngày bạn muốn. Một cái sử dụng java.util.CalWiki , một cái khác sử dụng Joda-Time và cái cuối cùng sử dụng khung java.time được tích hợp trong Java 8 trở lên.

Khung công tác java.time thay thế các lớp thời gian được đóng gói cũ và được lấy cảm hứng từ Joda-Time, được định nghĩa bởi JSR 310 và được mở rộng bởi dự án ThreeTen-Extra.

Khung công tác java.time là cách để sử dụng khi sử dụng Java 8 trở lên. Nếu không, chẳng hạn như Android, hãy sử dụng Joda-Time. Các lớp java.util.Date/.CalWiki nổi tiếng là rắc rối và nên tránh.

java.util.Date & .CalWiki

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-Thời gian

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

Đầu ra:

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

java.time

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

mili giâySinceEpoch: 1289375173771 tức thì: 2010-11-10T07: 46: 13.771Z đầu ra: 07: 46: 13: 771


1
Có bất kỳ lý do hiệu suất hoặc bất kỳ lý do nào khác, tôi nên ưu tiên Joda hơn Lịch?
Cratylus

1
trong những trường hợp đơn giản như thế này thì không. Nói chung: Api của Joda được thiết kế tốt hơn. ví dụ: Ngày java là Joda DateTimes có thể thay đổi được. Joda cũng thân thiện với lập trình viên hơn, bạn có thể truy cập gần như tất cả các chức năng từ lớp DateTime mà không phải chuyển đổi qua lại giữa Ngày và Lịch
Sean Patrick Floyd

nó có bất kỳ sự phụ thuộc nào tôi nên biết không?
Cratylus

2
Câu trả lời hay, nhưng tôi cũng đề nghị chỉ định múi giờ thay vì dựa hoàn toàn vào múi giờ mặc định hiện tại của JVM. Vì vậy, lệnh gọi hàm tạo của DateTime sẽ có một đối số thứ hai, một DateTimeZoneđối tượng. Như thế này:new DateTime( timestamp, DateTimeZone.forID( "America/Montreal" ) )
Basil Bourque

2
@Cratylus Các lớp java.time thay thế cả Joda-Time và các lớp thời gian cũ kế thừa được gói cùng với Java. Joda-Time đã truyền cảm hứng cho các lớp java.time, cả hai dự án được dẫn dắt bởi cùng một người đàn ông, Stephen Colbourne.
Basil Bourque

22

Có thể sử dụng apache commons (commons-lang3) và lớp WeatherFormatUtils của nó.

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

Ví dụ:

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"

Hy vọng nó có thể giúp ...


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

2
Điều này có vẻ không đúng. Chẳng TimeUnit.MILLISECONDS.toSeconds()hạn, có chuyển đổi mili giây thành cùng thời lượng tính bằng giây hay giây còn lại sau khi trừ giờ và phút không? Các giải pháp đòi hỏi sau này.
Derek Mahar

Phương pháp này không chính xác, nó trả về 431220: 25873204: 1552392282: 0 nếu tôi muốn chuyển đổi ngày 12 tháng 3 năm 2019 lúc
13h04

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

4

Đang làm

logEvent.timeStamp / (1000*60*60)

sẽ cho bạn giờ, không phải phút. Thử:

logEvent.timeStamp / (1000*60)

và bạn sẽ kết thúc với câu trả lời tương tự như

TimeUnit.MILLISECONDS.toMinutes(logEvent.timeStamp)

Nhưng TimeUnit.MILLISECONDS.toMinutes (logEvent.timeStamp) cũng cho rác của tôi. 21489586 không phải là phút!
Cratylus

1
Đó là số phút trôi qua kể từ ngày 01/01/1970.
Nico Huysamen

Ok, vậy làm thế nào để tôi có được định dạng tôi muốn? Tức là 10: 50: 40: 450? Tôi không biết cách sử dụng số phút kể từ năm 1970.
Cratylus

O xin lỗi, chỉ nghĩ rằng bạn muốn biết làm thế nào để có ý nghĩa của nó. Xem bài viết của seanizer, nên bao gồm nó.
Nico Huysamen

3

Thử cái này:

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

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);
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.