Java:如何将字符串(HH:MM:SS)转换为持续时间?

Java:如何将字符串(HH:MM:SS)转换为持续时间?,java,string,duration,Java,String,Duration,我想将格式为HH:MM:SS或MM:SS或SS的字符串转换为持续时间的数据类型 解决方案: private ArrayList<Duration> myCdDuration = new ArrayList<Duration>(); private void convert(String aDuration) { chooseNewDuration(stringToInt(splitDuration(aDuration))

我想将格式为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;
            }
        }
将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;
}

我假设你最终想要达到的是以秒为单位计算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;
  • 您的
    myCdDuration
    令人困惑。您希望一个
    Duration
    对象等效于字符串中指定的内容,还是一个
    Duration
    对象列表,其中第一个对象包含小时、第二分钟等

  • 您不能将
    字符串
    强制转换为其他对象。您应该将该值解析为数字类型,并使用它来构造
    Duration
    对象

  • 我建议不要使用
    javax.xml.datatype.Duration
    ,因为它与XMLJavaAPI相关,如果不处理xml,使用它会让人困惑。此外,它是一个抽象类,在JavaSE中没有非抽象文档化的实现,因此您必须创建自己的非抽象实现或以某种方式获取实例(可能是使用XMLAPI)

    您可以使用
    Date
    Calendar
    类在Java中管理时间和日期。要将
    字符串
    s转换为
    日期
    /
    日历
    ,可以使用
    日期格式
    简化格式
    。这将允许您执行持续时间算术,尽管这不是100%的完美

    Mansoor提供了一种使用字符串操作和将持续时间作为数值处理来手动执行操作的方法——如果您只执行简单的操作,那么这样做可能更简单


    如果您必须执行更复杂的操作,您可能需要研究一下

    我在utils类中编写了这个方法来解析各种类型的持续时间字符串。它相当灵活:

    public static int getSecondsFromFormattedDuration(String duration){
            if(duration==null)
                return 0;
            try{
    
                Pattern patternDuration = Pattern.compile("\\d+(?::\\d+){0,2}");
    
                int hours = 0;
                int minutes = 0;
                int seconds = 0;
                if(patternDuration.matcher(duration).matches()){
                    String[] tokens = duration.split(":");
                    if(tokens.length==1){
                        seconds = Integer.parseInt(tokens[0]);
                    }else if(tokens.length == 2){
                        minutes = Integer.parseInt(tokens[0]);
                        seconds = Integer.parseInt(tokens[1]);
                    }else{
                        hours = Integer.parseInt(tokens[0]);
                        minutes = Integer.parseInt(tokens[1]);
                        seconds = Integer.parseInt(tokens[2]);
                    }
    
                    return 3600 * hours + 60 * minutes + seconds;
                }else
                    return 0;
    
            }catch (NumberFormatException ignored){
                return 0;
            }
    
    }
    
    这就是它解析这些持续时间的方式:

    "1"   -->  1
    "10"  -->  10
    "10:"   -->  0  (not a valid duration)
    "10:07"   -->  607
    "06:08"   -->  368
    "7:22"   -->  442
    ":22"   -->  0  (not a valid duration)
    "10:32:33"   -->  37953
    "2:33:22"   -->  9202
    "2:2:02"   -->  7322
    "2:33:43:32"   -->  0  (not a valid duration)
    "33ff"   -->  0  (not a valid duration)
    "2d:33"   -->  0  (not a valid duration)
    

    对于Java 8和Java.time.Duration,如果字符串的格式为HH:MM:SS或MM:SS或SS,则可以执行此操作

    Duration.ofSeconds(Arrays.stream(runtime.split(":"))
                      .mapToInt(n -> Integer.parseInt(n))
                      .reduce(0, (n, m) -> n * 60 + m));
    
    tl;博士 无需定义自己的
    Duration
    类,因为Java提供了一个类

    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. 
    


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

    持续时间和一天中的时间是两个截然不同的概念。你必须清楚它们,每一个在你的头脑中都应该是不同的。使用模棱两可的HH:MM:SS格式会使区分更加困难(所以要避免这种格式!)

    java.time 现代的方法是使用java.time类

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

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

    LocalTime lt = LocalTime.parse ( "08:30:00" );
    
    持续时间
    为了表示所需的时间跨度,我们需要类。此类用于未附加到时间线的时间跨度。我们可以通过转换
    LocalTime
    来创建一个,通过获取从一天时钟开始的时间量,
    00:00:00.0
    or,以及我们刚刚实例化的
    lt

    Duration d = Duration.between ( LocalTime.MIN , lt );
    
    编辑输入字符串 上述使用
    LocalTime
    的方法仅在输入字符串的持续时间小于24小时时有效。如果超过24小时,您将自己解析输入字符串

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

    ISO 8601 我们可以通过简单调用在标准中生成一个字符串来查看结果。在解析/生成字符串时,java.time类默认使用ISO8601。对于持续时间,标准格式为
    PnYnMnDTnHnMnS
    ,其中
    P
    标记开始,而
    T
    将年-月-日部分与时-分-秒部分分开。因此,我们的八个半小时将显示为
    PT8H30M

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

    d、 toString():PT8H30M

    收集
    持续时间
    对象 您可以创建一个
    列表
    来保存类型为
    持续时间
    的元素

    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" ) ) ) ;
    
    看看这个例子


    关于java.time 该框架内置于Java8及更高版本中。这些类取代了麻烦的旧日期时间类,例如,&

    该项目现已启动,建议迁移到类

    要了解更多信息,请参阅。并搜索堆栈溢出以获得许多示例和解释。规格是

    从哪里获得java.time类

    • 后来
      • 内置的
      • 标准JavaAPI的一部分,带有捆绑实现
      • Java9添加了一些次要功能和修复
      • 大部分java.time功能都在中向后移植到Java6和Java7
      • 该项目专门为Android采用了ThreeTen Backport(如上所述)
    该项目使用其他类扩展了java.time
    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." );
    }
    
    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" ) ) ) ;
    
    Duration d = Duration.parse( "PT8H30M" );
    
    DatatypeFactory.newInstance().newDuration(Calendar.getInstance().getTimeInMillis())