快速设置 NSDate 0 秒

Posted

技术标签:

【中文标题】快速设置 NSDate 0 秒【英文标题】:Set NSDate 0 seconds in swift 【发布时间】:2015-04-22 06:14:46 【问题描述】:

我正在尝试从UIDatePicker 获取NSDate,但它不断地返回一个后缀为 20 秒的日期时间。如何在swift中手动将NSDate的秒数设置为零?

【问题讨论】:

我很快就需要这个 ***.com/questions/1525825/… 你可以在swift中使用同样的方式 【参考方案1】:
extension Date 

    var zeroSeconds: Date? 
        let calendar = Calendar.current
        let dateComponents = calendar.dateComponents([.year, .month, .day, .hour, .minute], from: self)
        return calendar.date(from: dateComponents)
    


用法:

let date1 = Date().zeroSeconds

let date2 = Date()
print(date2.zeroSeconds)

【讨论】:

【参考方案2】:

来自 Swift 中的 answer:

var date = NSDate();
let timeInterval = floor(date .timeIntervalSinceReferenceDate() / 60.0) * 60.0
date = NSDate(timeIntervalSinceReferenceDate: timeInterval)

【讨论】:

【参考方案3】:

这是 Swift 3 中的操作方法。

在此示例中,我删除了日期组件中的秒数:

let date = picker.date
let calendar = Calendar.current
let components = calendar.dateComponents([.year, .month, .day, .hour, .minute], from: date)
let fullMinuteDate = calendar.date(from: components)!

在操场上工作:

【讨论】:

【参考方案4】:

可以将日期截断为整分钟

let date = NSDate()

let cal = NSCalendar.currentCalendar()
var fullMinute : NSDate?
cal.rangeOfUnit(.CalendarUnitMinute, startDate: &fullMinute, interval: nil, forDate: date)
println(fullMinute!)

Swift 4 及更高版本的更新:

let date = Date()
let cal = Calendar.current
if let fullMinute = cal.dateInterval(of: .minute, for: date)?.start 
    print(fullMinute)

这种方法可以很容易地调整为截断整小时、一天、一个月……

【讨论】:

这让我觉得这是最好的方法。任何包含“60”的日期计算都让我颤抖!不要让我开始使用“60 * 60”甚至“60 * 60 * 24”!! 如果要截断的Date 具有完全相同的值,它不会总是“跳”到下一个/上一个Date 吗? @GuilhermeMatuella:你是对的,如果日期已经是整整一分钟,那么它将产生前一分钟。我已删除该部分,感谢您的反馈。【参考方案5】:

只需重新格式化日期:

func stripSecondsFromDate(date: NSDate) -> NSDate 
  let dateFormatter = NSDateFormatter()
  dateFormatter.dateFormat = "yyyy-MM-dd HH:mm"
  let str = dateFormatter.stringFromDate(date)
  let newDate = dateFormatter.dateFromString(str)!

  return newDate

【讨论】:

【参考方案6】:
import Foundation

let now = Date()
let calendar = Calendar.current
let date = calendar.date(bySettingHour: 0,
                         minute: 0,
                         second: 0,
                         of: now,
                         direction: .backward)

还有另一种方式,多了两个参数:matchingpolicy 和 repeatedTimePolicy。

let date = calendar.date(bySettingHour: 0,
                         minute: 0,
                         second: 0,
                         of: now,
                         matchingPolicy: .strict,
                         repeatedTimePolicy: .first,
                         direction: .backward)

检查结果:

let formatter = ISO8601DateFormatter()
formatter.timeZone = TimeZone.current // defaults to GMT
let string = formatter.string(from: date!)
print(string) // 2019-03-27T00:00:00+01:00

【讨论】:

【参考方案7】:

我知道这不能直接解决 NSDate,但无论如何它可能是值得的 - 我在 Date 上遇到了同样的问题,而且我认为这 可能 更 干净方法。

extension Calendar 
    /// Removes seconds `Calendar.Component` from a `Date`. If `removingFractional` is `true`, it also
    /// removes all fractional seconds from this particular `Date`.
    ///
    /// `removingFractional` defaults to `true`.
    func removingSeconds(fromDate date: Date, removingFractional removesFractional: Bool = true) -> Date? 
        let seconds = component(.second, from: date)
        let noSecondsDate = self.date(byAdding: .second, value: -seconds, to: date)

        if removesFractional, let noSecondsDate = noSecondsDate 
            let nanoseconds = component(.nanosecond, from: noSecondsDate)
            return self.date(byAdding: .nanosecond, value: -nanoseconds, to: noSecondsDate)
        

        return noSecondsDate
    

现在,为了解决您的问题,我们创建了函数removingSeconds(fromDate: removingFractional)。这真的很简单 - 正如您在函数的文档中看到的那样。它会删除.second 组件,如果removingFractionaltrue,它还会删除此Date.nanosecond 组件可能具有的任何小数秒。

【讨论】:

请注意,这不会删除小数秒,因此结果不一定是整分钟。 @MartinR 我已更新解决方案以处理可能需要考虑小数秒的情况。您认为现在这是一个体面的方法吗? 好吧,你现在有一种方法可以删除秒(包括小数秒)。但是移除其他单位的目的是什么?请注意,cal.removing(component: .day, fromDate: d) 为您提供上个月的最后一天,因为天数从 1 开始计数。例如,“2020-02-21 12:34”将变为“2020-01- 31 点 12 分 34 秒”。老实说,我不确定这是否有用。 你是完全正确的。如果在任何比.second“更大”的Calendar.Component 或任何与时间不直接相关的东西中使用,我已经删除了可能会引起混淆的抽象。谢谢,我再次改进了答案,使其更直接。

以上是关于快速设置 NSDate 0 秒的主要内容,如果未能解决你的问题,请参考以下文章

日期选择器中的小时:分钟:秒如何快速

如何创建过去的新 NSDate 对象,例如比另一个日期早 1 秒?

如何快速执行一个函数 5 秒

如何快速为 NSDate 做核心数据获取谓词?我想按月过滤

快速将 TimeString yyyy-mm-dd HH:mm:ss 转换为 NSDate 时间 HH:mm AM/PM [重复]

快速获取当天0点0分0秒(00:00:00)