实现模糊日期

时间:2015-01-17 20:56:58

标签: ios iphone swift

尝试从以下函数输出模糊日期:

import Foundation

let kMinute = 60
let kDay = kMinute * 24
let kWeek = kDay * 7
let kMonth = kDay * 31
let kYear = kDay * 365

func NSDateTimeAgoLocalizedStrings(key: String) -> String {

    let resourcePath = NSBundle.mainBundle().resourcePath
    let path = resourcePath?.stringByAppendingPathComponent("NSDateTimeAgo.bundle")
    let bundle = NSBundle(path: path!)

    return NSLocalizedString(key, tableName: "NSDateTimeAgo", bundle: bundle!, comment: "")
}

extension NSDate {

    // shows 1 or two letter abbreviation for units.
    // does not include 'ago' text ... just {value}{unit-abbreviation}
    // does not include interim summary options such as 'Just now'
    var timeAgoSimple: String {

        let now = NSDate()
        let deltaSeconds = Int(fabs(timeIntervalSinceDate(now)))
        let deltaMinutes = deltaSeconds / 60

        var value: Int!

        if deltaSeconds < kMinute {
            // Seconds
            return stringFromFormat("%%d%@s", withValue: deltaSeconds)
        } else if deltaMinutes < kMinute {
            // Minutes
            return stringFromFormat("%%d%@m", withValue: deltaMinutes)
        } else if deltaMinutes < kDay {
            // Hours
            value = Int(floor(Float(deltaMinutes / kMinute)))
            return stringFromFormat("%%d%@h", withValue: value)
        } else if deltaMinutes < kWeek {
            // Days
            value = Int(floor(Float(deltaMinutes / kDay)))
            return stringFromFormat("%%d%@d", withValue: value)
        } else if deltaMinutes < kMonth {
            // Weeks
            value = Int(floor(Float(deltaMinutes / kWeek)))
            return stringFromFormat("%%d%@w", withValue: value)
        } else if deltaMinutes < kYear {
            // Month
            value = Int(floor(Float(deltaMinutes / kMonth)))
            return stringFromFormat("%%d%@mo", withValue: value)
        }

        // Years
        value = Int(floor(Float(deltaMinutes / kYear)))
        return stringFromFormat("%%d%@yr", withValue: value)
    }

    var timeAgo: String {

        let now = NSDate()
        let deltaSeconds = Int(fabs(timeIntervalSinceDate(now)))
        let deltaMinutes = deltaSeconds / 60

        var value: Int!

        if deltaSeconds < 5 {
            // Just Now
            return NSDateTimeAgoLocalizedStrings("Just now")
        } else if deltaSeconds < kMinute {
            // Seconds Ago
            return stringFromFormat("%%d %@seconds ago", withValue: deltaSeconds)
        } else if deltaSeconds < 120 {
            // A Minute Ago
            return NSDateTimeAgoLocalizedStrings("A minute ago")
        } else if deltaMinutes < kMinute {
            // Minutes Ago
            return stringFromFormat("%%d %@minutes ago", withValue: deltaMinutes)
        } else if deltaMinutes < 120 {
            // An Hour Ago
            return NSDateTimeAgoLocalizedStrings("An hour ago")
        } else if deltaMinutes < kDay {
            // Hours Ago
            value = Int(floor(Float(deltaMinutes / kMinute)))
            return stringFromFormat("%%d %@hours ago", withValue: value)
        } else if deltaMinutes < (kDay * 2) {
            // Yesterday
            return NSDateTimeAgoLocalizedStrings("Yesterday")
        } else if deltaMinutes < kWeek {
            // Days Ago
            value = Int(floor(Float(deltaMinutes / kDay)))
            return stringFromFormat("%%d %@days ago", withValue: value)
        } else if deltaMinutes < (kWeek * 2) {
            // Last Week
            return NSDateTimeAgoLocalizedStrings("Last week")
        } else if deltaMinutes < kMonth {
            // Weeks Ago
            value = Int(floor(Float(deltaMinutes / kWeek)))
            return stringFromFormat("%%d %@weeks ago", withValue: value)
        } else if deltaMinutes < (kDay * 61) {
            // Last month
            return NSDateTimeAgoLocalizedStrings("Last month")
        } else if deltaMinutes < kYear {
            // Month Ago
            value = Int(floor(Float(deltaMinutes / kMonth)))
            return stringFromFormat("%%d %@months ago", withValue: value)
        } else if deltaMinutes < (kDay * (kYear * 2)) {
            // Last Year
            return NSDateTimeAgoLocalizedStrings("Last Year")
        }

        // Years Ago
        value = Int(floor(Float(deltaMinutes / kYear)))
        return stringFromFormat("%%d %@years ago", withValue: value)

    }

    func stringFromFormat(format: String, withValue value: Int) -> String {

        let localeFormat = String(format: format, getLocaleFormatUnderscoresWithValue(Double(value)))

        return String(format: NSDateTimeAgoLocalizedStrings(localeFormat), value)
    }

    func getLocaleFormatUnderscoresWithValue(value: Double) -> String {

        let localeCode = NSLocale.preferredLanguages().first as String

        if localeCode == "fr" {
            let XY = Int(floor(value)) % 100
            let Y = Int(floor(value)) % 10

            if Y == 0 || Y > 4 || (XY > 10 && XY < 15) {
                return ""
            }

            if Y > 1 && Y < 5 && (XY < 10 || XY > 20) {
                return "_"
            }

            if Y == 1 && XY != 11 {
                return "__"
            }
        }

        return ""
    }

} 

现在调用这样的函数时:

import UIKit

class ViewController: UIViewController {

    @IBOutlet weak var fuzzyDate: UITextField!

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.

        var dateNow = "Jan 17, 2015, 3:31 AM"

        fuzzyDate.text = NSDateTimeAgoLocalizedStrings(dateNow)
    }

}

结果是“2015年1月17日,上午3:31”而不是“xx小时前”。我做错了什么?新手在这里。

谢谢!

1 个答案:

答案 0 :(得分:2)

您的代码

var dateNow = "Jan 17, 2015, 3:31 AM"
fuzzyDate.text = NSDateTimeAgoLocalizedStrings(dateNow)

无处调用您定义的timeAgo方法。 它只对给定的字符串进行本地化,无需任何日期或时间计算。

您必须将String“2015年1月17日,上午3:31”转换为 NSDate首先使用日期格式化程序

var dateNow = "Jan 17, 2015, 3:31 AM"
let fmt = NSDateFormatter()
fmt.locale = NSLocale(localeIdentifier: "en_US_POSIX")
fmt.dateFormat = "MMM dd, yyyy, hh:mm a"
let date = fmt.dateFromString(dateNow)!

然后您可以将timeAgo方法应用于该日期 得到“模糊字符串”:

fuzzyDate.text = date.timeAgo // Result: 8 hours ago

备注:所有超出小时范围的日期和时间计算 最好使用NSCalendarNSDateComponent方法完成, 而不是“简单地”除以60,24,7,31或365。 原因是有几天23或25小时(夏令时 时间转换),所以不是每天都有24 * 60 * 60秒。 也不是每个月都有31天,一年可能有356或366天。