在 Java 中打印时差的最惯用方法?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2704473/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-29 22:25:46  来源:igfitidea点击:

Most idiomatic way to print a time difference in Java?

javadatetimeidiomscode-formatting

提问by Zombies

I'm familiar with printing time difference in milliseconds:

我熟悉以毫秒为单位的打印时间差:

 long time = System.currentTimeMillis();
 //do something that takes some time...
 long completedIn = System.currentTimeMillis() - time;

But, is there a nice way print a complete time in a specified format (eg: HH:MM:SS) either using Apache Commons or even the dreaded platform API's Date/Time objects? In other words, what is the shortest, simplest, no nonsense way to write a time format derived from milliseconds in Java?

但是,是否有一种使用 Apache Commons 甚至可怕的平台 API 的日期/时间对象以指定格式(例如:HH:MM:SS)打印完整时间的好方法?换句话说,在Java中编写从毫秒派生的时间格式的最短,最简单,没有废话的方法是什么?

回答by Bill the Lizard

Apache Commons has the DurationFormatUtilsclass for applying a specified format to a time duration. So, something like:

Apache Commons 具有DurationFormatUtils类,用于将指定格式应用于持续时间。所以,像这样:

long time = System.currentTimeMillis();
//do something that takes some time...
long completedIn = System.currentTimeMillis() - time;

DurationFormatUtils.formatDuration(completedIn, "HH:mm:ss:SS");

回答by trashgod

A library designed for the purpose is the better approach, but SimpleDateFormatwith the right TimeZonemay suffice for periods less than a day. Longer periods require treating the day specially.

为此目的而设计的库是更好的方法,但如果SimpleDateFormat使用正确的方法,则TimeZone可能在不到一天的时间内就足够了。更长的时间需要特别对待这一天。

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

public class Elapsed {

    private static final long MS_DAY = 24 * 60 * 60 * 1000;
    private final DateFormat df = new SimpleDateFormat("HH : mm : ss : S");

    public Elapsed() {
        df.setTimeZone(TimeZone.getTimeZone("GMT"));
    }

    private String format(long elapsed) {
        long day = elapsed / MS_DAY;
        StringBuilder sb = new StringBuilder();
        sb.append(day);
        sb.append(" : ");
        sb.append(df.format(new Date(elapsed)));
        return sb.toString();
    }

    public static void main(String[] args) {
        Elapsed e = new Elapsed();
        for (long t = 0; t < 3 * MS_DAY; t += MS_DAY / 2) {
            System.out.println(e.format(t));
        }
    }
}

Console output:

控制台输出:

0 : 00 : 00 : 00 : 0
0 : 12 : 00 : 00 : 0
1 : 00 : 00 : 00 : 0
1 : 12 : 00 : 00 : 0
2 : 00 : 00 : 00 : 0
2 : 12 : 00 : 00 : 0

回答by Basil Bourque

tl;dr

tl;博士

Duration.ofMillis( … )
        .toString()

…or…

…或者…

Duration.between(      // `Duration` represents a span of time unattached to the timeline, in a scale of days-hours-minutes-seconds-nanos.
    instantEarlier ,   // Capture the current moment to start.
    Instant.now()      // Capture the current moment now, in UTC.
)                      // Returns a `Duration` object.
.toString()            // Generate a string in standard ISO 8601 format.

PT1M23.407S

PT1M23.407S

ISO 8601

ISO 8601

what is the shortest, simplest, no nonsense way to write a time format derived from milliseconds

编写从毫秒派生的时间格式的最短,最简单,没有废话的方法是什么

The ISO 8601standard defines textual formats for date-time values. These formats are indeed short, simple, and no-nonsense. They are largely human-readable across various cultures, practical, and unambiguous.

ISO 8601标准定义为考证日期时间值的格式。这些格式确实简短、简单且没有废话。它们在不同文化中基本上是人类可读的,实用且明确。

For spans of time unattached to the timeline, the standard formatis PnYnMnDTnHnMnS. The Pmarks the beginning, and the Tseparates the years-month-days from the hours-minutes-seconds. So an hour and a half is PT1H30M.

对于未附加到时间线的时间跨度,标准格式PnYnMnDTnHnMnS. 该P标记的开始,而T分离小时-分-秒年-月-日。所以一个半小时是PT1H30M

java.time.Duration

java.time.Duration

The java.time classes include a pair of classes to represent spans of time. The Durationclass is for hours-minutes-seconds, and Period.

java.time 类包括一对表示时间跨度的类。该Duration课程以小时-分钟-秒为单位,并且Period.

Instant

Instant

The Instantclass represents a moment on the timeline in UTCwith a resolution of nanoseconds(up to nine (9) digits of a decimal fraction).

Instant级表示时间轴上的时刻UTC,分辨率为纳秒(最多小数的9个位数)。

Instant earlier = Instant.now() ;  // Capture the current moment in UTC.
… 
Instant later = Instant.now() ;

Duration d = Duration.between( earlier , later ) ;
String output = d.toString() ;  

PT3.52S

PT3.52S



About java.time

关于java.time

The java.timeframework is built into Java 8 and later. These classes supplant the troublesome old legacydate-time classes such as java.util.Date, Calendar, & SimpleDateFormat.

java.time框架是建立在Java 8和更高版本。这些类取代了麻烦的旧的遗留日期时间类,例如java.util.Date, Calendar, & SimpleDateFormat

The Joda-Timeproject, now in maintenance mode, advises migration to the java.timeclasses.

现在处于维护模式Joda-Time项目建议迁移到java.time类。

To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310.

要了解更多信息,请参阅Oracle 教程。并在 Stack Overflow 上搜索许多示例和解释。规范是JSR 310

You may exchange java.timeobjects directly with your database. Use a JDBC drivercompliant with JDBC 4.2or later. No need for strings, no need for java.sql.*classes.

您可以直接与数据库交换java.time对象。使用符合JDBC 4.2或更高版本的JDBC 驱动程序。不需要字符串,不需要类。java.sql.*

Where to obtain the java.time classes?

从哪里获得 java.time 类?

The ThreeTen-Extraproject extends java.time with additional classes. This project is a proving ground for possible future additions to java.time. You may find some useful classes here such as Interval, YearWeek, YearQuarter, and more.

ThreeTen-额外项目与其他类扩展java.time。该项目是未来可能添加到 java.time 的试验场。你可能在这里找到一些有用的类,比如IntervalYearWeekYearQuarter,和更多

回答by Michael Borgwardt

If you actually want to see a millisecond difference, I don't think there's a shorter, simpler way.

如果您真的想看到毫秒差异,我认为没有更短、更简单的方法。

If you need a more powerful (but certainly not simpler) way to collect performance statistics, there is Perf4J.

如果您需要一种更强大(但肯定不是更简单)的方法来收集性能统计信息,则可以使用Perf4J

回答by Thorbj?rn Ravn Andersen

Not to my knowledge. But printf()can do this easily if you calculate the values for H, M and S, and use a %02 pattern for each.

据我所知不是。但是如果您计算 H、M 和 S 的值,并为每个值使用 %02 模式,printf()可以轻松完成此操作。

回答by Dmitry Podobedov

long diff = System.currentTimeMillis() - startTime;
int hours = (int)(diff / 3600000); diff -= hours * 3600000;
int mins = (int)(diff / 60000); diff -= mins * 60000;
int secs = (int)(diff / 1000); diff -= secs * 1000;
System.out.println(String.format("%d:%d:%d.%d", hours, mins, secs, diff));