-
-
Save jinthagerman/009c85b7bbd0a40dcbba747e89a501bf to your computer and use it in GitHub Desktop.
import Foundation | |
struct DateComponentUnitFormatter { | |
private struct DateComponentUnitFormat { | |
let unit: Calendar.Component | |
let singularUnit: String | |
let pluralUnit: String | |
let futureSingular: String | |
let pastSingular: String | |
} | |
private let formats: [DateComponentUnitFormat] = [ | |
DateComponentUnitFormat(unit: .year, | |
singularUnit: "year", | |
pluralUnit: "years", | |
futureSingular: "Next year", | |
pastSingular: "Last year"), | |
DateComponentUnitFormat(unit: .month, | |
singularUnit: "month", | |
pluralUnit: "months", | |
futureSingular: "Next month", | |
pastSingular: "Last month"), | |
DateComponentUnitFormat(unit: .weekOfYear, | |
singularUnit: "week", | |
pluralUnit: "weeks", | |
futureSingular: "Next week", | |
pastSingular: "Last week"), | |
DateComponentUnitFormat(unit: .day, | |
singularUnit: "day", | |
pluralUnit: "days", | |
futureSingular: "Tomorrow", | |
pastSingular: "Yesterday"), | |
DateComponentUnitFormat(unit: .hour, | |
singularUnit: "hour", | |
pluralUnit: "hours", | |
futureSingular: "In an hour", | |
pastSingular: "An hour ago"), | |
DateComponentUnitFormat(unit: .minute, | |
singularUnit: "minute", | |
pluralUnit: "minutes", | |
futureSingular: "In a minute", | |
pastSingular: "A minute ago"), | |
DateComponentUnitFormat(unit: .second, | |
singularUnit: "second", | |
pluralUnit: "seconds", | |
futureSingular: "Just now", | |
pastSingular: "Just now"), | |
] | |
func string(forDateComponents dateComponents: DateComponents, useNumericDates: Bool) -> String { | |
for format in self.formats { | |
let unitValue: Int | |
switch format.unit { | |
case .year: | |
unitValue = dateComponents.year ?? 0 | |
case .month: | |
unitValue = dateComponents.month ?? 0 | |
case .weekOfYear: | |
unitValue = dateComponents.weekOfYear ?? 0 | |
case .day: | |
unitValue = dateComponents.day ?? 0 | |
case .hour: | |
unitValue = dateComponents.hour ?? 0 | |
case .minute: | |
unitValue = dateComponents.minute ?? 0 | |
case .second: | |
unitValue = dateComponents.second ?? 0 | |
default: | |
assertionFailure("Date does not have requried components") | |
return "" | |
} | |
switch unitValue { | |
case 2 ..< Int.max: | |
return "\(unitValue) \(format.pluralUnit) ago" | |
case 1: | |
return useNumericDates ? "\(unitValue) \(format.singularUnit) ago" : format.pastSingular | |
case -1: | |
return useNumericDates ? "In \(-unitValue) \(format.singularUnit)" : format.futureSingular | |
case Int.min ..< -1: | |
return "In \(-unitValue) \(format.pluralUnit)" | |
default: | |
break | |
} | |
} | |
return "Just now" | |
} | |
} | |
extension Date { | |
func timeAgoSinceNow(useNumericDates: Bool = false) -> String { | |
let calendar = Calendar.current | |
let unitFlags: Set<Calendar.Component> = [.minute, .hour, .day, .weekOfYear, .month, .year, .second] | |
let now = Date() | |
let components = calendar.dateComponents(unitFlags, from: self, to: now) | |
let formatter = DateComponentUnitFormatter() | |
return formatter.string(forDateComponents: components, useNumericDates: useNumericDates) | |
} | |
} |
Awesome!
I've made some changes to conform to my project's needs, referencing your work. Check it out: https://gist.github.com/ckalbas/eccdc7db6893001d0811dea7823549a2
Great job, thanks!
Thanks!!!! Awesome job!
I want to get the new string according to the currentTimeZone?
For example : My date is 2019-08-20 21:50:00 UTC
I am in IST
I get "Tomorrow"
But i need to get it according to IST which should be day after tomorrow
Sounds like your date might be deserializing incorrectly? If you convert it to a string using DateFormatter
, is it in the correct time zone?
Sounds like your date might be deserializing incorrectly? If you convert it to a string using
DateFormatter
, is it in the correct time zone?
No, my serailizing is fine. But the relative time that is being returned is according to UTC which is not my timezone
That doesn't make sense. There's no presumption of time zone in this code and Date
is time zone independent ("A specific point in time, independent of any calendar or time zone." - Apple Docs).
you just saved me an hour thanks