[英]java Time difference outputs negative value and wrong values
我試過下面的代碼。 java 時間差在開始時間和結束時間之間存在小時/日期差異時輸出負值和錯誤值
Date d3 = null;
Date d4 = null;
List<String> activeTimeList = new ArrayList();
int c = Integer.parseInt(cycle.get("Cycle No:").toString());
try {
for(int i = 0; i<c;i++) {
SimpleDateFormat format = new SimpleDateFormat("MM-dd-yyyy HH:mm", Locale.US); //("MM/dd/yyyy HH:mm:ss");
format.setTimeZone(TimeZone.getTimeZone("GMT"));
String cycleEndTm = cycle.get("End Time"+i+"").toString().trim();
String cycleStartTm = cycle.get("Start Time"+i+"").toString().trim();
d3 = format.parse(cycleEndTm);
d4 = format.parse(cycleStartTm);
long diff = d3.getTime() - d4.getTime();
long diffSeconds = diff / 1000 % 60;
long diffMinutes = diff / (60 * 1000) % 60;
long diffHours = diff / (60 * 60 * 1000) % 24;
long diffDays = diff / (24 * 60 * 60 * 1000);
String time1 = diffDays+"."+diffHours+"."+diffMinutes+"."+diffSeconds;
Log :
0.-10.-7.0
d4 =02-11-2017 16:47
d3 =02-11-2017 17:27 Diff = 0.-10.-7.0 無法獲得正確的時差? 我在這里缺少什么? 注意**:cycleEndTm -cycleStarttime 應該給出積極的結果。 我正在從地圖讀取 cycleEndTime 和開始時間。 這就是要求。
使用現代java.time類,不要使用Date
。 將任何Date
轉換為java.time.Instant
。
Duration // Represent a span-of-time as 24-hour days, hours, minutes, seconds, and nanoseconds.
.between( // Calculate elapsed time.
javaUtilDateStart.toInstant() , // Convert any `java.util.Date` to `java.time.Instant`. Never use `Date`; it is a terrible class, ditto for `Calendar`.
javaUtilDateStop.toInstant()
) // Returns a `Duration` object.
.toString() // Generate text in standard ISO 8601 format.
或者調用to…Part
方法來提取天數、小時數等。
您正在使用多年前被java.time類取代的糟糕的舊日期時間類( Date
、 Calendar
、 SimpleDateFormat
)。
Instant
顯然你得到了一個java.util.Date
對象。 如果可能,請重寫該代碼以使用其替代對象java.time.Instant
對象。 兩者都代表 UTC 中的一個時刻,但Instant
具有更精細的納秒分辨率而不是毫秒。 如果不可能,請立即將Date
轉換為Instant
。 調用添加到舊類的新轉換方法。
Instant instant = myJavaUtilDate.toInstant() ; // Convert from legacy class to modern class. Same moment in UTC, same point on the timeline.
以標准ISO 8601格式生成表示該時刻的文本。
以 UTC 格式捕獲當前時刻。
Instant now = Instant.now() ; // Capture the current moment in UTC.
Duration
將經過時間計算為Duration
對象。 同樣,這具有納秒的分辨率。
Duration d = Duration.between( instant , now ) ;
以標准ISO 8601格式生成表示經過時間的文本。
String output = d.toString() ;
或者創建您的字符串,將“天”定義為 24 小時的時間塊,而不考慮日歷。
long days = d.toDaysPart() ;
int hours = d.toHoursPart() ;
int minutes = d.toMinutesPart() ;
int seconds = d.toSecondsPart() ;
String output = days + "." + hours + "." + minutes + "." + seconds ;
您的問題不清楚您的輸入。 如果以字符串開頭,則解析。 首先,如果可能,更改這些字符串的來源以使用明智定義的ISO 8601標准格式。 如果不可能,請定義格式模式以匹配輸入。
String inputStart = "02-10-2018 10.30";
DateTimeFormatter f = DateTimeFormatter.ofPattern( "dd-MM-uuuu HH.mm" );
將您的輸入解析為LocalDateTime
因為它缺少時區或UTC 偏移量的任何指示符。
LocalDateTime ldtStart = LocalDateTime.parse( inputStart , f ) ;
一個LocalDateTime
不是一時,並不代表時間軸上的一個點。 這個類代表了大約 26-27 小時范圍內的潛在時刻,這是全球時區的范圍。
分配該字符串源預期的區域或偏移量,以提供確定時刻所需的上下文。
以continent/region
的格式指定正確的時區名稱,例如America/Montreal
、 Africa/Casablanca
或Pacific/Auckland
。 永遠不要使用EST
或IST
等 2-4 個字母的縮寫,因為它們不是真正的時區,不是標准化的,甚至不是唯一的(!)。
// Transform the indefinite `LocalDateTime` to a definite moment by assigning the time zone intended by that input string.
ZoneId z = ZoneId.of( "Africa/Tunis" );
ZonedDateTime zdtStart = ldtStart.atZone( z );
計算您過去的時間跨度。
Duration d = Duration.between( zdtStart , zdtStop ) ;
java.time框架內置於 Java 8 及更高版本中。 這些類取代麻煩的老傳統日期時間類,如java.util.Date
, Calendar
,和SimpleDateFormat
。
現在處於維護模式的Joda-Time項目建議遷移到java.time類。
要了解更多信息,請參閱Oracle 教程。 並在 Stack Overflow 上搜索許多示例和解釋。 規范是JSR 310 。
您可以直接與您的數據庫交換java.time對象。 使用符合JDBC 4.2或更高版本的JDBC 驅動程序。 不需要字符串,不需要java.sql.*
類。
從哪里獲得 java.time 類?
ThreeTen-Extra項目用額外的類擴展了 java.time。 該項目是未來可能添加到 java.time 的試驗場。 您可以在這里找到一些有用的類,比如Interval
, YearWeek
, YearQuarter
,和更多。
這個答案並沒有解決你問的問題。 無論如何,我建議使用 java.time,現代 Java 日期和時間 API。 這里的第一個版本至少需要Java 9 。 Java 6、7 和 8 緊隨其后。
Map<String, Object> cycle = Map.of("Cycle No:", 1,
"Start Time0", "02-11-2017 16:47",
"End Time0", "02-11-2017 17:27");
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("MM-dd-yyyy HH:mm", Locale.US);
List<String> activeTimeList = new ArrayList<>();
int c = Integer.parseInt(cycle.get("Cycle No:").toString());
try {
for(int i = 0; i < c; i++) {
String cycleEndTm = cycle.get("End Time" + i).toString().trim();
String cycleStartTm = cycle.get("Start Time" + i).toString().trim();
LocalDateTime d4 = LocalDateTime.parse(cycleStartTm, formatter);
LocalDateTime d3 = LocalDateTime.parse(cycleEndTm, formatter);
Duration diff = Duration.between(d4, d3);
String time1 = String.format(Locale.US, "%d.%d.%d.%d",
diff.toDays(), diff.toHoursPart(),
diff.toMinutesPart(), diff.toSecondsPart());
activeTimeList.add(time1);
}
System.out.println(activeTimeList);
} catch (DateTimeParseException dtpe) {
System.err.println(dtpe);
}
這打印:
[0.0.40.0]
我用於格式化的Duration
類的toXxxPart
方法不在Java 8 中。 因此,如果您使用的是 Java 8,則可以通過以下方式進行格式化:
long days = diff.toDays();
diff = diff.minusDays(days);
long hours = diff.toHours();
diff = diff.minusHours(hours);
long minutes = diff.toMinutes();
diff = diff.minusMinutes(minutes);
long seconds = diff.getSeconds();
String time1 = String.format(Locale.US, "%d.%d.%d.%d",
days, hours, minutes, seconds);
輸出與之前相同。
如果有人在使用Java 6 或 7 ,請獲取ThreeTen Backport 庫,Java 8 代碼也應該在那里工作。
您發布的代碼中的唯一問題是您使用的是過時且設計不佳的日期和時間類Date
、 SimpleDateFormat
和TimeZone
。 您的代碼中沒有任何內容解釋您是如何出錯的,負值,所以我懷疑您沒有解析您認為正在解析的字符串。
您可以使用java.time.Duration
,它以ISO-8601 標准為模型,並作為JSR-310 實現的一部分與Java-8一起引入。 Java-9引入了一些更方便的方法。
演示:
import java.time.Duration;
import java.time.LocalDateTime;
import java.time.OffsetDateTime;
import java.time.ZoneOffset;
import java.time.format.DateTimeFormatter;
import java.util.Locale;
public class Main {
public static void main(String[] args) {
String d4 = "02-11-2017 16:47";
String d3 = "02-11-2017 17:27";
DateTimeFormatter dtf = DateTimeFormatter.ofPattern("dd-MM-uuuu HH:mm", Locale.ENGLISH);
// The given date-times in UTC
OffsetDateTime odtD4 = LocalDateTime.parse(d4, dtf).atOffset(ZoneOffset.UTC);
OffsetDateTime odtD3 = LocalDateTime.parse(d3, dtf).atOffset(ZoneOffset.UTC);
// Duration between the date-times in UTC
Duration duration = Duration.between(odtD4, odtD3);
System.out.println(duration);
// Custom format
// ####################################Java-8####################################
String formattedDuration = String.format("%02d.%02d.%02d.%02d", duration.toDays(), duration.toHours() % 24,
duration.toMinutes() % 60, duration.toSeconds() % 60);
System.out.println(formattedDuration);
// ##############################################################################
// ####################################Java-9####################################
formattedDuration = String.format("%02d.%02d.%02d.%02d", duration.toDaysPart(), duration.toHoursPart(),
duration.toMinutesPart(), duration.toSecondsPart());
System.out.println(formattedDuration);
// ##############################################################################
}
}
輸出:
PT40M
00.00.40.00
00.00.40.00
從Trail: Date Time了解現代日期時間 API。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.