解析日期和时间以获取Java的总时数和分钟数时遇到问题。
如果我计算从“星期一22:00”到“星期二22:00”开始的总时间,那么我会得到正确的总小时数24。但是,如果我计算从“星期三22:00”到当前日期的总时间,时间像“星期四12:45”,那么我得到的“小时数:-153分钟:-15”。
仅在星期三和星期四才是这种情况。在剩下的日子里,它工作正常。
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.concurrent.TimeUnit;
public class Test {
private static DateFormat dateFormat = new SimpleDateFormat("EEE HH:mm");
private static DateFormat dayFormat = new SimpleDateFormat("E");
private static Calendar calendar = Calendar.getInstance();
public static void main(String[] args) {
try {
Date date1 = dateFormat.parse("Wed 22:00");
Date date2 = dateFormat.parse(dayFormat.format(calendar.getTime()) + " " + calendar.getTime().getHours() + ":"
+ calendar.getTime().getMinutes());
long hours2 = getDurationInHours(date1, date2);
long min = getDurationInMin(date1, date2);
System.out.println("Hours : " + hours2 + " Min : " + min);
} catch (Exception e) {
e.printStackTrace();
}
}
public static long getDurationInHours(Date returnTime, Date leaveTime) {
long durationInMillis = leaveTime.getTime() - returnTime.getTime();
long hours = TimeUnit.MILLISECONDS.toHours(durationInMillis);
return hours;
}
public static long getDurationInMin(Date returnTime, Date leaveTime) {
long durationInMillis = leaveTime.getTime() - returnTime.getTime();
long min = TimeUnit.MILLISECONDS.toMinutes(durationInMillis) % 60;
return min;
}
}
答案 0 :(得分:3)
这是因为当您将日期定义为22:00星期三时,它不是当前一周的星期三。实际上是1970年1月7日;)
您可能已经知道,java中的日期从1970年1月1日起一直是一个长整数。因此,当您说星期三而不是实际日期时,它将获得1970年之后的第一个星期三,即第七个星期三。当您说星期一22:00时,它可以正常工作,因为它使用的是1970年1月5日,并且相差2天。
当您以相同的逻辑使用“ Thu 22:00”时,它使用的是1970年1月1日(即星期四),因此您得到负数。因为实际上要提前6天
答案 1 :(得分:1)
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("EEE H:mm", Locale.ENGLISH);
ZonedDateTime now = ZonedDateTime.now(ZoneId.of("America/Dominica"));
TemporalAccessor fromTa = formatter.parse("Wed 22:00");
ZonedDateTime from = now
.with(TemporalAdjusters.previous(DayOfWeek.from(fromTa)))
.with(LocalTime.from(fromTa));
Duration dur = Duration.between(from, now);
System.out.println(dur);
现在运行此代码将给出以下输出:
PT11H41M25.284611S
这意味着持续11个小时41分钟25.284611秒。如果需要在程序中进一步使用此持续时间,则可能需要保留Duration
对象。对于向用户打印不是很好,所以可以这样做:
long hours = dur.toHours();
int min = dur.toMinutesPart();
System.out.println("" + hours + " hours " + min + " min");
11小时41分钟
Java没有“星期三22:00”的概念。因此,我们需要选择一个特定的星期三和一个特定的星期四。 SimpleDateFormat
试图为您提供帮助并为您选择,但没有选择您期望的星期三和星期四,因此对您没有任何帮助。 java.time,现代的Java日期和时间API,迫使我们自行选择。我更喜欢这个。这样可以使代码中发生的事情更加清晰明了,从而使发现和修复错误更容易。
我对TemporalAdjusters.previous
的使用可以确保我在最后星期三(不是下星期三)。我对ZonedDateTime
的使用可以确保小时和分钟正确无误。即使跨夏季和夏季时间(夏令时)之间的过渡以及其他此类时间过渡。如果不是美国/多米尼加,您当然应该填写自己的时区。
链接: Oracle tutorial: Date Time解释了如何使用java.time
。
答案 2 :(得分:0)
java.util
的日期时间 API 及其格式化 API SimpleDateFormat
已过时且容易出错。建议完全停止使用它们并切换到 modern date-time API。
您可以使用 java.time.Duration
以直观的方式完成此操作,它以 ISO-8601 standards 为模型,并作为 JSR-310 implementation 的一部分在 Java-8 中引入。 Java-9 引入了一些更方便的方法。
请注意工作日和时间,例如Mon 22:00
不足以直接创建日期时间对象。工作日星期一每周都会到来,因此我们必须创建一个默认为特定日期的日期时间对象,例如today
。以此日期作为参考,您可以找到给定工作日(例如LocalDate
)的第一次出现(Monday
),并且从该对象中,您可以获得具有给定时间的日期时间对象。
Duration#between
为您提供两个日期时间对象之间的 Duration
对象。使用 Duration
对象,您可以创建一个按照您的要求格式化的字符串,方法是从中获取天、小时、分钟、秒。
演示:
import java.time.DayOfWeek;
import java.time.Duration;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
import java.time.temporal.TemporalAccessor;
import java.time.temporal.TemporalAdjusters;
import java.util.Locale;
public class Main {
public static void main(String[] args) {
// Test
displayDuration(getDuration("Mon 22:00", "Tue 22:00"));
displayDuration(getDuration("Wed 22:00", "Thu 12:45"));
}
static Duration getDuration(String strStartDayTime, String strEndDayTime) {
LocalDate today = LocalDate.now();
DateTimeFormatter dtf = DateTimeFormatter.ofPattern("EEE HH:mm", Locale.ENGLISH);
TemporalAccessor taStart = dtf.parse(strStartDayTime);
TemporalAccessor taEnd = dtf.parse(strEndDayTime);
LocalDateTime ldtStartDateTime = today.with(TemporalAdjusters.nextOrSame(DayOfWeek.from(taStart)))
.atTime(LocalTime.from(taStart));
LocalDateTime ldtEndDateTime = today.with(TemporalAdjusters.nextOrSame(DayOfWeek.from(taEnd)))
.atTime(LocalTime.from(taEnd));
return Duration.between(ldtStartDateTime, ldtEndDateTime);
}
static String formatDurationJava8(Duration duration) {
return String.format("Days: %d, Hours: %02d, Minutes: %02d, Seconds: %02d", duration.toDays(),
duration.toHours() % 24, duration.toMinutes() % 60, duration.toSeconds() % 60);
}
static String formatDurationJava9(Duration duration) {
return String.format("Days: %d, Hours: %02d, Minutes: %02d, Seconds: %02d", duration.toDaysPart(),
duration.toHoursPart(), duration.toMinutesPart(), duration.toSecondsPart());
}
static void displayDuration(Duration duration) {
// Default format
System.out.println(duration);
// Custom format
System.out.println(formatDurationJava8(duration));
System.out.println(formatDurationJava9(duration));
}
}
输出:
PT24H
Days: 1, Hours: 00, Minutes: 00, Seconds: 00
Days: 1, Hours: 00, Minutes: 00, Seconds: 00
PT14H45M
Days: 0, Hours: 14, Minutes: 45, Seconds: 00
Days: 0, Hours: 14, Minutes: 45, Seconds: 00
从 Trail: Date Time 了解现代日期时间 API。