繁体   English   中英

swift 中未显示秒数的两个日期之间的差异

[英]difference between two dates not showing seconds in swift

在此处输入图像描述我有两个日期格式的日期。我使用以下代码来查找两个日期之间的差异。

extension Date {
    /// Returns the amount of years from another date
    func years(from date: Date) -> Int {
        return Calendar.current.dateComponents([.year], from: date, to: self).year ?? 0
    }
    /// Returns the amount of months from another date
    func months(from date: Date) -> Int {
        return Calendar.current.dateComponents([.month], from: date, to: self).month ?? 0
    }
    /// Returns the amount of weeks from another date
    func weeks(from date: Date) -> Int {
        return Calendar.current.dateComponents([.weekOfMonth], from: date, to: self).weekOfMonth ?? 0
    }
    /// Returns the amount of days from another date
    func days(from date: Date) -> Int {
        return Calendar.current.dateComponents([.day], from: date, to: self).day ?? 0
    }
    /// Returns the amount of hours from another date
    func hours(from date: Date) -> Int {
        return Calendar.current.dateComponents([.hour], from: date, to: self).hour ?? 0
    }
    /// Returns the amount of minutes from another date
    func minutes(from date: Date) -> Int {
        return Calendar.current.dateComponents([.minute], from: date, to: self).minute ?? 0
    }
    /// Returns the amount of seconds from another date
    func seconds(from date: Date) -> Int {
        return Calendar.current.dateComponents([.second], from: date, to: self).second ?? 0
    }
    /// Returns the a custom time interval description from another date
    func offset(from date: Date) -> String {
        if years(from: date)   > 0 { return "\(years(from: date))y"   }
        if months(from: date)  > 0 { return "\(months(from: date))M"  }
        if weeks(from: date)   > 0 { return "\(weeks(from: date))w"   }
        if days(from: date)    > 0 { return "\(days(from: date))d"    }
        if hours(from: date)   > 0 { return "\(hours(from: date))h"   }
        if minutes(from: date) > 0 { return "\(minutes(from: date))m" }
        if seconds(from: date) > 0 { return "\(seconds(from: date))s" }
        return ""
    }
    func offsetLong(from date: Date) -> String {
        if years(from: date)   > 0 { return years(from: date) > 1 ? "\(years(from: date)) yrs ago" : "\(years(from: date)) yr ago" }
        if months(from: date)  > 0 { return months(from: date) > 1 ? "\(months(from: date)) mo ago" : "\(months(from: date)) mo ago" }
        if weeks(from: date)   > 0 { return weeks(from: date) > 1 ? "\(weeks(from: date)) wks ago" : "\(weeks(from: date)) wk ago"   }
        if days(from: date)    > 0 { return days(from: date) > 1 ? "\(days(from: date)) days ago" : "\(days(from: date)) day ago" }
        if hours(from: date)   > 0 { return hours(from: date) > 1 ? "\(hours(from: date)) hrs ago" : "\(hours(from: date)) hr ago"   }
        if minutes(from: date) > 0 { return minutes(from: date) > 1 ? "\(minutes(from: date)) mins ago" : "\(minutes(from: date)) min ago" }
        if seconds(from: date) > 0 { return seconds(from: date) > 1 ? "\(seconds(from: date)) secs ago" : "\(seconds(from: date)) sec ago" }
        return ""
    }
}

我已在 EDT 时区的两个日期应用此扩展,如下所示:

let dateFormatterGet = DateFormatter()
                       // dateFormatterGet.timeZone = TimeZone(abbreviation: "UTC")
                        dateFormatterGet.dateFormat = "yyyy-MM-dd HH:mm:ss"

                        let dateFormatterPrint = DateFormatter()
                       // dateFormatterPrint.timeZone = TimeZone(abbreviation: "UTC")
                         dateFormatterPrint.dateFormat = "yyyy-MM-dd HH:mm:ss"

                        let date1: Date? = dateFormatterGet.date(from: date) as Date?
                        
                     //   print("date1 is",date1)

                                let now = Date()
                                
                                let dateFormatterGet1 = DateFormatter()
                                dateFormatterGet1.timeZone = TimeZone(abbreviation: "EDT")
                                dateFormatterGet1.dateFormat = "yyyy-MM-dd HH:mm:ss"
                                
                                let dateFormatterPrint1 = DateFormatter()
                                 dateFormatterPrint1.timeZone = TimeZone(abbreviation: "EDT")
                                 dateFormatterPrint1.dateFormat = "yyyy-MM-dd HH:mm:ss"
                                
                                let dat = dateFormatterPrint1.string(from: now) as String
                             
                                           
                                let date2: Date? = dateFormatterGet1.date(from: dat) as Date?
                              
                               let timeOffset3 = date2!.offsetLong(from: date1!)
                               
                                cell2.dateposted.text = timeOffset3

时间偏移值显示到几小时,而不是以分钟或秒显示。 谁能告诉我这个转换有什么问题?

有一个内置的 class DateComponentsFormatter ,它将根据时间间隔或一对日期创建格式化字符串。 您可以使用所需的单位和所需的单位样式对其进行配置,它会执行 rest。 它仅提供某些预设格式(使用 DateComponentsFormatter.UnitsStyle 指定)

如果您想以任意格式显示两个日期之间的差异,则可能需要使用Calendar function dateComponents(_:from:to:) function 需要两个日期和一组您要使用的组件,并返回一个 DateComponents object。 然后,您需要编写自定义代码,以您想要的格式显示DateComponents object 的值,这应该不难。

如果您在问题中解释了您想要的 output 将会有所帮助。

好的,我看了一下图片。 看起来您想要一个字符串,例如“3 分钟前”“7 小时前”“三天前”、“三个月前”等。

试试这样的代码:

import Foundation

 var timeFormatter:DateComponentsFormatter = {
    let temp = DateComponentsFormatter()
    temp.allowedUnits = [.year, .month, .weekOfMonth, .day, .hour, .minute, .second]
    temp.maximumUnitCount = 1
    temp.unitsStyle = .full
    return temp
}()

let now = Date()

func timefromDateToNow(_ date: Date) -> String {
    if let output = timeFormatter.string(from: date, to: now) {
        return output + " ago"
    } else {
        return "error"
    }
}

enum Ranges: Int, CaseIterable {
    case seconds
    case minutes
    case hours
    case days
    case weeks
    case months
    case years
}

for _ in 1 ... 20 {
    var min: Double
    var max: Double = 0
    let range = Ranges.allCases.randomElement()!
    switch range {
    case .seconds:
        min = -59.999
    case .minutes: //0 ... 1 hours
        min = -3600
    case .hours: //0 ... 1 day
        min = -86400
    case .days: //0 ... 1 month
        min = -3600 * 24 * 31
    case .weeks:
        min = -3600 * 24 * 31
        max = -3600 * 24 * 7
    case .months:
        min = -3600 * 24 * 365
    case .years: // 0 ... 5 years
        min = -3600 * 24 * 365 * 5
    }
    let past = now.addingTimeInterval(Double.random(in: min ... max))
    print("Range = \(range): \(timefromDateToNow(past))")
}


var units: NSCalendar.Unit

//Note that all 3 methods of populating `units' yields the same value:

print("\nNow show that the order of OptionSet values does not matter:\n")
units = [.year, .second, .month, .hour]
print(units.rawValue)

units = [.second, .hour, .month, .year]
print(units.rawValue)


units = NSCalendar.Unit( rawValue:
                            NSCalendar.Unit.month.rawValue +
                            NSCalendar.Unit.year.rawValue +
                            NSCalendar.Unit.second.rawValue +
                            NSCalendar.Unit.hour.rawValue
)
print(units.rawValue)

这会生成 output ,如下所示:

Range = years: 3 years ago
Range = seconds: 56 seconds ago
Range = months: 9 months ago
Range = minutes: 27 minutes ago
Range = minutes: 34 minutes ago
Range = hours: 15 hours ago
Range = years: 1 year ago
Range = months: 2 months ago
Range = years: 1 year ago
Range = years: 3 years ago
Range = years: 3 years ago
Range = years: 3 years ago
Range = years: 2 months ago
Range = years: 2 years ago
Range = seconds: 59 seconds ago
Range = days: 6 days ago
Range = weeks: 3 weeks ago
Range = years: 11 months ago
Range = hours: 16 hours ago
Range = hours: 7 hours ago

Now show that the order of OptionSet values does not matter:

172
172
172

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM