gpt4 book ai didi

Java - 以分钟为单位计算差异

转载 作者:行者123 更新时间:2023-12-01 19:28:29 25 4
gpt4 key购买 nike

  • 我必须计算这两个日期之间的分钟差,但日期重叠。
  • 我有两个日期范围:EventStart、EventEnd
  • 我之前写过一个 SQL 查询(见下文),它工作得很好,但速度很慢,所以我想用 Java 处理它(结果集)

这是我从 SQL Server 获取的 JSON:

https://pastebin.com/raw/xhCnXynA

这是我正在运行的 SQL 脚本:

DECLARE @T TABLE(ID INT,FromDate DATETIME, ToDate DATETIME)

INSERT INTO @T(ID,FromDate,ToDate)
SELECT 1,'20090801','20090803' UNION ALL
SELECT 2,'20090802','20090809' UNION ALL
SELECT 3,'20090805','20090806' UNION ALL
SELECT 4,'20090812','20090813' UNION ALL
SELECT 5,'20090811','20090812' UNION ALL
SELECT 6,'20090802','20090802'

SELECT ROW_NUMBER() OVER(ORDER BY s1.FromDate) AS ID,
s1.FromDate,
MIN(t1.ToDate) AS ToDate
FROM @T s1
INNER JOIN @T t1 ON s1.FromDate <= t1.ToDate
AND NOT EXISTS(SELECT * FROM @T t2
WHERE t1.ToDate >= t2.FromDate
AND t1.ToDate < t2.ToDate)
WHERE NOT EXISTS(SELECT * FROM @T s2
WHERE s1.FromDate > s2.FromDate
AND s1.FromDate <= s2.ToDate)
GROUP BY s1.FromDate
ORDER BY s1.FromDate

结果:

enter image description here

我的 Java 代码:

//Date Format
DateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

Integer downTime;

while (rs.next()) {

//Parse to Date
eventStart = formatter.parse(rs.getString("EventStart"));
eventEnd = formatter.parse(rs.getString("EventEnd"));

if (eventStart.after(eventEnd)){
//How should I do this?
}
else{
//How should I do this?
}

//I have to count here the difference between the dates in minutes
}

最佳答案

计算 2 个日期之间的分钟差异

最好使用新 Java 日期/时间 API 中的 java.time.format.DateTimeFormatterjava.time.LocalDateTime 而不是 SimpleDateFormat > 和日期:

DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.S");
LocalDateTime eventStart = LocalDateTime.parse("2019-10-09 01:24:05.0", formatter);
LocalDateTime eventEnd = LocalDateTime.parse("2019-10-09 01:35:14.0", formatter);
Duration duration;
if (eventStart.isBefore(eventEnd)) {
duration = Duration.between(eventStart, eventEnd);
} else {
duration = Duration.between(eventEnd, eventStart);
}
long minutes = duration.toMinutes();
System.out.println("" + minutes + " minute(s)");

结果是:11 分钟

合并所有重叠的日期范围

要合并所有重叠的日期范围,请考虑以下方法。

使用方法 isOverlappingWithmergeWithtoMinutes 创建一个类来表示日期范围,并覆盖 equals哈希码

private static class DateRange {

private final LocalDateTime startDate;
private final LocalDateTime endDate;

public DateRange(LocalDateTime startDate, LocalDateTime endDate) {
this.startDate = startDate;
this.endDate = endDate;
}

public boolean isOverlappingWith(DateRange other) {
return !startDate.isAfter(other.endDate) && !endDate.isBefore(other.startDate);
}

public DateRange mergeWith(DateRange other) {
return new DateRange(
startDate.isBefore(other.startDate) ? startDate : other.startDate,
endDate.isAfter(other.endDate) ? endDate : other.endDate);
}

public long toMinutes() {
return Duration.between(startDate, endDate).toMinutes();
}

@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
DateRange dateRange = (DateRange) o;
return Objects.equals(startDate, dateRange.startDate) &&
Objects.equals(endDate, dateRange.endDate);
}

@Override
public int hashCode() {
return Objects.hash(startDate, endDate);
}

@Override
public String toString() {
return "DateRange{" +
"startDate=" + startDate +
", endDate=" + endDate +
'}';
}
}

迭代所有日期范围并尝试合并它们。为了跟踪重复项,需要额外的HashSet。这个想法是尝试将每个日期范围与列表中的下一个范围合并。如果至少有一次合并,则删除原始日期范围。如果列表不包含生成的合并日期范围,则将其附加到列表中。

DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.S");

List<List<String>> rawDateRanges = List.of(
List.of("2009-08-01 00:00:00.0", "2009-08-03 00:00:00.0"),
List.of("2009-08-05 00:00:00.0", "2009-08-06 00:00:00.0"),
List.of("2009-08-02 00:00:00.0", "2009-08-09 00:00:00.0"),
List.of("2009-08-12 00:00:00.0", "2009-08-13 00:00:00.0"),
List.of("2009-08-11 00:00:00.0", "2009-08-12 00:00:00.0"),
List.of("2009-08-02 00:00:00.0", "2009-08-02 00:00:00.0"));

List<DateRange> dateRanges = new ArrayList<>();
for (List<String> rawDateRange : rawDateRanges) { //Replace with while (rs.next()) { ... }
LocalDateTime fromDate = LocalDateTime.parse(rawDateRange.get(0), formatter);
LocalDateTime toDate = LocalDateTime.parse(rawDateRange.get(1), formatter);
dateRanges.add(new DateRange(fromDate, toDate));
}

Set<DateRange> mergedDateRanges = new HashSet<>();
for (int i = 0; i < dateRanges.size(); i++) {
DateRange dateRange = dateRanges.get(i);
boolean merged = false;
for (int j = i + 1; j < dateRanges.size(); j++) {
DateRange otherDateRange = dateRanges.get(j);
if (dateRange.isOverlappingWith(otherDateRange)) {
dateRange = dateRange.mergeWith(otherDateRange);
merged = true;
}
}
if (merged) {
dateRanges.remove(i--);
if (mergedDateRanges.add(dateRange)) {
dateRanges.add(dateRange);
}
}
}

List<Long> minutes = dateRanges.stream()
.peek(System.out::println)
.map(DateRange::toMinutes) //Convert to minutes
.collect(toList());

System.out.println(minutes);

输出:

DateRange{startDate=2009-08-01T00:00, endDate=2009-08-09T00:00}
DateRange{startDate=2009-08-11T00:00, endDate=2009-08-13T00:00}
[11520, 2880]

关于Java - 以分钟为单位计算差异,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60614942/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com