【问题标题】:Calculate age from string swift从字符串 swift 计算年龄
【发布时间】:2021-03-27 19:08:02
【问题描述】:

我正在尝试计算从婴儿到成人(例如 8 周大、4 个月大或 22 岁)的任何人的年龄。但是我的计算失败了,我找不到在哪里。如果我在 2020 年 10 月 16 日输入 DOB,它会返回 8 周大,这是正确的。但是,如果我输入 2020 年 10 月 26 日,它会返回 11 周,这是不正确的。非常感谢任何帮助。

年龄函数:

let bornOn = "10/16/2020"
func calculateAge(dob: String, format: String = "MM/dd/yyyy") -> String{
    let df = DateFormatter()
    df.dateFormat = format
    let date = df.date(from: dob)
    guard let val = date else{
        return ""
    }
    var years = 0
    var months = 0
    var days = 0
    
    let cal = Calendar.current
    years = cal.component(.year, from: Date()) - cal.component(.year, from: val)
    
    let currentMonth = cal.component(.month, from: Date())
    let birthMonth = cal.component(.month, from: val)
    
    months = currentMonth - birthMonth
    
    if months < 0 {
        years = years - 1
        months = 12 - birthMonth
        if cal.component(.day, from: Date()) < cal.component(.day, from: val){
            months = months - 1
        }
    }else if months == 0 && cal.component(.day, from: Date()) < cal.component(.day, from: val){
        years = years - 1
        months = 11
    }
    if cal.component(.day, from: Date()) > cal.component(.day, from: val){
        days = cal.component(.day, from: Date()) - cal.component(.day, from: val)
    }else if cal.component(.day, from: Date()) < cal.component(.day, from: val){
        let today = cal.component(.day, from: Date())
        let date = cal.date(byAdding: .month, value: -1, to: Date())
        days = date!.daysInMonth - cal.component(.day, from: val) + today
    }else{
        days = 0
        if months == 12 {
            years = years + 1
            months = 0
        }
    }
    print("Years: \(years), Months: \(months), Days: \(days)")
    if years > 0{
        if years == 1{
            return "\(years) year old"
        }else{
        return "\(years) years old"
        }
    }else if months > 4{
        return "\(months) months old"
    }else {
        if  months >= 1{
            let daysleftInMonth = months * 30
            print(daysleftInMonth)
            days += daysleftInMonth
        }
       
        let weeks = days / 7
       return "\(weeks) weeks old"
    }
}

extension Date{
     var daysInMonth:Int{
        let calendar = Calendar.current
        
        let dateComponents = DateComponents(year: calendar.component(.year, from: self), month: calendar.component(.month, from: self))
        let date = calendar.date(from: dateComponents)!
        
        let range = calendar.range(of: .day, in: .month, for: date)!
        let numDays = range.count
        
        return numDays
    }
}
calculateAge(dob: bornOn)

【问题讨论】:

    标签: swift string date


    【解决方案1】:

    你走错了方向。您需要解析日期字符串并将其转换为日期并使用 DateComponentsFormatter 来显示此人的年龄。您还可以获取从生日到今天的日期组件:

    extension Formatter {
        static let dateMMddyyyy: DateFormatter = {
            let formatter = DateFormatter()
            formatter.locale = .init(identifier: "en_US_POSIX")
            formatter.dateFormat = "MM/dd/yyyy"
            return formatter
        }()
        static let dateComponents: DateComponentsFormatter = {
            let formatter = DateComponentsFormatter()
            formatter.unitsStyle = .full
            formatter.allowedUnits = [.day, .month, .year]
            formatter.maximumUnitCount = 1
            return formatter
        }()
    }
    

    extension Date {
        var ageComponents: DateComponents { Calendar.current.dateComponents([.year, .month, .day], from: self, to: Date()) }
        var relativeAge: String {
            Formatter.dateComponents.allowedUnits = ageComponents.month! >= 2 ?
                [.day, .month, .year] : [.weekOfMonth]
            return Formatter.dateComponents.string(from: self, to: Date())! 
        }
    }
    

    extension String {
        var dateFromMMddyyyy: Date? { Formatter.dateMMddyyyy.date(from: self) }
    }
    

    "09/10/1970".dateFromMMddyyyy?.relativeAge  // "50 years"
    "10/16/2020".dateFromMMddyyyy?.relativeAge  // "2 months"
    "10/23/2020".dateFromMMddyyyy?.relativeAge  // "7 weeks"
    

    【讨论】:

    • 我认为 OP 对于何时显示周数(少于 4 个月)有一些自定义逻辑,但建议还是不错的。
    【解决方案2】:
    extension Date {
        func timeAgo() -> String {
            let formatter = DateComponentsFormatter()
            formatter.unitsStyle = .full
            formatter.allowedUnits = [.year, .month, .weekOfMonth ,.day, .hour, .minute, .second]
            formatter.zeroFormattingBehavior = .dropAll
            formatter.maximumUnitCount = 1
            return String(format: formatter.string(from: self, to: Date()) ?? "", locale: .current)
        }
    }
    

    在您的方法中使用上述日期扩展

    func calculateAge(dob: String, format: String = "MM/dd/yyyy") -> String{
           let df = DateFormatter()
           df.dateFormat = format
           let date = df.date(from: dob)
           return date?.timeAgo() ?? ""
    }
    

    像这样使用它,

    let date = calculateAge(dob: bornOn)
    print(date) //print - 2 weeks
    

    【讨论】:

      猜你喜欢
      • 2023-03-29
      • 1970-01-01
      • 2011-08-21
      • 1970-01-01
      • 1970-01-01
      • 2022-07-11
      • 2012-03-26
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多