2017-06-05 167 views
3

我想將以下格式的時間轉換爲小時。將小時,分鐘,秒轉換爲小時字符串

我輸入這是一個時間格式也能像

1 hour 30 mins 20 secs 
2 hrs 10 mins 
45 mins 

什麼,而我的輸出將是:

1.505 
2.167 
0.75 

這些都是個小時。

目前我正在通過解析輸入字符串1 hour 30 mins 20 secs,查找是否存在單詞hour/hours/hrs/hr,然後採取前面的數字 - 分鐘和秒相同。我使用該公式將手動和分鐘轉換爲小時。

有什麼可以在Java中使用的內置規定嗎?

+0

有一個thrird黨庫** ** JNLP自然語言處理,但是這將是矯枉過正。 –

+0

你檢查了喬達時間嗎?它具有包含這種可能性的週期分析功能。 – RealSkeptic

+1

使用小數來表示以小時爲單位的時間跨度是不明智的。我建議你查看[ISO 8601](https://en.wikipedia.org/wiki/ISO_8601#Durations)標準格式的持續時間,並查看java.time類['Duration'](https:// docs.oracle.com/javase/8/docs/api/java/time/Duration.html)。 'java.time.Duration.parse(「PT1H30M20S」)' –

回答

3

另一種方法是將其解析爲a Duration,但您需要先改變格式。喜歡的東西:

String adjusted = input.replaceAll("\\s+(hour|hr)[s]\\s+", "H"); 
//Do the same for minutes and seconds 
//So adjusted looks like 1H30M20S 
Duration d = Duration.parse("PT" + adjusted); 

double result = d.toMillis()/3_600_000d; 
+0

您是不是指'(小時|小時)'而不是'[小時|小時]'?使用'[]'的正則表達式不匹配整個字符串「hour」或「hr」 – 2017-06-05 21:58:01

+1

確實,這就是當您在沒有編譯器的情況下在移動設備上編寫代碼時發生的情況! – assylias

2

通常我不會推薦Joda-Time(因爲它是由新的Java API的替換),但它是我知道的一個很好的格式化/解析器時期的唯一API。

可以使用PeriodFormatterBuilder類,並使用appendSuffix方法來定義用於單數和複數值後綴每個字段:

import org.joda.time.Period; 
import org.joda.time.format.PeriodFormatter; 
import org.joda.time.format.PeriodFormatterBuilder; 

// method to parse the period 
public void getPeriod(String input) { 
    PeriodFormatter formatter = new PeriodFormatterBuilder() 
      // hours (singular and plural suffixes) 
      .appendHours().appendSuffix("hour", "hours") 
      // minutes 
      .appendMinutes().appendSuffix("min", "mins") 
      // seconds 
      .appendSeconds().appendSuffix("sec", "secs") 
      // create formatter 
      .toFormatter(); 

    // remove spaces and change "hr" to "hour" 
    Period p = formatter.parsePeriod(input.replaceAll(" ", "").replaceAll("hr", "hour")); 

    double hours = p.getHours(); 
    hours += p.getMinutes()/60d; 
    hours += p.getSeconds()/3600d; 
    System.out.println(hours); 
} 

// tests 
getPeriod("1 hour 30 mins 20 secs"); 
getPeriod("2 hrs 10 mins"); 
getPeriod("45 mins"); 

輸出:

1.5055555555555555
2.1666666666666665
0.75


另一種創建PeriodFormatter的方法是使用帶正則表達式的appendSuffix

PeriodFormatter formatter = new PeriodFormatterBuilder() 
    // hours (all possible suffixes for singular and plural) 
    .appendHours() 
    .appendSuffix(
     // regular expressions for singular and plural 
     new String[] { "^1$", ".*", "^1$", ".*" }, 
     // possible suffixes for singular and plural 
     new String[] { " hour", " hours", " hr", " hrs" }) 
    // optional space (if there are more fields) 
    .appendSeparatorIfFieldsBefore(" ") 
    // minutes 
    .appendMinutes().appendSuffix(" min", " mins") 
    // optional space (if there are more fields) 
    .appendSeparatorIfFieldsBefore(" ") 
    // seconds 
    .appendSeconds().appendSuffix(" sec", " secs") 
    // create formatter 
    .toFormatter(); 

請注意,我還添加了appendSeparatorIfFieldsBefore(" ")以表明它有下一個前場的空間:當你有很多的後綴不同的選項(如hourhr的時間字段)這是非常有用的。

關於這個版本的好處是,你不需要預先處理輸入:

// no need to call replaceAll (take input just as it is) 
Period p = formatter.parsePeriod(input); 

輸出是與上面相同。


的Java 8日期時間API

正如@assylian's answer所述,您可以使用java.time.Duration類:

public void getDuration(String input) { 
    // replace hour/min/secs strings for H, M and S 
    String adjusted = input.replaceAll("\\s*(hour|hr)s?\\s*", "H"); 
    adjusted = adjusted.replaceAll("\\s*mins?\\s*", "M"); 
    adjusted = adjusted.replaceAll("\\s*secs?\\s*", "S"); 
    Duration d = Duration.parse("PT" + adjusted); 

    double hours = d.toMillis()/3600000d; 
    System.out.println(hours); 
} 

//tests 
getDuration("1 hour 30 mins 20 secs"); 
getDuration("2 hrs 10 mins"); 
getDuration("45 mins"); 

輸出是一樣的。

PS:如果您的Java版本是< = 7,您可以使用ThreeTen Backport。類名和方法是相同的,唯一的區別是包名稱:org.threeten.bp而不是java.time

0

目前我在做這樣的:

private double convertToHours(String inputTime) { 
    inputTime = " 1 hour 30 mins 20 secs"; 
    double hours = 0; 
    List<String> timeList = Arrays.asList(inputTime.split(" ")); 
    ListIterator<String> iterator = timeList.listIterator(); 
    String time = null; 
    String previous = null; 
    while (iterator.hasNext()) { 
     int prevIndex = iterator.previousIndex(); 
     time = (String) iterator.next(); 

     if (!time.isEmpty() && time != null) { 

      if (time.contains("hours") || time.contains("hrs") || time.contains("hr") || time.contains("hour")) { 
       // time = time.substring(0, time.indexOf('h')); 
        previous = timeList.get(prevIndex); 

       hours = hours + Double.parseDouble(previous.trim()); 
      } 

      if (time.contains("mins") || time.contains("min") || time.contains("mns")) { 
       //time = time.substring(0, time.indexOf('m')); 
       previous = timeList.get(prevIndex); 
       hours = hours + Double.parseDouble(previous)/60; 
      } 

      if (time.contains("secs") || time.contains("sec") || time.contains("scs")) { 
       //time = time.substring(0, time.indexOf('s')); 
       previous = timeList.get(prevIndex); 
       hours = hours + Double.parseDouble(previous)/3600; 
      } 
     } 
    } 
    return hours; 
} 
相關問題