在我的应用中,我需要获取之前的凌晨4点,而不是当前日期的凌晨4点。
例如:

  • 如果它是March 05, 10:00 am,那么我应该期待回来:March 05, 4:00 am
  • 如果它是March 05, 02:00 am,那么我应该期待回来:March 04, 4:00 am

  • 为此,我正在使用Calendar.nextDate。除每月的最后一天外,它在每月的每个月中都适用。

    这是幸福之路的一个示例,它可以按预期运行:

    let components = DateComponents(hour: 4, minute: 0, second: 0)
    
    let date =  Calendar.current.date(from: DateComponents(year: 2018,
                                                           month: 03,
                                                           day: 05,
                                                           hour: 13,
                                                           minute: 25,
                                                           second: 0))!
    let result = Calendar.current.nextDate(after: date,
                                           matching: components,
                                           matchingPolicy: .nextTime,
                                           direction: .backward)
    

    输出:
    date = "Mar 5, 2018 at 1:25 PM"
    result = "Mar 5, 2018 at 4:00 AM"
    

    这是一条黑暗悲伤之路的示例,在该示例中并非发挥预期作用:

    let components = DateComponents(hour: 4, minute: 0, second: 0)
    
    let date =  Calendar.current.date(from: DateComponents(year: 2018,
                                                           month: 03,
                                                           day: 31,
                                                           hour: 13,
                                                           minute: 25,
                                                           second: 0))!
    let result = Calendar.current.nextDate(after: date,
                                           matching: components,
                                           matchingPolicy: .nextTime,
                                           direction: .backward)
    

    输出:
    date = "Mar 31, 2018 at 1:25 PM"
    result = "Mar 30, 2018 at 4:00 AM"
    // it should give me this instead: "Mar 31, 2018 at 4:00 AM"
    

    知道为什么会这样吗?这是Apple代码中的错误,我应该报告吗?还是我使用这个错误?
    如果是Apple bug,在此期间是否还有另一种方法可以实现我所需的功能?

    更新:

    在查看了一些Swift源代码之后,我注意到问题不是专门与Calendar.nextDate()函数有关的。 nextDate()使用Calendar.enumerateDates(),这才是真正的问题所在。我找不到该函数的源代码。
    这是使用Calendar.enumerateDates()的相同错误:

    let components = DateComponents(hour: 4, minute: 0, second: 0)
    
    let date =  Calendar.current.date(from: DateComponents(year: 2018,
                                                           month: 03,
                                                           day: 31,
                                                           hour: 13,
                                                           minute: 25,
                                                           second: 0))!
    
    Calendar.current.enumerateDates(startingAfter: inputDate,
                                    matching: components,
                                    matchingPolicy: .nextTime,
                                    direction: .backward) { (date, exactMatch, stop) in
        let result = date
        // result = "Mar 30, 2018 at 4:00 AM"
        stop = true
    }
    

    另外,这是一个类似的问题:Swift's Calendar.enumerateDates gives incorrect result when starting on February

    最佳答案

    这确实是应该向Apple报告的错误。确保您包含一个可运行的测试应用程序来演示该问题。 请注意,此错误仅出现在iOS中。在macOS(至少是macOS游乐场)中,代码按预期工作。

    同时,有一个相当简单的解决方法。

    将您的代码更改为使用.forward而不是.backward。这将给出下一个日期而不是上一个日期。似乎没有朝着这个方向发展的错误。然后使用:

    Calendar.current.date(byAdding: .day, value: -1, date: result)
    

    回到前一天,以获得您想要的结果。

    关于ios - 当使用.backward指示方向时,Calendar.nextDate()的行为确实很奇怪。仅在该月的最后一天,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/49202865/

    10-12 00:06
    查看更多