【问题标题】:Is a date in same week, month, year of another date in swift是 swift 中另一个日期的同一周、月、年的日期
【发布时间】:2017-04-27 16:47:06
【问题描述】:

了解某个日期是否与另一个日期在同一周(或年份或月份)的最佳方法是什么,最好有扩展名,并且仅使用 Swift

例如,在 Objective-C 中我有

- (BOOL)isSameWeekAs:(NSDate *)date {
    NSDateComponents *otherDay = [[NSCalendar currentCalendar] components:NSCalendarUnitEra | NSCalendarUnitYear | NSCalendarUnitMonth | NSCalendarUnitDay fromDate:self];
    NSDateComponents *today = [[NSCalendar currentCalendar] components:NSCalendarUnitEra | NSCalendarUnitYear | NSCalendarUnitMonth | NSCalendarUnitDay fromDate:date];
    return ([today weekOfYear]   == [otherDay weekOfYear] &&
            [today year]         == [otherDay year] &&
            [today era]          == [otherDay era]);
}

请不要提出将Date 连接到NSDate 的解决方案

【问题讨论】:

  • 更新您的问题,尝试将此代码转换为 Swift。清楚地描述您遇到的问题。
  • 您是否阅读了整篇文章? NSDate Comparison using Swift
  • @rmaddy 抱歉,这个问题不是问题,但没有通过搜索找到直接答案,但对于需要相同答案的人来说,这是一个值得探讨的问题.但是是的,我很懒,因为我没有直接给出答案,我是过失。

标签: ios swift date


【解决方案1】:

您可以使用日历方法isDate(equalTo:granularity:)查看如下:

Xcode 11 • Swift 5.1

extension Date {

    func isEqual(to date: Date, toGranularity component: Calendar.Component, in calendar: Calendar = .current) -> Bool {
        calendar.isDate(self, equalTo: date, toGranularity: component)
    }

    func isInSameYear(as date: Date) -> Bool { isEqual(to: date, toGranularity: .year) }
    func isInSameMonth(as date: Date) -> Bool { isEqual(to: date, toGranularity: .month) }
    func isInSameWeek(as date: Date) -> Bool { isEqual(to: date, toGranularity: .weekOfYear) }

    func isInSameDay(as date: Date) -> Bool { Calendar.current.isDate(self, inSameDayAs: date) }

    var isInThisYear:  Bool { isInSameYear(as: Date()) }
    var isInThisMonth: Bool { isInSameMonth(as: Date()) }
    var isInThisWeek:  Bool { isInSameWeek(as: Date()) }

    var isInYesterday: Bool { Calendar.current.isDateInYesterday(self) }
    var isInToday:     Bool { Calendar.current.isDateInToday(self) }
    var isInTomorrow:  Bool { Calendar.current.isDateInTomorrow(self) }

    var isInTheFuture: Bool { self > Date() }
    var isInThePast:   Bool { self < Date() }
}

【讨论】:

  • 假设我们使用 Calendar.current.isDate(self, equalTo: date, toGranularity: .day) 并且日期是 2016 年 1 月 1 日和 2017 年,它返回 false 吗?
  • 是的,它与 isDateInSameDay 相同。查看我的编辑
  • 接受这个答案,因为我认为可读性 > 功能齐全,但 @Mr.Hedgehog 是一个非常好的答案
  • 你为什么要传递“日期”作为参数?这可以像 Calendar.current.isDate(self, equalTo: Date(), toGranularity: .year) 一样使用 dateToBeChecked 来完成。 isInSameYear() 我猜,你在做反向 (currentDate.isInSameYear(checkingDate))
【解决方案2】:

您可以使用这个基于您提供的 Objective-C 代码的扩展:

extension Date {
    func hasSame(_ components: Calendar.Component..., as date: Date, using calendar: Calendar = .autoupdatingCurrent) -> Bool {
             return components.filter { calendar.component($0, from: date) != calendar.component($0, from: self) }.isEmpty
    }
}

这里的默认日历是autoupdatingCurrent,因此如果用户更改日历,它将相应更新。它还使用可变参数组件,允许您指定任意数量的组件,而无需将它们包装到数组中。

使用示例:

let date1 = Date()
let date2 = Date()
let date3 = Date(timeIntervalSince1970: 30.0)

print(date1.hasSame(.weekOfYear, .day, .hour, as: date2)) // true
print(date1.hasSame(.weekOfYear, as: date3)) // false

编辑

正如@Leo Dabus 所指出的,我们可以在此处使用 set 而不是数组/可变参数 - 这样,如果用户将一些重复项传递给该方法,我们将避免多次比较相同的组件:

extension Date {
    func hasSame(_ components: Set<Calendar.Component>, as date: Date, using calendar: Calendar = .autoupdatingCurrent) -> Bool {
             return components.filter { calendar.component($0, from: date) != calendar.component($0, from: self) }.isEmpty
    }
}

【讨论】:

  • 为什么要在这里使用set?除了删除重复项之外,我看不到任何要点
  • 好吧,我明白了,起初我不相信我们是否应该防止这种误用,但这就像没有任何成本(除了可变参数语法,这更像是个人喜好)。感谢您的评论,我会更新我的答案
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-10-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多