2つの日付オブジェクトがあります。
2017-01-13 11:40:17 +0000
2016-03-15 10:22:14 +0000
これらの値の時間のみを比較し、日付を無視する必要があります
例:12:00 amおよび12:01 am、12:01の方が遅い(12:01 am> 12:00 am)== true
これは私が最後に取ったルートです。これにより、Swiftで日付の時刻だけを比較するのが簡単になります
新しいオブジェクト時間:
class Time: Comparable, Equatable {
init(_ date: Date) {
//get the current calender
let calendar = Calendar.current
//get just the minute and the hour of the day passed to it
let dateComponents = calendar.dateComponents([.hour, .minute], from: date)
//calculate the seconds since the beggining of the day for comparisions
let dateSeconds = dateComponents.hour! * 3600 + dateComponents.minute! * 60
//set the varibles
secondsSinceBeginningOfDay = dateSeconds
hour = dateComponents.hour!
minute = dateComponents.minute!
}
init(_ hour: Int, _ minute: Int) {
//calculate the seconds since the beggining of the day for comparisions
let dateSeconds = hour * 3600 + minute * 60
//set the varibles
secondsSinceBeginningOfDay = dateSeconds
self.hour = hour
self.minute = minute
}
var hour : Int
var minute: Int
var date: Date {
//get the current calender
let calendar = Calendar.current
//create a new date components.
var dateComponents = DateComponents()
dateComponents.hour = hour
dateComponents.minute = minute
return calendar.date(byAdding: dateComponents, to: Date())!
}
/// the number or seconds since the beggining of the day, this is used for comparisions
private let secondsSinceBeginningOfDay: Int
//comparisions so you can compare times
static func == (lhs: Time, rhs: Time) -> Bool {
return lhs.secondsSinceBeginningOfDay == rhs.secondsSinceBeginningOfDay
}
static func < (lhs: Time, rhs: Time) -> Bool {
return lhs.secondsSinceBeginningOfDay < rhs.secondsSinceBeginningOfDay
}
static func <= (lhs: Time, rhs: Time) -> Bool {
return lhs.secondsSinceBeginningOfDay <= rhs.secondsSinceBeginningOfDay
}
static func >= (lhs: Time, rhs: Time) -> Bool {
return lhs.secondsSinceBeginningOfDay >= rhs.secondsSinceBeginningOfDay
}
static func > (lhs: Time, rhs: Time) -> Bool {
return lhs.secondsSinceBeginningOfDay > rhs.secondsSinceBeginningOfDay
}
}
簡単にアクセスできる日付拡張://日付から時刻を取得する機能を追加します:
extension Date {
var time: Time {
return Time(self)
}
}
例:
let firstDate = Date()
let secondDate = firstDate
//Will return true
let timeEqual = firstDate.time == secondDate.time
私のアプローチは、 Calendar
を使用してそれらを同じ日付のDate
オブジェクトにしてから、たとえば timeIntervalSinceReferenceDate
を使用してそれらを比較することです。 。
別のよりクリーンな(ただし、結果のコードの行数が増える可能性が高い)のは、Date
にsecondsFromBeginningOfTheDay() -> TimeInterval
と呼ばれる拡張を作成し、結果のdouble値を比較することです。
2番目のアプローチに基づく例:
// Creating Date from String
let textDate1 = "2017-01-13T12:21:00-0800"
let textDate2 = "2016-03-06T20:12:05-0900"
let dateFormatter: DateFormatter = {
let formatter = DateFormatter()
formatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ssZZZ"
formatter.timeZone = TimeZone.current
return formatter
} ()
// Dates used for the comparison
let date1 = dateFormatter.date(from: textDate1)
let date2 = dateFormatter.date(from: textDate2)
// Date extensions
extension Date {
func secondsFromBeginningOfTheDay() -> TimeInterval {
let calendar = Calendar.current
// omitting fractions of seconds for simplicity
let dateComponents = calendar.dateComponents([.hour, .minute, .second], from: self)
let dateSeconds = dateComponents.hour! * 3600 + dateComponents.minute! * 60 + dateComponents.second!
return TimeInterval(dateSeconds)
}
// Interval between two times of the day in seconds
func timeOfDayInterval(toDate date: Date) -> TimeInterval {
let date1Seconds = self.secondsFromBeginningOfTheDay()
let date2Seconds = date.secondsFromBeginningOfTheDay()
return date2Seconds - date1Seconds
}
}
if let date1 = date1, let date2 = date2 {
let diff = date1.timeOfDayInterval(toDate: date2)
// as text
if diff > 0 {
print("Time of the day in the second date is greater")
} else if diff < 0 {
print("Time of the day in the first date is greater")
} else {
print("Times of the day in both dates are equal")
}
// show interval as as H M S
let timeIntervalFormatter = DateComponentsFormatter()
timeIntervalFormatter.unitsStyle = .abbreviated
timeIntervalFormatter.allowedUnits = [.hour, .minute, .second]
print("Difference between times since midnight is", timeIntervalFormatter.string(from: diff) ?? "n/a")
}
// Output:
// Time of the day in the second date is greater
// Difference between times since midnight is 8h 51m 5s
私はこれだけを行うのに問題があり、2つの日付の時間を比較したいだけなら、もっと簡単な解決策を見つけたと思います。少し「ハック」を感じますが、うまく機能しているようです。
Swift 4
// date1 and date2 are the dates you want to compare
let calendar = Calendar.current
var newDate = Date(TimeIntervalSinceReferenceDate: 0) // Initiates date at 2001-01-01 00:00:00 +0000
var newDate1 = Date(TimeIntervalSinceReferenceDate: 0) // Same as above
// Recieving the components from the dates you want to compare
let newDateComponents = calendar.dateComponents([.hour, .minute], from: date1)!
let newDate1Components = calendar.dateComponents([.hour, .minute], from: date2)!
// Adding those components
newDate = calendar.date(byAdding: newDateComponents, to: newDate)
newDate1 = calendar.date(byAdding: newDate1Components, to: newDate1)
日付を無視して1日2回を比較するための私の解決策:
let date1 = some time as a date
let date2 = some other time as a date
let time1 = 60*Calendar.current.component(.hour, from: date1!) + Calendar.current.component(.minute, from: date1!)
let time2 = 60*Calendar.current.component(.hour, from: date2!) + Calendar.current.component(.minute, from: date2!)
これで、曜日に関係なく整数time1とtime2を比較できます。より高い精度が必要な場合は、seconds/60を追加できます。
時刻の標準タイプはありません。最初に妥当なタイプはタプルです:
typealias TimeOfDay = (hour: Int, minute: Int, second: Int)
これらのTimeOfDay
値を作成するには、Calendar
が必要です。デフォルトでは、Calendar
はデバイスのシステム全体のタイムゾーンを使用します。そうしたくない場合は、Calendar
のタイムゾーンを明示的に設定してください。例:
var calendar = Calendar.autoupdatingCurrent
calendar.timeZone = TimeZone(abbreviation: "UTC")!
これで、DateFormatter
を使用して文字列をDate
sに変換し(必要な場合)、次にcalendar
を使用してDate
s:
let strings: [String] = ["2017-01-13 11:40:17 +0000", "2016-03-15 10:22:14 +0000"]
let parser = DateFormatter()
parser.dateFormat = "yyyy-MM-dd HH:mm:ss Z"
let timesOfDay: [TimeOfDay] = strings.map({ (string) -> TimeOfDay in
let components = calendar.dateComponents([.hour, .minute, .second], from: parser.date(from: string)!)
return (hour: components.hour!, minute: components.minute!, second: components.second!)
})
Swift.print(timesOfDay)
// Output: [(11, 40, 17), (10, 22, 14)]
最後に、これらのTimeOfDay
値を比較できます。 Swiftには、要素がComparable
であるタプルの標準比較演算子が付属しているため、このTimeOfDay
型が適格です。次のように言うだけです。
if timesOfDay[0] < timesOfDay[1] {
Swift.print("date[0] comes first")
} else if timesOfDay[0] == timesOfDay[1] {
Swift.print("times are equal")
} else {
Swift.print("date[1] comes first")
}
これは、Swiftを使用する場合、非常に簡単です Swifter Swift
date1.day = 1
date1.month = 1
date1.year = 2000
date2.day = 1
date2.month = 1
date2.year = 2000
これで、date1およびdate2で>、<、==演算子を使用して、時間コンポーネントのみを比較できます。
編集-日付クラスを拡張することでこれを自分で行うことができます。たとえば、swifter-Swiftは日コンポーネントのベローズを行います。
public var day: Int {
get {
return Calendar.current.component(.day, from: self)
}
set {
let allowedRange = Calendar.current.range(of: .day, in: .month, for: self)!
guard allowedRange.contains(newValue) else { return }
let currentDay = Calendar.current.component(.day, from: self)
let daysToAdd = newValue - currentDay
if let date = Calendar.current.date(byAdding: .day, value: daysToAdd, to: self) {
self = date
}
}
}
このコードは機能し、遊び場で簡単に確認できます
let s1 = "22:31"
let s2 = "14:31"
let f = DateFormatter()
f.dateFormat = "HH:mm"
f.date(from: s1)! //"Jan 1, 2000 at 10:31 PM"
f.date(from: s2)! //"Jan 1, 2000 at 2:31 PM"
f.date(from: s1)! > f.date(from: s2)! // true