Swift 转换时间到以前

标签 swift parse-platform nsdate

在 Swift5 中,我们有 RelativeDateTimeFormatter

在 Swift5 之前:


我正在尝试将时间转换为以前的时间,我想做的是:

从 1 到 15 秒,它会说“刚刚”

从 60 分钟到 119 分钟,它会说“一个小时前”

从 24 小时到 47 小时它会说“昨天”

从 7 天到 7 天 23 小时它会说“一周前”

我不确定我的计数是否错误,请随时为我修复

这是代码

    extension NSDate {

    struct Date {
        static let timeFormatter: NSDateFormatter = {
            let df = NSDateFormatter()
            df.calendar = NSCalendar(calendarIdentifier: NSCalendarIdentifierGregorian)
            df.dateFormat = "h:mm a"
            return df
            }()
    }
    var time: String { return Date.timeFormatter.stringFromDate(self) }

    var year:    Int { return NSCalendar.autoupdatingCurrentCalendar().component(.Year,   fromDate: self) }
    var month:   Int { return NSCalendar.autoupdatingCurrentCalendar().component(.Month,  fromDate: self) }
    var day:     Int { return NSCalendar.autoupdatingCurrentCalendar().component(.Day,    fromDate: self) }
    var hour:     Int { return NSCalendar.autoupdatingCurrentCalendar().component(.Hour,    fromDate: self) }
    var minute:     Int { return NSCalendar.autoupdatingCurrentCalendar().component(.Minute,    fromDate: self) }
    var second:     Int { return NSCalendar.autoupdatingCurrentCalendar().component(.Second,    fromDate: self) }


    struct DateComponents {
        static let formatter: NSDateComponentsFormatter = {
            let dcFormatter = NSDateComponentsFormatter()
            dcFormatter.calendar = NSCalendar(identifier: NSCalendarIdentifierISO8601)!
            dcFormatter.unitsStyle = .Full
            dcFormatter.maximumUnitCount = 1
            dcFormatter.zeroFormattingBehavior = .Default
            dcFormatter.allowsFractionalUnits = false
            dcFormatter.allowedUnits = [.Year, .Month, .Weekday, .Day, .Hour, .Minute, .Second]
            return dcFormatter
            }()
    }

    var elapsedTime: String {


        if isecond(NSDate()) {
            return "Just now"

        }

        if ishour(NSDate()) {
           return "an hour ago"

        }
        if isyesterday(NSDate()) {
            return "Yesterday"
        }
        if isweek(NSDate()) {

            return "a week ago"
        }




        return (DateComponents.formatter.stringFromTimeInterval(NSDate().timeIntervalSinceDate(self)) ?? "") + " ago"
    }
    func isyesterday(date: NSDate) -> Bool {
        return  NSCalendar.autoupdatingCurrentCalendar().isDate(self, inSameDayAsDate: date.yesterday)
    }
    var yesterday: NSDate {
        return  NSCalendar.autoupdatingCurrentCalendar().dateWithEra(1, year: year, month: month, day: day-1, hour: 0, minute: 0, second: 0, nanosecond: 0)!
    }



    func isweek(date: NSDate) -> Bool {
        return  NSCalendar.autoupdatingCurrentCalendar().isDate(self, inSameDayAsDate: date.weekago)
    }
    var weekago: NSDate {
        return  NSCalendar.autoupdatingCurrentCalendar().dateWithEra(1, year: year, month: month, day: day-7, hour: 0, minute: 0, second: 0, nanosecond: 0)!
    }

    func isecond(date: NSDate) -> Bool {
        return  NSCalendar.autoupdatingCurrentCalendar().isDate(self, inSameDayAsDate: date.secondsago)
    }
    var secondsago: NSDate {
        return  NSCalendar.autoupdatingCurrentCalendar().dateWithEra(1, year: year, month: month, day: 0, hour: 0, minute: 0, second: second-15, nanosecond: 0)!
    }

    func ishour(date: NSDate) -> Bool {
        return  NSCalendar.autoupdatingCurrentCalendar().isDate(self, inSameDayAsDate: date.hourago)
    }
    var hourago: NSDate {
        return  NSCalendar.autoupdatingCurrentCalendar().dateWithEra(1, year: year, month: month, day: 0, hour: hour-1, minute: minute-1, second: 0, nanosecond: 0)!
    }
}

这是我在我的应用程序中得到的: enter image description here

“一小时前”、“刚刚”等没有显示,只有“昨天”,我不确定是否只有 7 天到 23 小时!

这是我的第一个问题链接:Swift How to convert Parse createdAt time to time ago?

请帮我修改代码, 感谢@Leo Dabus 提供的代码。

最佳答案

我将更新 Truongky 对 Swif 3 的回答:

extension Date {

func getElapsedInterval() -> String {

    let interval = Calendar.current.dateComponents([.year, .month, .day], from: self, to: Date())

    if let year = interval.year, year > 0 {
        return year == 1 ? "\(year)" + " " + "year ago" :
            "\(year)" + " " + "years ago"
    } else if let month = interval.month, month > 0 {
        return month == 1 ? "\(month)" + " " + "month ago" :
            "\(month)" + " " + "months ago"
    } else if let day = interval.day, day > 0 {
        return day == 1 ? "\(day)" + " " + "day ago" :
            "\(day)" + " " + "days ago"
    } else {
        return "a moment ago"

    }

}
}

如果您更喜欢可本地化的响应而不仅仅是英语,则此代码可以完成工作

extension Date {
func getElapsedInterval() -> String {

    var calendar = Calendar.current
    calendar.locale = Locale(identifier: Bundle.main.preferredLocalizations[0]) 
// IF THE USER HAVE THE PHONE IN SPANISH BUT YOUR APP ONLY SUPPORTS I.E. ENGLISH AND GERMAN
// WE SHOULD CHANGE THE LOCALE OF THE FORMATTER TO THE PREFERRED ONE 
// (IS THE LOCALE THAT THE USER IS SEEING THE APP), IF NOT, THIS ELAPSED TIME 
// IS GOING TO APPEAR IN SPANISH

    let formatter = DateComponentsFormatter()
    formatter.unitsStyle = .full
    formatter.maximumUnitCount = 1
    formatter.calendar = calendar

    var dateString: String?

    let interval = calendar.dateComponents([.year, .month, .weekOfYear, .day], from: self, to: Date())

    if let year = interval.year, year > 0 {
        formatter.allowedUnits = [.year] //2 years
    } else if let month = interval.month, month > 0 {
        formatter.allowedUnits = [.month] //1 month
    } else if let week = interval.weekOfYear, week > 0 {
        formatter.allowedUnits = [.weekOfMonth] //3 weeks
    } else if let day = interval.day, day > 0 {
        formatter.allowedUnits = [.day] // 6 days
    } else {
        let dateFormatter = DateFormatter()
        dateFormatter.locale = Locale(identifier: Bundle.main.preferredLocalizations[0]) //--> IF THE USER HAVE THE PHONE IN SPANISH BUT YOUR APP ONLY SUPPORTS I.E. ENGLISH AND GERMAN WE SHOULD CHANGE THE LOCALE OF THE FORMATTER TO THE PREFERRED ONE (IS THE LOCALE THAT THE USER IS SEEING THE APP), IF NOT, THIS ELAPSED TIME IS GOING TO APPEAR IN SPANISH
        dateFormatter.dateStyle = .medium
        dateFormatter.doesRelativeDateFormatting = true

        dateString = dateFormatter.string(from: self) // IS GOING TO SHOW 'TODAY'
    }

    if dateString == nil {
        dateString = formatter.string(from: self, to: Date())
    }

    return dateString!
}

关于Swift 转换时间到以前,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34457434/

相关文章:

parse-platform - 如何使用内容类型为 zip 的 Parse.Cloud.httpRequest 下载文件

javascript - parse.com 云代码问题,但在 javascript 中运行完美

ios - 允许 iOS 应用程序用户通过 Twilio 号码、Parse 后端相互调用电话和发短信

ios - 从 UTC-5 时区日期和时间 iPhone 应用程序获取当前 iPhone 设备时区日期和时间?

swift - iOS 9、Xcode 7、带 SpriteKit 的多点触控

ios - 在完成 block 中识别 NSURLSession

ios - Swift:标签文本问题(获取相同数组的不同计数)来自 API 的响应

swift - List SwiftUI 中的粘性页脚

ios - 具有不同格式的 Swift Date 对象

ios - objective c error "No visible @interface for ' NSString' declares the selector 'timeIntervalSinceDate:' "