【问题标题】:How can I extract number of years, months, and days since a date in Swift如何在 Swift 中提取自日期以来的年数、月数和天数
【发布时间】:2015-12-26 18:38:35
【问题描述】:

如何在 Swift 中提取自日期以来的年数、月数和天数。

到目前为止,我在名为DatePickerController 的类文件中有以下代码。

class DatePickerController: UIViewController {

    @IBOutlet var datePicker:UIDatePicker!
    @IBOutlet var dateDisplay: UILabel!

    override func viewDidLoad() {
        super.viewDidLoad()

        // Do any additional setup after loading the view.
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }

    @IBAction func datePickerChanged(sender: AnyObject) {
        setDate()
    }

    let dateFormatter = NSDateFormatter()

    // MARK: - Date Format
    func setDate() {
        dateFormatter.dateStyle = NSDateFormatterStyle.ShortStyle
        dateDisplay.text = dateFormatter.stringFromDate(datePicker.date)
    }

}

我将为年、月和日创建单独的UILables

【问题讨论】:

    标签: swift nsdate


    【解决方案1】:

    就像你说的,每个日期组件都需要 UILabel。然后,您可以使用自定义日期格式字符串而不是使用 NSDateFormatterStye.ShortStyle 来提取组件。这为您提供了最大的灵活性。格式化字符串遵循unicode standard

    我无法在您的项目上下文中测试代码,但如果您添加标签并将它们正确连接到 Xcode,我相信这段代码将完全符合您的要求:

    class DatePickerController: UIViewController {
    
      @IBOutlet var datePicker:UIDatePicker!
      @IBOutlet var dayDisplay: UILabel!
      @IBOutlet var monthDisplay: UILabel!
      @IBOutlet var yearDisplay: UILabel!
    
      override func viewDidLoad() {
        super.viewDidLoad()
    
        // Do any additional setup after loading the view.
      }
    
      override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
      }
    
      @IBAction func datePickerChanged(sender: AnyObject) {
        setDate()
      }
    
      let dateFormatter = NSDateFormatter()
    
      // MARK: - Date Format
      func setDate() {
        dateFormatter.dateFormat = "dd"
        dayDisplay.text = dateFormatter.stringFromDate(datePicker.date)
        dateFormatter.dateFormat = "MM"
        monthDisplay.text = dateFormatter.stringFromDate(datePicker.date)
        dateFormatter.dateFormat = "yyyy"
        yearDisplay.text = dateFormatter.stringFromDate(datePicker.date)
      }
    
    }
    

    【讨论】:

    • 我需要做故事板的工作,但是这段代码“打印”了正确的输出。谢谢@hashemi
    • 我收到 dayDisplay.text = dateFormatter.stringFromDate(datePicker.date) 的“致命错误:在展开可选值时意外发现 nil”。我认为 nil 来自日期选择器
    • 我敢打赌,dayDisplay 或 datePicker 都没有连接到界面生成器中的正确组件。
    【解决方案2】:

    您可以使用NSCalendar 获取两个日期之间的NSDateComponents。在 Swift 3 中:

    let components = Calendar.current.dateComponents([.day, .month, .year], from: date1, to: date2)
    let dayString = "\(components.day!)"
    let monthString = "\(components.month!)"
    let yearString = "\(components.year!)"
    

    或者在 Swift 2 中:

    let components = NSCalendar.currentCalendar().components([.Day, .Month, .Year], fromDate: date1, toDate: date2, options: [])
    let dayString = "\(components.day)"
    let monthString = "\(components.month)"
    let yearString = "\(components.year)"
    

    也许更简单,如果你想用一个字符串来表示这两个日期之间经过的时间,你可以使用NSDateComponentsFormatter,例如,在 Swift 3 中:

    let formatter = DateComponentsFormatter()
    formatter.allowedUnits = [.day, .month, .year]
    formatter.unitsStyle = .full
    let string = formatter.string(from: date1, to: date2)
    

    或者在 Swift 2 中:

    let formatter = NSDateComponentsFormatter()
    formatter.allowedUnits = [.Day, .Month, .Year]
    formatter.unitsStyle = .Full
    let string = formatter.stringFromDate(date1, toDate: date2)
    

    这个字符串也是本地化的。

    【讨论】:

      【解决方案3】:

      您可以使用NSCalender的方法components(fromDate: toDate: options:),使用NSDateComponents检索年月日

      例子

      let date = NSDate(timeIntervalSinceNow: -123123123)
      
      extension NSDate {
          func intereval(date:NSDate) -> (year: Int, month:Int, day:Int) {
              let calender = NSCalendar.currentCalendar()
      
             let components = calender.components([.Year, .Month, .Day], fromDate: date, toDate: self, options:.MatchStrictly)
              return (components.year, components.month, components.day)
          }
      }
      
      let component = NSDate().intereval(date)
      
      print(component.year)
      print(component.month)
      print(component.day)
      

      【讨论】:

        【解决方案4】:
        import Foundation
        
        let now = NSDate()
        now.description.characters.split {
            " -".characters.contains($0)
        }.enumerate().forEach {
            print($0.0,String($0.1))
        }
        /*
        0 2015
        1 12
        2 26
        3 19:34:33
        4 +0000
        */
        

        【讨论】:

        • 这在紧要关头有效,但要小心,因为日期描述格式可能会发生变化,例如取决于语言环境或 API 的变化。这可能会以奇怪或意想不到的方式破坏您的代码。
        • @hashemi 顺便说一句,NSCalendar API 也可以改变(它是否独立于语言环境??),就像所有其他 API 一样。描述是语言的一部分,与其他语言相比非常稳定。并且有据可查
        • 抱歉,我无法提供具体示例,但您可以参考 Apple 的 NSDate.description 文档,其中明确指出“该表示仅对调试有用”。然后指导您以可靠的方式获得日期表示的所有其他方式。 developer.apple.com/library/ios/documentation/Cocoa/Reference/…
        • @hashemi 我明白你的意思,你是对的。 description 属性在 Swift 中经常使用,如果苹果决定更改默认的 description 属性行为,您可以通过实现 CustomStringConvertible 协议作为扩展来“覆盖”它。
        • 宾果游戏。我并不是说这段代码不起作用或它将停止工作。这只是一个警告。干杯。
        猜你喜欢
        • 2018-10-10
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2023-01-31
        • 1970-01-01
        • 2013-03-05
        • 2020-04-29
        • 1970-01-01
        相关资源
        最近更新 更多