首先,您的示例字符串並不一致:8:30 pm
缺少填充爲零。我會認爲這是一個錯字,應該是08:30 pm
。
不良串格式
順便提一句,這些輸入字符串格式是不期望的。 - 更好的方法是使用標準ISO 8601格式。 - 帶AM/PM的12小時鬧鐘很麻煩。標準格式使用24小時制,時間爲0-23小時。
- 間隔的標準符號是由斜槓分隔的一對日期時間字符串:2008-01-01T13:00/2008-01-01T13:56
。
您的輸入字符串有另一個嚴重問題:沒有指示offset-from-UTC或時區。如果沒有抵消或時區,我們必須回到假設通用24小時的日子。這忽略了夏令時(DST)等異常情況,可能導致23或25小時長的天。
如果您知道傳入字符串的時區,請將其作爲第二個參數傳遞以獲得正確的結果。
java.time
這個問題很老了。從那以後,Java用現代java.time類取代了麻煩的舊日期時間類(Date
,Calendar
等)。我們在下面的示例代碼中使用java.time。
例類
這裏是因爲你的問題給出處理這些字符串一個完整的類。 A Duration
被生產。
package javatimestuff;
import java.time.Duration;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.ZoneId;
import java.time.ZoneOffset;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeParseException;
import java.util.Locale;
/**
*
* @author Basil Bourque
*/
public class DurationProcessor {
static final int SHORT = 30;
static final int LONG = 41;
static final DateTimeFormatter FORMATTER_LOCALDATETIME = DateTimeFormatter.ofPattern ("uuuu-MM-dd hh:mm a");
static final DateTimeFormatter FORMATTER_LOCALTIME = DateTimeFormatter.ofPattern ("hh:mm a");
static public Duration process (String input) {
return DurationProcessor.process (input , ZoneOffset.UTC);
}
static public Duration process (String input , ZoneId zoneId) {
Duration d = Duration.ZERO; // Or maybe null. To be generated by the bottom of this code.
if (null == input) {
// …
System.out.println ("ERROR - Passed null argument.");
return d;
}
if (input.length() == 0) {
// …
System.out.println ("ERROR - Passed empty string as argument.");
return d;
}
String inputModified = input.toUpperCase (Locale.ENGLISH); // Change `am` `pm` to `AM` `PM` for parsing.
String[] parts = inputModified.split (" - ");
String inputStart = parts[ 0 ]; // A date-time sting.
String inputStop = parts[ 1 ]; // Either a date-time string or a time-only string (assume the same date).
ZonedDateTime start = null; // To be generated in this block of code.
try {
LocalDateTime ldt = LocalDateTime.parse (inputStart , DurationProcessor.FORMATTER_LOCALDATETIME);
start = ldt.atZone (zoneId);
} catch (DateTimeParseException e) {
// …
System.out.println ("ERROR - The start failed to parse. inputStart: " + inputStart);
return d;
}
ZonedDateTime stop = null; // To be generated in this block of code.
switch (input.length()) {
case DurationProcessor.SHORT: // Example: "2008-01-01 01:00 pm - 01:56 pm"
try {
LocalTime stopTime = LocalTime.parse (inputStop , DurationProcessor.FORMATTER_LOCALTIME);
stop = ZonedDateTime.of (start.toLocalDate() , stopTime , zoneId);
} catch (DateTimeParseException e) {
// …
System.out.println ("ERROR - The stop time failed to parse.");
return d;
}
break;
case DurationProcessor.LONG: // "2008-01-01 8:30 pm - 2008-01-02 09:30 am"
try {
LocalDateTime ldt = LocalDateTime.parse (inputStop , DurationProcessor.FORMATTER_LOCALDATETIME);
stop = ldt.atZone (zoneId);
} catch (DateTimeParseException e) {
// …
System.out.println ("ERROR - The stop date-time failed to parse.");
return d;
}
break;
default:
// …
System.out.println ("ERROR - Input string is of unexpected length: " + input.length());
break;
}
d = Duration.between (start , stop);
return d;
}
public static void main (String[] args) {
// Run with out time zone (assumes UTC).
Duration dShort = DurationProcessor.process ("2008-01-01 01:00 pm - 01:56 pm");
System.out.println ("dShort: " + dShort);
Duration dLong = DurationProcessor.process ("2008-01-01 08:30 pm - 2008-01-02 09:30 am");
System.out.println ("dLong: " + dLong);
// Run with specified time zone.
ZoneId z = ZoneId.of ("America/Montreal");
Duration dShortZoned = DurationProcessor.process ("2008-01-01 01:00 pm - 01:56 pm" , z);
System.out.println ("dShortZoned: " + dShortZoned);
Duration dLongZoned = DurationProcessor.process ("2008-01-01 08:30 pm - 2008-01-02 09:30 am" , z);
System.out.println ("dLongZoned: " + dLongZoned);
}
}
請注意類中的main
方法,例如用法。
首先是一對沒有指定時區的呼叫。所以UTC和24小時的天數將被使用。
Duration dShort = DurationProcessor.process ("2008-01-01 01:00 pm - 01:56 pm");
System.out.println ("dShort: " + dShort);
Duration dLong = DurationProcessor.process ("2008-01-01 08:30 pm - 2008-01-02 09:30 am");
System.out.println ("dLong: " + dLong);
另一對調用我們指定的目標時區。
ZoneId z = ZoneId.of ("America/Montreal");
Duration dShortZoned = DurationProcessor.process ("2008-01-01 01:00 pm - 01:56 pm" , z);
System.out.println ("dShortZoned: " + dShortZoned);
Duration dLongZoned = DurationProcessor.process ("2008-01-01 08:30 pm - 2008-01-02 09:30 am" , z);
System.out.println ("dLongZoned: " + dLongZoned);
直播代碼
見live code in IdeOne.com該類運行。
dShort:PT56M
dLong:PT13H
dShortZoned:PT56M
dLongZoned:PT13H
由於此頁面上的其他地方所指出的,使用時間的輸出格式日期風格如00:56
含糊不清,應該避免。 Duration
類改爲使用標準ISO 8601 format for durations。上面,我們看到了56分鐘和13分鐘的結果。
關於java.time
的java.time框架是建立在Java 8和更高版本。這些類取代了日期時間類legacy,如java.util.Date
,Calendar
,& SimpleDateFormat
。
Joda-Time項目現在位於maintenance mode,建議遷移到java.time類。請參閱Oracle Tutorial。並搜索堆棧溢出了很多例子和解釋。規格是JSR 310。
從何處獲取java.time類?
的ThreeTen-Extra項目與其他類擴展java.time。這個項目是未來可能增加java.time的一個試驗場。您可以在這裏找到一些有用的類,如Interval
,YearWeek
,YearQuarter
和more。
輸入不一致。大多數時間值的填充爲零,但「8:30 pm」省略了這個值。 – 2017-01-28 23:58:25