Use*_*343 39 objective-c nsdate relative-date nsdateformatter ios
我想将nsdate转换为相对格式"Today","Yesterday","a week ago","a month ago","a year ago","date as it is"
.
我已经为它写了以下方法..但有些如何只是打印,因为它是日期..你能告诉我应该是什么问题吗?
//以下是我的函数,它将日期转换为相对字符串
+(NSString *)getDateDiffrence:(NSDate *)strDate{
NSDateFormatter *df = [[NSDateFormatter alloc] init];
df.timeStyle = NSDateFormatterMediumStyle;
df.dateStyle = NSDateFormatterShortStyle;
df.doesRelativeDateFormatting = YES;
NSLog(@"STRING DATEEE : %@ REAL DATE TODAY %@",[df stringFromDate:strDate],[NSDate date]);
return [df stringFromDate:strDate];
}
Run Code Online (Sandbox Code Playgroud)
我有以下格式的日期字符串 "2013-10-29T09:38:00"
当我试图给出NSDate对象时,它总是返回我的null日期.
所以我试图将该日期转换为yyyy-MM-dd HH:mm:ssZZZZ
然后我将此日期传递给函数然后它只是打印整个日期..
如何解决这个问题呢?
//以下是我调用上述函数的代码
NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
[formatter setDateFormat:@"yyyy-MM-dd'T'HH:mm:ss"];
NSDate *date = [formatter dateFromString:[threadDict objectForKey:@"lastMessageDate"]];
[formatter setDateFormat:@"yyyy-MM-dd HH:mm:ssZZZZ"];
NSString *date1 = [formatter stringFromDate:date];
NSDate *date_d = [formatter dateFromString:date1];
NSString *resultstr=[UserManager getDateDiffrence:date];
self.dateLabel.text=resultstr;
Run Code Online (Sandbox Code Playgroud)
Dav*_*ist 56
为简单起见,我假设你格式化的日期都是过去的(没有"明天"或"下周").并不是说它不能完成,而是处理更多的情况并返回更多的字符串.
您可以使用所需components:fromDate:toDate:options:
的任何日期组件组合来获取两个日期之间的年数,月数,周数,天数,小时数等.然后,按照从最重要(例如年份)到最不重要(例如日)的顺序浏览它们,您可以仅基于最重要的组件格式化字符串.
例如:1周,2天和7小时前的日期将被格式化为"1周".
如果要为特定数量的单元创建特殊字符串,例如"明天"为"1天前",则可以在确定该组件是最重要的组件后检查该组件的值.
代码看起来像这样:
- (NSString *)relativeDateStringForDate:(NSDate *)date
{
NSCalendarUnit units = NSCalendarUnitDay | NSCalendarUnitWeekOfYear |
NSCalendarUnitMonth | NSCalendarUnitYear;
// if `date` is before "now" (i.e. in the past) then the components will be positive
NSDateComponents *components = [[NSCalendar currentCalendar] components:units
fromDate:date
toDate:[NSDate date]
options:0];
if (components.year > 0) {
return [NSString stringWithFormat:@"%ld years ago", (long)components.year];
} else if (components.month > 0) {
return [NSString stringWithFormat:@"%ld months ago", (long)components.month];
} else if (components.weekOfYear > 0) {
return [NSString stringWithFormat:@"%ld weeks ago", (long)components.weekOfYear];
} else if (components.day > 0) {
if (components.day > 1) {
return [NSString stringWithFormat:@"%ld days ago", (long)components.day];
} else {
return @"Yesterday";
}
} else {
return @"Today";
}
}
Run Code Online (Sandbox Code Playgroud)
如果您的日期也可以在将来,那么您可以按相同的顺序检查组件的绝对值,然后检查它是正还是负,以返回相应的字符串.我只展示下面的一年:
if ( abs(components.year > 0) ) {
// year is most significant component
if (components.year > 0) {
// in the past
return [NSString stringWithFormat:@"%ld years ago", (long)components.year];
} else {
// in the future
return [NSString stringWithFormat:@"In %ld years", (long)components.year];
}
}
Run Code Online (Sandbox Code Playgroud)
Chr*_*sJF 13
这是我的回答(在Swift 3中!)以及为什么它更好.
func datePhraseRelativeToToday(from date: Date) -> String {
// Don't use the current date/time. Use the end of the current day
// (technically 0h00 the next day). Apple's calculation of
// doesRelativeDateFormatting niavely depends on this start date.
guard let todayEnd = dateEndOfToday() else {
return ""
}
let calendar = Calendar.autoupdatingCurrent
let units = Set([Calendar.Component.year,
Calendar.Component.month,
Calendar.Component.weekOfMonth,
Calendar.Component.day])
let difference = calendar.dateComponents(units, from: date, to: todayEnd)
guard let year = difference.year,
let month = difference.month,
let week = difference.weekOfMonth,
let day = difference.day else {
return ""
}
let timeAgo = NSLocalizedString("%@ ago", comment: "x days ago")
let dateFormatter: DateFormatter = {
let formatter = DateFormatter()
formatter.locale = Locale.autoupdatingCurrent
formatter.dateStyle = .medium
formatter.doesRelativeDateFormatting = true
return formatter
}()
if year > 0 {
// sample output: "Jan 23, 2014"
return dateFormatter.string(from: date)
} else if month > 0 {
let formatter = DateComponentsFormatter()
formatter.unitsStyle = .brief // sample output: "1mth"
formatter.allowedUnits = .month
guard let timePhrase = formatter.string(from: difference) else {
return ""
}
return String(format: timeAgo, timePhrase)
} else if week > 0 {
let formatter = DateComponentsFormatter()
formatter.unitsStyle = .brief; // sample output: "2wks"
formatter.allowedUnits = .weekOfMonth
guard let timePhrase = formatter.string(from: difference) else {
return ""
}
return String(format: timeAgo, timePhrase)
} else if day > 1 {
let formatter = DateComponentsFormatter()
formatter.unitsStyle = .abbreviated; // sample output: "3d"
formatter.allowedUnits = .day
guard let timePhrase = formatter.string(from: difference) else {
return ""
}
return String(format: timeAgo, timePhrase)
} else {
// sample output: "Yesterday" or "Today"
return dateFormatter.string(from: date)
}
}
func dateEndOfToday() -> Date? {
let calendar = Calendar.autoupdatingCurrent
let now = Date()
let todayStart = calendar.startOfDay(for: now)
var components = DateComponents()
components.day = 1
let todayEnd = calendar.date(byAdding: components, to: todayStart)
return todayEnd
}
Run Code Online (Sandbox Code Playgroud)
请记住重复使用格式化程序以避免任何性能损失!提示:DateFormatter和DateComponentsFormatter上的扩展是好主意.
这个答案的灵感来自于GitHub上的DateTools.
Sau*_*dav 10
Swift更新,感谢DavidRönnqvist的客观答案,它将适用于过去的日期.
func relativeDateStringForDate(date : NSDate) -> NSString {
let todayDate = NSDate()
let units: NSCalendarUnit = [.Hour, .Day, .Month, .Year, .WeekOfYear]
let components = NSCalendar.currentCalendar().components(units, fromDate: date , toDate: todayDate, options: NSCalendarOptions.MatchFirst )
let year = components.year
let month = components.month
let day = components.day
let hour = components.hour
let weeks = components.weekOfYear
// if `date` is before "now" (i.e. in the past) then the components will be positive
if components.year > 0 {
return NSString.init(format: "%d years ago", year);
} else if components.month > 0 {
return NSString.init(format: "%d months ago", month);
} else if components.weekOfYear > 0 {
return NSString.init(format: "%d weeks ago", weeks);
} else if (components.day > 0) {
if components.day > 1 {
return NSString.init(format: "%d days ago", day);
} else {
return "Yesterday";
}
} else {
return NSString.init(format: "%d hours ago", hour);
}
}
Run Code Online (Sandbox Code Playgroud)
FOR:SWIFT 3
这是一个Swift 3版本,对于过去的日期,它处理返回的String中的所有单位和单数或复数.
示例使用:
let oneWeekAgo = Calendar.current.date(byAdding: .weekOfYear, value: -1, to: Date())!
print(relativePast(for: oneWeekAgo)) // output: "1 week ago"
Run Code Online (Sandbox Code Playgroud)
我的基础是Saurabh Yadav的即兴演奏.谢谢.
func relativePast(for date : Date) -> String {
let units = Set<Calendar.Component>([.year, .month, .day, .hour, .minute, .second, .weekOfYear])
let components = Calendar.current.dateComponents(units, from: date, to: Date())
if components.year! > 0 {
return "\(components.year!) " + (components.year! > 1 ? "years ago" : "year ago")
} else if components.month! > 0 {
return "\(components.month!) " + (components.month! > 1 ? "months ago" : "month ago")
} else if components.weekOfYear! > 0 {
return "\(components.weekOfYear!) " + (components.weekOfYear! > 1 ? "weeks ago" : "week ago")
} else if (components.day! > 0) {
return (components.day! > 1 ? "\(components.day!) days ago" : "Yesterday")
} else if components.hour! > 0 {
return "\(components.hour!) " + (components.hour! > 1 ? "hours ago" : "hour ago")
} else if components.minute! > 0 {
return "\(components.minute!) " + (components.minute! > 1 ? "minutes ago" : "minute ago")
} else {
return "\(components.second!) " + (components.second! > 1 ? "seconds ago" : "second ago")
}
}
Run Code Online (Sandbox Code Playgroud)
为了避免Budidino提到大卫答案的24小时问题,我将其修改为如下所示 -
- (NSString *)relativeDateStringForDate:(NSDate *)date
{
NSCalendarUnit units = NSDayCalendarUnit | NSWeekOfYearCalendarUnit |
NSMonthCalendarUnit | NSYearCalendarUnit ;
NSCalendar *cal = [NSCalendar currentCalendar];
NSDateComponents *components1 = [cal components:(NSCalendarUnitEra|NSCalendarUnitYear|NSCalendarUnitMonth|NSCalendarUnitDay) fromDate:[NSDate date]];
NSDate *today = [cal dateFromComponents:components1];
components1 = [cal components:(NSCalendarUnitEra|NSCalendarUnitYear|NSCalendarUnitMonth|NSCalendarUnitDay) fromDate:date];
NSDate *thatdate = [cal dateFromComponents:components1];
// if `date` is before "now" (i.e. in the past) then the components will be positive
NSDateComponents *components = [[NSCalendar currentCalendar] components:units
fromDate:thatdate
toDate:today
options:0];
if (components.year > 0) {
return [NSString stringWithFormat:@"%ld years ago", (long)components.year];
} else if (components.month > 0) {
return [NSString stringWithFormat:@"%ld months ago", (long)components.month];
} else if (components.weekOfYear > 0) {
return [NSString stringWithFormat:@"%ld weeks ago", (long)components.weekOfYear];
} else if (components.day > 0) {
if (components.day > 1) {
return [NSString stringWithFormat:@"%ld days ago", (long)components.day];
} else {
return @"Yesterday";
}
} else {
return @"Today";
}
}
Run Code Online (Sandbox Code Playgroud)
基本上,它创建了2个新的日期,没有包含时间片.然后比较是为了"天"差异.
归档时间: |
|
查看次数: |
29362 次 |
最近记录: |