实施模糊日期
Implementing Fuzzy Dates
正在尝试从以下函数输出模糊日期:
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)
}
}
结果是 "Jan 17, 2015, 3:31 AM" 而不是 "xx hours ago"。我做错了什么?这里是新手。
谢谢!
您的代码
var dateNow = "Jan 17, 2015, 3:31 AM"
fuzzyDate.text = NSDateTimeAgoLocalizedStrings(dateNow)
没有任何地方调用您定义的 timeAgo
方法。
它只本地化给定的字符串,没有任何日期或时间计算。
您必须将 String
"Jan 17, 2015, 3:31 AM" 转换为
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
方法应用于该日期
得到 "fuzzy string":
fuzzyDate.text = date.timeAgo // Result: 8 hours ago
备注:所有超出小时范围的日期和时间计算
最好使用 NSCalendar
和 NSDateComponent
方法来完成,
而不是 "simply" 除以 60、24、7、31 或 365。
原因是有些日子有 23 或 25 小时(夏令时
时间转换),所以不是每一天都有 24*60*60 秒。
也不是每个月都有31天,一年可能有356或366天。
正在尝试从以下函数输出模糊日期:
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)
}
}
结果是 "Jan 17, 2015, 3:31 AM" 而不是 "xx hours ago"。我做错了什么?这里是新手。
谢谢!
您的代码
var dateNow = "Jan 17, 2015, 3:31 AM"
fuzzyDate.text = NSDateTimeAgoLocalizedStrings(dateNow)
没有任何地方调用您定义的 timeAgo
方法。
它只本地化给定的字符串,没有任何日期或时间计算。
您必须将 String
"Jan 17, 2015, 3:31 AM" 转换为
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
方法应用于该日期
得到 "fuzzy string":
fuzzyDate.text = date.timeAgo // Result: 8 hours ago
备注:所有超出小时范围的日期和时间计算
最好使用 NSCalendar
和 NSDateComponent
方法来完成,
而不是 "simply" 除以 60、24、7、31 或 365。
原因是有些日子有 23 或 25 小时(夏令时
时间转换),所以不是每一天都有 24*60*60 秒。
也不是每个月都有31天,一年可能有356或366天。