Java:如何将字符串(HH:MM:SS)转换为持续时间?tl;博士避免格式HH:MM:SSjava.time关于 java.time

2022-09-02 05:11:44

我想将格式为HH:MM:SS或MM:SS或SS的字符串转换为持续时间的数据类型。

溶液:

    private ArrayList<Duration> myCdDuration = new ArrayList<Duration>();

        private void convert(String aDuration) {

            chooseNewDuration(stringToInt(splitDuration(aDuration))); //stringToInt() returns an int[] and splitDuration() returns a String[]
        }

        private void chooseNewDuration(int[] array) {
            int elements = array.length;
            switch (elements) {
            case 1:
                myCdDuration.add(newDuration(true, 0, 0, 0, 0, 0, array[0]));
                break;
            case 2:
                myCdDuration.add(newDuration(true, 0, 0, 0, 0, array[0], array[1]));
                break;
            case 3:
                myCdDuration.add(newDuration(true, 0, 0, 0, array[0], array[1],
                        array[2]));
                break;
            }
        }

感谢您的帮助...任何更简单的方法来做到这一点?->创建自己的持续时间类:

public class Duration {
        private int intSongDuration;
        private String printSongDuration;

        public String getPrintSongDuration() {
            return printSongDuration;
        }

        public void setPrintSongDuration(int songDuration) {
            printSongDuration = intToStringDuration(songDuration);
        }

        public int getIntSongDuration() {
            return intSongDuration;
        }

        public void setIntSongDuration(int songDuration) {
            intSongDuration = songDuration;
        }

        public Duration(int songDuration) {

            setIntSongDuration(songDuration);
        }

将 int 值转换为字符串以进行输出/打印:

private String intToStringDuration(int aDuration) {
    String result = "";

    int hours = 0, minutes = 0, seconds = 0;

    hours = aDuration / 3600;
    minutes = (aDuration - hours * 3600) / 60;
    seconds = (aDuration - (hours * 3600 + minutes * 60));

    result = String.format("%02d:%02d:%02d", hours, minutes, seconds);
    return result;
}

答案 1

tl;博士

无需定义自己的类,因为 Java 提供了一个。Duration

Duration.between (                  // Represent a span of time of hours, minutes, seconds. 
    LocalTime.MIN ,                 // 00:00:00
    LocalTime.parse ( "08:30:00" )  // Parse text as a time-of-day. 
)                                   // Returns a `Duration` object, a span-of-time. 
.toString()                         // Generate a `String` with text in standard ISO 8601 format. 

PT8H30M

并解析标准ISO 8601格式的文本。

Duration.parse( "PT8H30M" )   // Parse standard ISO 8601 text yo get a `Duration` object. 

Table of span-of-time classes in Java and in the ThreeTen-Extra project


避免格式HH:MM:SS

如果字符串的意思是“八个半小时”的时间跨度,而不是一天中的时间“早上八点半”,那么请避免使用.这种格式模棱两可,似乎是一天中的时间。请改用下面讨论的标准 ISO 8601 格式。08:30:00HH:MM:SS

持续时间和一天中的时间是两个非常不同的概念。你必须清楚它们,每个在你的脑海中都应该是不同的。使用 HH:MM:SS 的模糊格式会使这种区分变得更加困难(因此请避免使用该格式!

java.time

现代的方式是java.time类。

LocalTime

首先将字符串解析为 LocalTime。此类表示一天中没有日期和时区的时间。没有时区意味着这些对象基于通用的 24 小时制,而不考虑异常情况,如夏令时 (DST)。

我们并不真正想要 a,因为您的输入字符串表示时间跨度,而不是一天中的时间。但这只是第一步。LocalTime

LocalTime lt = LocalTime.parse ( "08:30:00" );

Duration

为了表示所需的时间跨度,我们需要 Duration 类。此类适用于未附加到时间线的时间跨度。我们可以通过从时间时钟或LocalTime.MIN开始获取时间量以及我们刚刚实例化的时间量来创建一个。LocalTime00:00:00.0lt

Duration d = Duration.between ( LocalTime.MIN , lt );

编辑输入字符串

上述使用方法仅在输入字符串表示持续时间小于 24 小时时才有效。如果超过 24 小时,您将自行解析输入字符串。LocalTime

类似于下面的代码。当然,实际的解析取决于解决特定输入字符串的歧义。是五十小时还是五十分钟?(这种模糊性是尽可能避免这种令人困惑的格式并坚持使用ISO 8601格式的有力理由。50:00

String input = "50:00";  // Or "50:00:00" (fifty hours, either way)

String[] parts = input.split ( ":" );
Duration d = Duration.ZERO;
if ( parts.length == 3 ) {
    int hours = Integer.parseInt ( parts[ 0 ] );
    int minutes = Integer.parseInt ( parts[ 1 ] );
    int seconds = Integer.parseInt ( parts[ 2 ] );
    d = d.plusHours ( hours ).plusMinutes ( minutes ).plusSeconds ( seconds );
} else if ( parts.length == 2 ) {
    int hours = Integer.parseInt ( parts[ 0 ] );
    int minutes = Integer.parseInt ( parts[ 1 ] );
    d = d.plusHours ( hours ).plusMinutes ( minutes );
} else {
    System.out.println ( "ERROR - Unexpected input." );
}

国际标准化组织 ISO 8601

我们可以通过简单地调用 Duration::toString 来生成标准 ISO 8601 格式的持续时间字符串来查看结果。java.time 类在解析/生成字符串时默认使用 ISO 8601。对于持续时间,标准格式是标记开始的地方,并将年-月-日部分与小时-分钟-秒部分分开。因此,我们的八个半小时将显示为 .PnYnMnDTnHnMnSPTPT8H30M

System.out.println ( “d.toString(): ” + d );

d.toString(): PT8H30M

收集对象Duration

您可以使 类型的保留元素。ListDuration

List<Duration> durations = new ArrayList<>( 3 );  // Initial capacity of 3 elements.
durations.add( d ) ;
durations.add( Duration.between ( LocalTime.MIN , LocalTime.parse ( "03:00:00" ) ) ) ;
durations.add( Duration.between ( LocalTime.MIN , LocalTime.parse ( "01:15:00" ) ) ) ;

Durations.toString(): [PT8H30M, PT3H, PT1H15M]

请记住,您在该输出中看到的字符串就是这样:生成的字符串的输出。该类型不是简单的字符串,而是通过其 toString 方法生成 String 对象。PT8H30MDuration

如果您坚持使用ISO 8601格式,则可以轻松解析和生成此类字符串。无需完成我们在此答案顶部执行的转换rigamarole。LocalTime

Duration d = Duration.parse( "PT8H30M" );

IdeOne.com 中实时查看此示例代码。


关于 java.time

java.time 框架内置于 Java 8 及更高版本中。这些类取代了麻烦的旧日期时间类,如java.util.DateCalendarSimpleDateFormat

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

要了解更多信息,请参阅 Oracle 教程。搜索 Stack Overflow 以获取许多示例和解释。规格是JSR 310

从哪里获取 java.time 类?

ThreeTen-Extra 项目通过其他类扩展了 java.time。这个项目是未来可能添加到java.time的试验场。您可以在此处找到一些有用的课程,例如IntervalYearWeekYearQuarter


答案 2

我假设您最终要实现的是以秒为单位计算CD的持续时间。

有几种方法可以做到这一点,但我认为最直接的是拆分以获取小时,分钟和秒字段,然后手动计算持续时间::

String timestampStr = "14:35:06";
String[] tokens = timestampStr.split(":");
int hours = Integer.parseInt(tokens[0]);
int minutes = Integer.parseInt(tokens[1]);
int seconds = Integer.parseInt(tokens[2]);
int duration = 3600 * hours + 60 * minutes + seconds;