获取两个日期之间的分钟差异,而不进行60秒的计算。

huangapple go评论52阅读模式
英文:

Getting minute difference between 2 dates without 60 second calculation

问题

I want to get minute difference between 2 dates but unlike the other answers in stackoverflow, I don't want to calculate with seconds.

What I mean is :

(year-month-day hours-minutes-seconds)

  • 2023-04-17 13:42:00
  • 2023-04-17 13:43:00

between these 2 dates there is only 1 minutes difference.

  • 2023-04-17 13:42:58
  • 2023-04-17 13:43:00

If I changed to first date's seconds to 58, I still want output as 1. Technically, difference is only 2 seconds but minute is different and difference is 1.

You might think, take only the minute part from date and calculate but difference between these 2 dates might be much far, like months away so it would be hard to calculate like that or I could not find a way to do it.

Codes I have tried:

let diff = Int(end.timeIntervalSince1970 - start.timeIntervalSince1970)

let hours = diff / 3600
let minutes = (diff - hours * 3600) / 60

This one obviously calculate the minutes based on seconds so if seconds difference is less than 60 but still 2 dates are on different minutes, output is 0.

I also tried .dateComponents

let calendar = Calendar.current

let startDate = Date() // replace with your start date
let endDate = Date() // replace with your end date

let components = calendar.dateComponents([.minute], from: startDate, to: endDate)

if let minutes = components.minute {
    print("Number of minutes between start and end dates: \(minutes)")
}

But also the same problem here.

英文:

I want to get minute difference between 2 dates but unlike the other answers in stackoverflow, I don't want to calculate with seconds.

What I mean is :

(year-month-day hours-minutes-seconds)

  • 2023-04-17 13:42:00
  • 2023-04-17 13:43:00

between these 2 dates there is only 1 minutes difference.

  • 2023-04-17 13:42:58
  • 2023-04-17 13:43:00

If I changed to first date's seconds to 58, I still want output as 1. Technically, difference is only 2 seconds but minute is different and difference is 1.

You might think, take only the minute part from date and calculate but difference between these 2 dates might be much far, like months away so it would be hard to calculate like that or I could not find a way to do it.

Codes I have tried :

let diff = Int(end.timeIntervalSince1970 - start.timeIntervalSince1970)

let hours = diff / 3600
let minutes = (diff - hours * 3600) / 60

This one obviously calculate the minutes based on seconds so if seconds difference is less than 60 but still 2 dates are on different minutes, output is 0.

I also tried .dateComponents

let calendar = Calendar.current

let startDate = Date() // replace with your start date
let endDate = Date() // replace with your end date

let components = calendar.dateComponents([.minute], from: startDate, to: endDate)

if let minutes = components.minute {
    print("Number of minutes between start and end dates: \(minutes)")
}

But also the same problem here.

答案1

得分: 1

这是一个计算时间差的函数。它首先使用与您相同的方法,但检查分钟结果是否为零,如果是,则使用Calendar的第二个函数查看日期是否完全相同,然后按分钟比较,isDate(:equalTo:toGranularity:)

func minuteDifference(from startDate: Date, to endDate: Date) -> Int {
    let minutes = calendar.dateComponents([.minute], from: startDate, to: endDate).minute!

    if minutes != 0 {
        return minutes
    } else {
        let factor = startDate <= endDate ? 1 : -1
        return calendar.isDate(startDate, equalTo: endDate, toGranularity: .minute) ? 0 : 1 * factor
    }
}
英文:

Here is a function that calculates the difference. It starts by using the same method you use but checks if the result in minutes is zero and of so uses a second function from Calendar to see if the dates are exactly the same or not and then equal comparing down to minutes, isDate(:equalTo:toGranularity:)

func minuteDifference(from startDate: Date, to endDate: Date) -&gt; Int {
    let minutes = calendar.dateComponents([.minute], from: startDate, to: endDate).minute!

    if minutes != 0 {
        return minutes
    } else {
        let factor = startDate &lt;= endDate ? 1 : -1
        return calendar.isDate(startDate, equalTo: endDate, toGranularity: .minute) ? 0 : 1 * factor
    }
}

答案2

得分: 0

根据我的理解,这里的逻辑是“找到最大的时间单位差异,并将其四舍五入到下一个更大的时间单位差异的整数倍”。

注释中提到使用DateComponents,这绝对是正确的起点,但我没有看到内置的方法能够精确地执行此操作。例如,如果你的时间单位集合是[.minute],但不包括.second,那么你就会完全失去秒的精度。你不会看到它被四舍五入到1分钟的差异,仅仅是因为你没有要求以秒为单位的差异。

这是我的开始方式:

import Foundation

extension Date {
    static private let allComponents: [Calendar.Component] = [.year, .month, .day, .hour, .minute, .second]
    static private let allComponentsSet = Set(allComponents)
    
    static func approximatedDifference(from start: Date, to end: Date) -> DateComponents {
        var differenceComponents = Calendar.current.dateComponents(Self.allComponentsSet, from: start, to: end)
        
        // 例如,对于`2023-04-17 13:42:58`和`2023-04-17 13:43:00`,这将是`.second`。
        let largestDifferingComponent = Self.allComponents.first(where: { differenceComponents.value(for: $0) != 0 })!
        
        // 这是下一个更大的时间单位。例如,如果`largestDifferingComponent`是`.second`,那么这将是`.minute`。
        let largerComponentIndex = Self.allComponents.index(allComponents.firstIndex(of: largestDifferingComponent)!, offsetBy: -1, limitedBy: 0)!
        let largerComponent = allComponents[largerComponentIndex]
        
        // 将较小的差异组件清零
        differenceComponents.setValue(0, for: largestDifferingComponent)
        // 在下一个更大的时间单位中增加差异
        differenceComponents.setValue(differenceComponents.value(for: largerComponent)! + 1, for: largerComponent)
        
        return differenceComponents
    }
}

let start = DateComponents(calendar: .current, year: 2023, month: 04, day: 17, hour: 13, minute: 42, second: 58).date!
let end = DateComponents(calendar: .current, year: 2023, month: 04, day: 17, hour: 13, minute: 43, second: 00).date!
print(Date.approximatedDifference(from: start, to: end)) // 1 minute
英文:

From what I understand, the logic here is "take the largest unit of difference, and round it up to 1 of the next larger unit of difference".

The comments mention using DateComponents, which is definitely the correct starting point, but I don't see any built in way to do precisely this. E.g. if your set of components is [.minute] but doesn't include .second, you just lose the second granularity entirely. You won't see it rounded up to a 1 minute difference just because you didn't ask for the difference in seconds.

Here's how I would start:

import Foundation

extension Date {
	static private let allComponents: [Calendar.Component] = [.year, .month, .day, .hour, .minute, .second]
	static private let allComponentsSet = Set(allComponents)
	
	static func approximatedDifference(from start: Date, to end: Date) -&gt; DateComponents {
		var differenceComponents = Calendar.current.dateComponents(Self.allComponentsSet, from: start, to: end)
		
		// E.g. for `2023-04-17 13:42:58` and `2023-04-17 13:43:00`, this will be `.second`.
		let largestDifferingComponent = Self.allComponents.first(where: { differenceComponents.value(for: $0) != 0 })!
		
		// This is the next large component. E.g. if `largestDifferingComponent` is `.second`, then this will be `.minute`.
		let largerComponentIndex = Self.allComponents.index(allComponents.firstIndex(of: largestDifferingComponent)!, offsetBy: -1, limitedBy: 0)!
		let largerComponent = allComponents[largerComponentIndex]
		
		// Zero out the smaller differing component
		differenceComponents.setValue(0, for: largestDifferingComponent)
		// Increment the difference in the next larger component
		differenceComponents.setValue(differenceComponents.value(for: largerComponent)! + 1, for: largerComponent)
		
		return differenceComponents
	}
}

let start = DateComponents(calendar: .current, year: 2023, month: 04, day: 17, hour: 13, minute: 42, second: 58).date!
let end = DateComponents(calendar: .current, year: 2023, month: 04, day: 17, hour: 13, minute: 43, second: 00).date!
print(Date.approximatedDifference(from: start, to: end)) // 1 minute

It works correctly for your example, but you'll need to clean up some of those first unwraps (though some of them seem unfailable).

huangapple
  • 本文由 发表于 2023年4月17日 20:43:55
  • 转载请务必保留本文链接:https://go.coder-hub.com/76035281.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定