Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
//
// NSDate+FAExtension.m
// frank-ios
//
// Created by Ринат Муртазин on 20/10/15.
// Copyright © 2015 Frank. All rights reserved.
//
#import "NSDate+FAExtension.h"
#import "FALocalization"
#define SECONDS_IN_MINUTE 60
#define MINUTES_IN_HOUR 60
#define CALENDAR [NSCalendar currentCalendar]
#define UNITS NSCalendarUnitYear | NSCalendarUnitMonth | NSCalendarUnitWeekday | NSCalendarUnitDay | NSCalendarUnitHour | NSCalendarUnitMinute
@implementation NSDate (FAExtension)
- (NSString *)fa_momentDescription
{
return [self fa_momentDescriptionShort:NO
relativeDate:[NSDate date]];
}
- (NSString *)fa_momentDescriptionShort
{
return [self fa_momentDescriptionShort:YES
relativeDate:[NSDate date]];
}
- (NSString *)fa_momentDescriptionRelativeDate:(NSDate *)date
{
return [self fa_momentDescriptionShort:NO
relativeDate:date];
}
- (NSString *)fa_momentDescriptionShort:(BOOL)isShort
relativeDate:(NSDate *)relativeDate
{
// minutes
NSInteger minutesDelta = (relativeDate.timeIntervalSince1970 - self.timeIntervalSince1970) / SECONDS_IN_MINUTE;
minutesDelta = MAX(minutesDelta, 1);
if(minutesDelta < 60)
{
if(isShort)
{
return [NSString stringWithFormat:@"%dm", (int)minutesDelta];
}
else
{
return [NSString stringWithFormat:@"%d %@ ago", (int)minutesDelta, minutesDelta == 1 ? @"minute" : @"minutes"];
}
}
// hours
NSInteger hoursDelta = minutesDelta / MINUTES_IN_HOUR;
hoursDelta = MAX(hoursDelta, 1);
if(hoursDelta < 24)
{
if(isShort)
{
return [NSString stringWithFormat:@"%dh", (int)hoursDelta];
}
else
{
return [NSString stringWithFormat:@"%d %@ ago", (int)hoursDelta, hoursDelta == 1 ? @"hour" : @"hours"];
}
}
// yesterday
NSDateComponents *relativeComponents = [CALENDAR components:UNITS
fromDate:relativeDate];
NSDateComponents *selfComponents = [CALENDAR components:UNITS
fromDate:self];
NSString *yesterday = [self fa_yesterdayStringBySelfComponents:selfComponents
andRelativeComponents:relativeComponents
isShort:isShort];
if(yesterday)
{
return yesterday;
}
// week days
NSString *weekString = [self fa_weekDateStringBySelfComponents:selfComponents
andRelativeComponents:relativeComponents
isShort:isShort];
if(weekString)
{
return weekString;
}
// full date
return [self fa_fullDateStringBySelfComponents:selfComponents
andRelativeComponents:relativeComponents
isShort:isShort];
}
- (NSString *)fa_yesterdayStringBySelfComponents:(NSDateComponents *)selfComponents
andRelativeComponents:(NSDateComponents *)relativeComponents
isShort:(BOOL)isShort
{
BOOL isYesterday = NO;
NSDateComponents *tempComponents = [selfComponents copy];
tempComponents.day += 1;
tempComponents = [CALENDAR components:UNITS
fromDate:[CALENDAR dateFromComponents:tempComponents]];
if(tempComponents.year == relativeComponents.year
&& tempComponents.month == relativeComponents.month
&& tempComponents.day == relativeComponents.day)
{
isYesterday = YES;
}
if(isYesterday)
{
if(isShort)
{
return [NSString stringWithFormat:@"Yesterday, %@", [self fa_timeStringByDateComponents:selfComponents]];
}
else
{
return [NSString stringWithFormat:@"Yesterday at %@", [self fa_timeStringByDateComponents:selfComponents]];
}
}
return nil;
}
- (NSString *)fa_weekDateStringBySelfComponents:(NSDateComponents *)selfComponents
andRelativeComponents:(NSDateComponents *)relativeComponents
isShort:(BOOL)isShort
{
NSDateComponents *tempComponents = [selfComponents copy];
tempComponents.day += 7;
tempComponents = [CALENDAR components:UNITS
fromDate:[CALENDAR dateFromComponents:tempComponents]];
BOOL isWeek = NO;
if(tempComponents.year == relativeComponents.year
&& tempComponents.month == relativeComponents.month
&& tempComponents.day > relativeComponents.day)
{
isWeek = YES;
}
if(tempComponents.year > relativeComponents.year)
{
isWeek = YES;
}
else if(tempComponents.year == relativeComponents.year
&& tempComponents.month > relativeComponents.month)
{
isWeek = YES;
}
if(isWeek)
{
NSString *weekDay = @"weekday";
NSInteger weekDayIndex = selfComponents.weekday - 1;
NSArray *weekdays = [self fa_weakdaysShort:isShort];
if(weekDayIndex >= 0
&& weekDayIndex < [weekdays count])
{
weekDay = weekdays[weekDayIndex];
}
if(isShort)
{
return [NSString stringWithFormat:@"%@, %@", weekDay, [self fa_timeStringByDateComponents:selfComponents]];
}
else
{
return [NSString stringWithFormat:@"%@ at %@", weekDay, [self fa_timeStringByDateComponents:selfComponents]];
}
}
else
{
return nil;
}
}
- (NSString *)fa_fullDateStringBySelfComponents:(NSDateComponents *)selfComponents
andRelativeComponents:(NSDateComponents *)relativeComponents
isShort:(BOOL)isShort
{
NSString *time = [self fa_timeStringByDateComponents:selfComponents];
BOOL needIncludeYear = selfComponents.year != relativeComponents.year;
NSString *month = @"month";
NSInteger momthIndex = selfComponents.month - 1;
NSArray *months = [self fa_monthsShort:isShort];
if(momthIndex >= 0
&& momthIndex < [months count])
{
month = months[momthIndex];
}
if (isShort)
{
if(needIncludeYear)
{
NSString *year = [NSString stringWithFormat:@"%d", (int)selfComponents.year];
return [NSString stringWithFormat:@"%@ %@, %@", month, [self fa_twoSymbylsByValue:(int)selfComponents.day], year];
}
else
{
return [NSString stringWithFormat:@"%@ %@", month, [self fa_twoSymbylsByValue:(int)selfComponents.day]];
}
}
else
{
month = [NSString stringWithFormat:@"%@ %d", month, (int)selfComponents.day];
NSString *year = @"";
if(needIncludeYear)
{
year = [NSString stringWithFormat:@", %d", (int)selfComponents.year];
}
return [NSString stringWithFormat:@"%@%@ at %@", month, year, time];
}
}
- (NSArray *)fa_monthsShort:(BOOL)isShort
{
static NSArray *months = nil;
static NSArray *monthsShort = nil;
if(months == nil
&& isShort == NO)
{
months = [FALocalization months];
}
if(monthsShort == nil
&& isShort)
{
monthsShort = [FALocalization monthsShort];
}
return isShort ? monthsShort : months;
}
- (NSArray *)fa_weakdaysShort:(BOOL)isShort
{
static NSArray *weekdays = nil;
static NSArray *weekdaysShort = nil;
if(weekdays == nil
&& isShort == NO)
{
weekdays = [FALocalization weekdays];
}
if(weekdaysShort == nil
&& isShort)
{
weekdaysShort = FALocalization weekdaysShort];
}
return isShort ? weekdaysShort : weekdays;
}
- (NSString *)fa_timeStringByDateComponents:(NSDateComponents *)dc
{
NSString *suffix = @"am";
if(dc.hour > 11)
{
suffix = @"pm";
if(dc.hour > 12)
{
dc.hour -= 12;
}
}
else if(dc.hour == 0)
{
dc.hour = 12;
}
NSString *time = [NSString stringWithFormat:@"%d:%@", (int)dc.hour, [self fa_twoSymbylsByValue:(int)dc.minute]];
return [NSString stringWithFormat:@"%@%@", time, suffix];
}
- (NSString *)fa_twoSymbylsByValue:(int)value
{
if(value < 10)
{
return [NSString stringWithFormat:@"0%d", value];
}
else
{
return [NSString stringWithFormat:@"%d", value];
}
}
- (BOOL)fa_isYesterdayRelativeDate:(NSDate *)relative
{
NSDateComponents *selfComponents = [CALENDAR components:UNITS fromDate:self];
NSDateComponents *relativeComponents = [CALENDAR components:UNITS fromDate:relative];
if(selfComponents.day == relativeComponents.day - 1
&& selfComponents.month == relativeComponents.month
&& selfComponents.year == relativeComponents.year)
{
return YES;
}
if((selfComponents.month == relativeComponents.month - 1
|| selfComponents.year == relativeComponents.year - 1)
&& relativeComponents.day == 1)
{
NSDateComponents *tempComponents = [selfComponents copy];
tempComponents.day += 1;
tempComponents = [CALENDAR components:UNITS
fromDate:[CALENDAR dateFromComponents:tempComponents]];
if(tempComponents.year == relativeComponents.year
&& tempComponents.month == relativeComponents.month
&& tempComponents.day == relativeComponents.day)
{
return YES;
}
}
return NO;
}
@end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.