NSDate

作者: 二斤寂寞 | 来源:发表于2020-02-14 15:31 被阅读0次

    记录几种常用的日期格式转化

    Demo
    转化主要针对以下两个方法:
    //date转字符串
    - (NSString *)stringFromDate:(NSDate *)date;
    
    //字符串转date
    - (nullable NSDate *)dateFromString:(NSString *)string;
    
    1、获取当前时间,并转化成yyyy-MM-dd HH:mm:ss 格式
    NSDate *date = [NSDate date];
    NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
    //24小时制:yyyy-MM-dd HH:mm:ss  12小时制:yyyy-MM-dd hh:mm:ss
    dateFormatter.dateFormat = @"yyyy-MM-dd HH:mm:ss";
    NSString *nowDateString = [dateFormatter stringFromDate:date];
    
    2、获取当前时间的时间戳
    NSDate *date = [NSDate date];
    //单位:秒
    NSTimeInterval interval = [date timeIntervalSince1970];
    
    3、时间戳转时间字符串
    NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
    //24小时制:yyyy-MM-dd HH:mm:ss  12小时制:yyyy-MM-dd hh:mm:ss
    dateFormatter.dateFormat = @"yyyy-MM-dd HH:mm:ss";
    NSTimeInterval interval = [@"1528094475" longLongValue];
    NSDate *date = [NSDate dateWithTimeIntervalSince1970:interval];
    NSString *dateString = [dateFormatter stringFromDate:date];
    
    4、时间字符串转时间戳
    NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
    //24小时制:yyyy-MM-dd HH:mm:ss  12小时制:yyyy-MM-dd hh:mm:ss
    dateFormatter.dateFormat = @"yyyy-MM-dd HH:mm:ss";
    NSDate *date = [dateFormatter dateFromString:@"2018-06-04 14:41:15"];
    NSTimeInterval interval = [date timeIntervalSince1970];
    
    5、某个时间点与当前时间的间隔(单位:秒)
    //时间格式先转换,再比较
    NSDate *date = [dateFormatter dateFromString:@"2018-06-04 14:41:15"];
    NSTimeInterval interval = [date timeIntervalSince1970];
    
    //如果是时间戳就直接拿时间戳进行下面的转换比较
    //NSTimeInterval interval = [@"1528094475" longLongValue];
    NSDate *date = [NSDate dateWithTimeIntervalSince1970:interval];
    NSTimeInterval timeInterval = [date timeIntervalSinceNow];//值=某个时间-当前时间
    
    //也可以用下面的方法进行比较(改方法可以比较任意两个时间点的间隔)
    //NSDate * currentDate = [NSDate date];
    //NSTimeInterval interval = [currentDate timeIntervalSinceDate:date];//值= currentDate-date
    
    6、获取将来的某个时间
    NSTimeInterval interval = 24 * 60 * 60;
    NSDate *tomorrow = [NSDate dateWithTimeIntervalSinceNow:interval];
    
    7、根据某个时间来创建时间
    NSTimeInterval interval = 24 * 60 * 60;//正值表示将来,负值表示过去时间
    NSDate *date = [NSDate date];
    NSDate *tomorrow = [date dateByAddingTimeInterval:interval];
    
    8、日期比较
    NSDate * currentDate = [NSDate date];
    NSTimeInterval interval = [@"1528094475" longLongValue];
    NSDate *date = [NSDate dateWithTimeIntervalSince1970:interval];
    
    //方法一:
    //比较时间是否相等
    BOOL sameDate = [currentDate isEqualToDate:date];
    //获取两个时间中较早的时间
    NSDate *earlierDate = [currentDate earlierDate: date];
    //获取两个时间中较晚的时间
    NSDate *laterDate = [currentDate laterDate: date];
    
    //方法二:
    NSComparisonResult result = [currentDate compare:date];
        if (result == NSOrderedAscending) {//升序
            //currentDate < date
        }else if (result == NSOrderedDescending) {//降序
            //currentDate > date
        }else {//相等
            //currentDate == date
        }
    
    //方法三:(用日历进行比较)
        NSCalendar *calendar = nil;
        if ([UIDevice currentDevice].systemVersion.doubleValue >= 8.0) {
            calendar = [NSCalendar calendarWithIdentifier:NSCalendarIdentifierGregorian];
        } else {
            calendar = [NSCalendar currentCalendar];
        }
        
    //    NSCalendar *calendar = nil;
    //    if ([NSCalendar respondsToSelector:@selector(calendarWithIdentifier:)]) {
    //        calendar = [NSCalendar calendarWithIdentifier:NSCalendarIdentifierGregorian];
    //    } else {
    //        calendar = [NSCalendar currentCalendar];
    //    }
    
    NSCalendarUnit unit = NSCalendarUnitYear | NSCalendarUnitMonth | NSCalendarUnitDay | NSCalendarUnitHour | NSCalendarUnitMinute | NSCalendarUnitSecond;
        // 4.获取了时间元素
        NSDateComponents *components = [calendar components:unit fromDate:date toDate: currentDate options:0];
        NSLog(@"相差:%ld年%ld月%ld日%ld小时%ld分钟%ld秒钟", (long)components.year, (long)components.month, (long)components.day, (long)components.hour, (long)components.minute, (long)components.second);
    
    

    NSCalendar的一些用法

    1、获取当前时间
    NSCalendar *calendar = nil;
    if ([NSCalendar respondsToSelector:@selector(calendarWithIdentifier:)]) {
            calendar = [NSCalendar calendarWithIdentifier:NSCalendarIdentifierGregorian];
        } else {
            calendar = [NSCalendar currentCalendar];
        }
    NSDateComponents  *components  =  [calendar components:NSCalendarUnitYear | NSCalendarUnitMonth | NSCalendarUnitDay | NSCalendarUnitHour | NSCalendarUnitMinute | NSCalendarUnitSecond fromDate:[NSDate date]];
        NSLog(@"%ld-%ld-%ld %ld:%ld:%ld" ,(long)components.year,(long)components.month,(long)components.day,(long)components.hour,(long)components.minute,(long)components.second);
    //现在处于今年的几月
    NSInteger month = [calendar ordinalityOfUnit:NSCalendarUnitMonth inUnit:NSCalendarUnitYear forDate:[NSDate date]];
        NSLog(@"今天是今年的%ld月",(long)month);
    //当前日期是今年的第几周
    NSInteger week = [calendar ordinalityOfUnit:NSCalendarUnitWeekday inUnit:NSCalendarUnitYear forDate:[NSDate date]];
    NSLog(@"今天是今年的第%ld周",(long)week);
    //当前日期是今年的第几天
    NSInteger day = [calendar ordinalityOfUnit:NSCalendarUnitDay inUnit:NSCalendarUnitYear forDate:[NSDate date]];
    NSLog(@"今天是今年的第%ld天",(long)day);
    
    2、获取过去一周时间
    NSCalendar *calendar = nil;
    if ([NSCalendar respondsToSelector:@selector(calendarWithIdentifier:)]) {
            calendar = [NSCalendar calendarWithIdentifier:NSCalendarIdentifierGregorian];
        } else {
            calendar = [NSCalendar currentCalendar];
        }
    NSMutableArray *dates = [NSMutableArray array];
    for (int i=-6; i < 1; i++) {
            NSDateComponents  *components  =  [[NSDateComponents alloc] init];
            components.year = 0;
            components.month = 0;
            components.day = i;
            NSDate *currentDate = [NSDate date];
            NSDate *date = [calendar dateByAddingComponents:components toDate:currentDate options:NSCalendarMatchStrictly];
            NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
            formatter.dateFormat = @"MM-dd";
            NSString *dateString = [formatter stringFromDate:date];
            [dates addObject:dateString];
        }
        NSLog(@"%@,%@,%@,%@,%@,%@,%@",dates[0],dates[1],dates[2],dates[3],dates[4],dates[5],dates[6]);
    
    3、获取某个时间点对应的月份有几天
    - (NSInteger)getDaysByDate:(NSDate *)date {
        NSCalendar *calendar = nil;
        if ([NSCalendar respondsToSelector:@selector(calendarWithIdentifier:)]) {
            calendar = [NSCalendar calendarWithIdentifier:NSCalendarIdentifierGregorian];
        } else {
            calendar = [NSCalendar currentCalendar];
        }
        NSRange range = [calendar rangeOfUnit:NSCalendarUnitDay inUnit:NSCalendarUnitMonth forDate:date];
        NSUInteger days = range.length;
        return days;
    }
    
    4、获取某个时间点对应的月份的某一天的时间
    - (NSDate *)getDateByDate:(NSDate *)date day:(int)day {
         NSCalendar *calendar = nil;
        if ([NSCalendar respondsToSelector:@selector(calendarWithIdentifier:)]) {
            calendar = [NSCalendar calendarWithIdentifier:NSCalendarIdentifierGregorian];
        } else {
            calendar = [NSCalendar currentCalendar];
        }
        NSCalendarUnit unit = NSCalendarUnitYear | NSCalendarUnitMonth | NSCalendarUnitDay | NSCalendarUnitHour | NSCalendarUnitMinute | NSCalendarUnitSecond;
        NSDateComponents *components = [calendar components:unit fromDate:date];
        components.day = day;
        return [calendar dateFromComponents:components];
    }
    
    5、获取某天对应星期几
    - (NSInteger)getTheCorrespondingWeekByDate:(NSDate*)date {
        NSCalendar *calendar = nil;
        if ([NSCalendar respondsToSelector:@selector(calendarWithIdentifier:)]) {
            calendar = [NSCalendar calendarWithIdentifier:NSCalendarIdentifierGregorian];
        } else {
            calendar = [NSCalendar currentCalendar];
        }
        NSDateComponents *components = [calendar components:NSCalendarUnitYear|NSCalendarUnitMonth|NSCalendarUnitDay|NSCalendarUnitHour|NSCalendarUnitMinute|NSCalendarUnitSecond|NSCalendarUnitWeekday fromDate:date];
        NSInteger weekday = [components weekday];
        NSLog(@"weekday = %ld",(long)weekday);
        weekday--;//美国从周日开始一周,我们从周一开始,所以我们这得调整
        NSLog(@"weekday = %ld",(long)weekday);
        if (weekday == 7) {
            return 0;
        }
        return weekday;
    }
    
    6、传入时间戳同当前时间比对
    - (NSString *)timeAgoWithTimeString:(NSString *)string {
        NSDate *date = [NSDate date];
        NSTimeInterval timeInterval = [date timeIntervalSince1970];
        NSDate *compareDate = [NSDate dateWithTimeIntervalSince1970:[string longLongValue]];
        NSTimeInterval compareImterval = [compareDate timeIntervalSince1970];
        int difference = timeInterval - compareImterval;
        int days = difference/(60*60*24);
        int hours = (difference%(60*60*24))/(60*60);
        int minites = (difference%(60*60*24))%(60*60)/60;
        int seconds = (difference%(60*60*24))%(60*60)%60;
        if (days != 0) {
            return [NSString stringWithFormat:@"%d天前",days];
        }else if (hours != 0) {
            return [NSString stringWithFormat:@"%d小时前",hours];
        }else if (minites != 0) {
            return [NSString stringWithFormat:@"%d分钟前",minites];
        }else if (seconds != 0) {
            return @"刚刚";
        }else {
            return @"时间格式有误";
        }
    }
    

    最后送上日期分类文件

    //
    //  NSDate+Tools.h
    //  ZLDate
    //
    //  Created by wangzelong on 2020/2/14.
    //
    
    #ifndef DateToolsLocalizedStrings
    #define DateToolsLocalizedStrings(key) \
    NSLocalizedStringFromTableInBundle(key, @"DateTools", [NSBundle bundleWithPath:[[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:@"DateTools.bundle"]], nil)
    #endif
    
    #import <Foundation/Foundation.h>
    
    @interface NSDate (Tools)
    
    #pragma mark - Time Ago
    + (NSString*)timeAgoSinceDate:(NSDate*)date;
    + (NSString*)shortTimeAgoSinceDate:(NSDate*)date;
    - (NSString*)timeAgoSinceNow;
    - (NSString *)shortTimeAgoSinceNow;
    - (NSString *)timeAgoSinceDate:(NSDate *)date;
    - (NSString *)timeAgoSinceDate:(NSDate *)date numericDates:(BOOL)useNumericDates;
    - (NSString *)timeAgoSinceDate:(NSDate *)date numericDates:(BOOL)useNumericDates numericTimes:(BOOL)useNumericTimes;
    - (NSString *)shortTimeAgoSinceDate:(NSDate *)date;
    
    
    #pragma mark - Date Components Without Calendar
    - (NSInteger)era;
    - (NSInteger)year;
    - (NSInteger)month;
    - (NSInteger)day;
    - (NSInteger)hour;
    - (NSInteger)minute;
    - (NSInteger)second;
    - (NSInteger)weekday;
    - (NSInteger)weekdayOrdinal;
    - (NSInteger)quarter;
    - (NSInteger)weekOfMonth;
    - (NSInteger)weekOfYear;
    - (NSInteger)yearForWeekOfYear;
    - (NSInteger)daysInMonth;
    - (NSInteger)dayOfYear;
    -(NSInteger)daysInYear;
    -(BOOL)isInLeapYear;
    - (BOOL)isToday;
    - (BOOL)isTomorrow;
    - (BOOL)isTheDayAfterTomorrow;
    -(BOOL)isYesterday;
    - (BOOL)isWeekend;
    - (BOOL)isSameDayWithDate:(NSDate *)date;
    
    #pragma mark - Date Components With Calendar
    
    
    - (NSInteger)eraWithCalendar:(NSCalendar *)calendar;
    - (NSInteger)yearWithCalendar:(NSCalendar *)calendar;
    - (NSInteger)monthWithCalendar:(NSCalendar *)calendar;
    - (NSInteger)dayWithCalendar:(NSCalendar *)calendar;
    - (NSInteger)hourWithCalendar:(NSCalendar *)calendar;
    - (NSInteger)minuteWithCalendar:(NSCalendar *)calendar;
    - (NSInteger)secondWithCalendar:(NSCalendar *)calendar;
    - (NSInteger)weekdayWithCalendar:(NSCalendar *)calendar;
    - (NSInteger)weekdayOrdinalWithCalendar:(NSCalendar *)calendar;
    - (NSInteger)quarterWithCalendar:(NSCalendar *)calendar;
    - (NSInteger)weekOfMonthWithCalendar:(NSCalendar *)calendar;
    - (NSInteger)weekOfYearWithCalendar:(NSCalendar *)calendar;
    - (NSInteger)yearForWeekOfYearWithCalendar:(NSCalendar *)calendar;
    
    
    #pragma mark - Date Creating
    + (NSDate *)dateWithYear:(NSInteger)year month:(NSInteger)month day:(NSInteger)day;
    + (NSDate *)dateWithYear:(NSInteger)year month:(NSInteger)month day:(NSInteger)day hour:(NSInteger)hour minute:(NSInteger)minute second:(NSInteger)second;
    + (NSDate *)dateWithString:(NSString *)dateString formatString:(NSString *)formatString;
    + (NSDate *)dateWithString:(NSString *)dateString formatString:(NSString *)formatString timeZone:(NSTimeZone *)timeZone;
    
    
    #pragma mark - Date Editing
    #pragma mark Date By Adding
    - (NSDate *)dateByAddingYears:(NSInteger)years;
    - (NSDate *)dateByAddingMonths:(NSInteger)months;
    - (NSDate *)dateByAddingWeeks:(NSInteger)weeks;
    - (NSDate *)dateByAddingDays:(NSInteger)days;
    - (NSDate *)dateByAddingHours:(NSInteger)hours;
    - (NSDate *)dateByAddingMinutes:(NSInteger)minutes;
    - (NSDate *)dateByAddingSeconds:(NSInteger)seconds;
    #pragma mark Date By Subtracting
    - (NSDate *)dateBySubtractingYears:(NSInteger)years;
    - (NSDate *)dateBySubtractingMonths:(NSInteger)months;
    - (NSDate *)dateBySubtractingWeeks:(NSInteger)weeks;
    - (NSDate *)dateBySubtractingDays:(NSInteger)days;
    - (NSDate *)dateBySubtractingHours:(NSInteger)hours;
    - (NSDate *)dateBySubtractingMinutes:(NSInteger)minutes;
    - (NSDate *)dateBySubtractingSeconds:(NSInteger)seconds;
    
    #pragma mark - Date Comparison
    #pragma mark Time From
    -(NSInteger)yearsFrom:(NSDate *)date;
    -(NSInteger)monthsFrom:(NSDate *)date;
    -(NSInteger)weeksFrom:(NSDate *)date;
    -(NSInteger)daysFrom:(NSDate *)date;
    -(double)hoursFrom:(NSDate *)date;
    -(double)minutesFrom:(NSDate *)date;
    -(double)secondsFrom:(NSDate *)date;
    #pragma mark Time From With Calendar
    -(NSInteger)yearsFrom:(NSDate *)date calendar:(NSCalendar *)calendar;
    -(NSInteger)monthsFrom:(NSDate *)date calendar:(NSCalendar *)calendar;
    -(NSInteger)weeksFrom:(NSDate *)date calendar:(NSCalendar *)calendar;
    -(NSInteger)daysFrom:(NSDate *)date calendar:(NSCalendar *)calendar;
    
    #pragma mark Time Until
    -(NSInteger)yearsUntil;
    -(NSInteger)monthsUntil;
    -(NSInteger)weeksUntil;
    -(NSInteger)daysUntil;
    -(double)hoursUntil;
    -(double)minutesUntil;
    -(double)secondsUntil;
    #pragma mark Time Ago
    -(NSInteger)yearsAgo;
    -(NSInteger)monthsAgo;
    -(NSInteger)weeksAgo;
    -(NSInteger)daysAgo;
    -(double)hoursAgo;
    -(double)minutesAgo;
    -(double)secondsAgo;
    #pragma mark Earlier Than
    -(NSInteger)yearsEarlierThan:(NSDate *)date;
    -(NSInteger)monthsEarlierThan:(NSDate *)date;
    -(NSInteger)weeksEarlierThan:(NSDate *)date;
    -(NSInteger)daysEarlierThan:(NSDate *)date;
    -(double)hoursEarlierThan:(NSDate *)date;
    -(double)minutesEarlierThan:(NSDate *)date;
    -(double)secondsEarlierThan:(NSDate *)date;
    #pragma mark Later Than
    -(NSInteger)yearsLaterThan:(NSDate *)date;
    -(NSInteger)monthsLaterThan:(NSDate *)date;
    -(NSInteger)weeksLaterThan:(NSDate *)date;
    -(NSInteger)daysLaterThan:(NSDate *)date;
    -(double)hoursLaterThan:(NSDate *)date;
    -(double)minutesLaterThan:(NSDate *)date;
    -(double)secondsLaterThan:(NSDate *)date;
    #pragma mark Comparators
    -(BOOL)isEarlierThan:(NSDate *)date;
    -(BOOL)isLaterThan:(NSDate *)date;
    -(BOOL)isEarlierThanOrEqualTo:(NSDate *)date;
    -(BOOL)isLaterThanOrEqualTo:(NSDate *)date;
    
    #pragma mark - Formatted Dates
    #pragma mark Formatted With Style
    -(NSString *)formattedDateWithStyle:(NSDateFormatterStyle)style;
    -(NSString *)formattedDateWithStyle:(NSDateFormatterStyle)style timeZone:(NSTimeZone *)timeZone;
    -(NSString *)formattedDateWithStyle:(NSDateFormatterStyle)style locale:(NSLocale *)locale;
    -(NSString *)formattedDateWithStyle:(NSDateFormatterStyle)style timeZone:(NSTimeZone *)timeZone locale:(NSLocale *)locale;
    #pragma mark Formatted With Format
    -(NSString *)formattedDateWithFormat:(NSString *)format;
    -(NSString *)formattedDateWithFormat:(NSString *)format timeZone:(NSTimeZone *)timeZone;
    -(NSString *)formattedDateWithFormat:(NSString *)format locale:(NSLocale *)locale;
    -(NSString *)formattedDateWithFormat:(NSString *)format timeZone:(NSTimeZone *)timeZone locale:(NSLocale *)locale;
    
    #pragma mark - Helpers
    +(NSString *)defaultCalendarIdentifier;
    + (void)setDefaultCalendarIdentifier:(NSString *)identifier;
    @end
    
    
    //
    //  NSDate+Tools.m
    //  ZLDate
    //
    //  Created by wangzelong on 2020/2/14.
    //
    
    #import "NSDate+Tools.h"
    
    typedef NS_ENUM(NSUInteger, DTDateComponent){
        DTDateComponentEra,
        DTDateComponentYear,
        DTDateComponentMonth,
        DTDateComponentDay,
        DTDateComponentHour,
        DTDateComponentMinute,
        DTDateComponentSecond,
        DTDateComponentWeekday,
        DTDateComponentWeekdayOrdinal,
        DTDateComponentQuarter,
        DTDateComponentWeekOfMonth,
        DTDateComponentWeekOfYear,
        DTDateComponentYearForWeekOfYear,
        DTDateComponentDayOfYear
    };
    
    static const unsigned int allCalendarUnitFlags = NSCalendarUnitYear | NSCalendarUnitQuarter | NSCalendarUnitMonth | NSCalendarUnitWeekOfYear | NSCalendarUnitWeekOfMonth | NSCalendarUnitDay | NSCalendarUnitHour | NSCalendarUnitMinute | NSCalendarUnitSecond | NSCalendarUnitEra | NSCalendarUnitWeekday | NSCalendarUnitWeekdayOrdinal | NSCalendarUnitWeekOfYear;
    
    static NSString *defaultCalendarIdentifier = nil;
    static NSCalendar *implicitCalendar = nil;
    
    //static const long long SECONDS_IN_YEAR = 31556900;
    //static const NSInteger SECONDS_IN_MONTH_28 = 2419200;
    //static const NSInteger SECONDS_IN_MONTH_29 = 2505600;
    //static const NSInteger SECONDS_IN_MONTH_30 = 2592000;
    //static const NSInteger SECONDS_IN_MONTH_31 = 2678400;
    //static const NSInteger SECONDS_IN_WEEK = 604800;
    //static const NSInteger SECONDS_IN_DAY = 86400;
    static const NSInteger SECONDS_IN_HOUR = 3600;
    static const NSInteger SECONDS_IN_MINUTE = 60;
    //static const NSInteger MILLISECONDS_IN_DAY = 86400000;
    
    @implementation NSDate (Tools)
    
    + (void)load {
        [self setDefaultCalendarIdentifier:NSCalendarIdentifierGregorian];
    }
    
    #pragma mark - Time Ago
    
    
    /**
     *  Takes in a date and returns a string with the most convenient unit of time representing
     *  how far in the past that date is from now.
     *
     *  @param date - Date to be measured from now
     *
     *  @return NSString - Formatted return string
     */
    + (NSString*)timeAgoSinceDate:(NSDate*)date{
        return [date timeAgoSinceDate:[NSDate date]];
    }
    
    /**
     *  Takes in a date and returns a shortened string with the most convenient unit of time representing
     *  how far in the past that date is from now.
     *
     *  @param date - Date to be measured from now
     *
     *  @return NSString - Formatted return string
     */
    + (NSString*)shortTimeAgoSinceDate:(NSDate*)date{
        return [date shortTimeAgoSinceDate:[NSDate date]];
    }
    
    /**
     *  Returns a string with the most convenient unit of time representing
     *  how far in the past that date is from now.
     *
     *  @return NSString - Formatted return string
     */
    - (NSString*)timeAgoSinceNow{
        return [self timeAgoSinceDate:[NSDate date]];
    }
    
    /**
     *  Returns a shortened string with the most convenient unit of time representing
     *  how far in the past that date is from now.
     *
     *  @return NSString - Formatted return string
     */
    - (NSString *)shortTimeAgoSinceNow{
        return [self shortTimeAgoSinceDate:[NSDate date]];
    }
    
    - (NSString *)timeAgoSinceDate:(NSDate *)date{
        return [self timeAgoSinceDate:date numericDates:NO];
    }
    
    - (NSString *)timeAgoSinceDate:(NSDate *)date numericDates:(BOOL)useNumericDates{
        return [self timeAgoSinceDate:date numericDates:useNumericDates numericTimes:NO];
    }
    
    - (NSString *)timeAgoSinceDate:(NSDate *)date numericDates:(BOOL)useNumericDates numericTimes:(BOOL)useNumericTimes{
        
        NSCalendar *calendar = [NSCalendar currentCalendar];
        NSUInteger unitFlags = NSCalendarUnitMinute | NSCalendarUnitHour | NSCalendarUnitDay | NSCalendarUnitWeekOfYear | NSCalendarUnitMonth | NSCalendarUnitYear | NSCalendarUnitSecond;
        NSDate *earliest = [self earlierDate:date];
        NSDate *latest = (earliest == self) ? date : self;
        NSDateComponents *components = [calendar components:unitFlags fromDate:earliest toDate:latest options:0];
        NSDate *yesterday = [date dateBySubtractingDays:1];
        BOOL isYesterday = yesterday.day == self.day;
        
        //Not Yet Implemented/Optional
        //The following strings are present in the translation files but lack logic as of 2014.04.05
        //@"Today", @"This week", @"This month", @"This year"
        //and @"This morning", @"This afternoon"
        
        if (components.year >= 2) {
            return  [self logicLocalizedStringFromFormat:@"%%d %@years ago" withValue:components.year];
        }
        else if (components.year >= 1) {
            
            if (useNumericDates) {
                return DateToolsLocalizedStrings(@"1 year ago");
            }
            
            return DateToolsLocalizedStrings(@"Last year");
        }
        else if (components.month >= 2) {
            return [self logicLocalizedStringFromFormat:@"%%d %@months ago" withValue:components.month];
        }
        else if (components.month >= 1) {
            
            if (useNumericDates) {
                return DateToolsLocalizedStrings(@"1 month ago");
            }
            
            return DateToolsLocalizedStrings(@"Last month");
        }
        else if (components.weekOfYear >= 2) {
            return [self logicLocalizedStringFromFormat:@"%%d %@weeks ago" withValue:components.weekOfYear];
        }
        else if (components.weekOfYear >= 1) {
            
            if (useNumericDates) {
                return DateToolsLocalizedStrings(@"1 week ago");
            }
            
            return DateToolsLocalizedStrings(@"Last week");
        }
        else if (components.day >= 2) {
            return [self logicLocalizedStringFromFormat:@"%%d %@days ago" withValue:components.day];
        }
        else if (isYesterday) {
            if (useNumericDates) {
                return DateToolsLocalizedStrings(@"1 day ago");
            }
            
            return DateToolsLocalizedStrings(@"Yesterday");
        }
        else if (components.hour >= 2) {
            return [self logicLocalizedStringFromFormat:@"%%d %@hours ago" withValue:components.hour];
        }
        else if (components.hour >= 1) {
            
            if (useNumericTimes) {
                return DateToolsLocalizedStrings(@"1 hour ago");
            }
            
            return DateToolsLocalizedStrings(@"An hour ago");
        }
        else if (components.minute >= 2) {
            return [self logicLocalizedStringFromFormat:@"%%d %@minutes ago" withValue:components.minute];
        }
        else if (components.minute >= 1) {
            
            if (useNumericTimes) {
                return DateToolsLocalizedStrings(@"1 minute ago");
            }
            
            return DateToolsLocalizedStrings(@"A minute ago");
        }
        else if (components.second >= 3) {
            return [self logicLocalizedStringFromFormat:@"%%d %@seconds ago" withValue:components.second];
        }
        else {
            
            if (useNumericTimes) {
                return DateToolsLocalizedStrings(@"1 second ago");
            }
            
            return DateToolsLocalizedStrings(@"Just now");
        }
        
    }
    - (NSString *)shortTimeAgoSinceDate:(NSDate *)date{
        
        //If shortened formatting is requested, drop the "ago" part of the time ago
        //use abbreviated unit names
        
        NSCalendar *calendar = [NSCalendar currentCalendar];
        NSUInteger unitFlags = NSCalendarUnitMinute | NSCalendarUnitHour | NSCalendarUnitDay | NSCalendarUnitWeekOfYear | NSCalendarUnitMonth | NSCalendarUnitYear | NSCalendarUnitSecond;
        NSDate *earliest = [self earlierDate:date];
        NSDate *latest = (earliest == self) ? date : self;
        NSDateComponents *components = [calendar components:unitFlags fromDate:earliest toDate:latest options:0];
        NSDate *yesterday = [date dateBySubtractingDays:1];
        BOOL isYesterday = yesterday.day == self.day;
        
        
        if (components.year >= 1) {
            return  [self logicLocalizedStringFromFormat:@"%%d%@y" withValue:components.year];
        }
        else if (components.month >= 1) {
            return [self logicLocalizedStringFromFormat:@"%%d%@M" withValue:components.month];
        }
        else if (components.weekOfYear >= 1) {
            return [self logicLocalizedStringFromFormat:@"%%d%@w" withValue:components.weekOfYear];
        }
        else if (components.day >= 2) {
            return [self logicLocalizedStringFromFormat:@"%%d%@d" withValue:components.day];
        }
        else if (isYesterday) {
            return [self logicLocalizedStringFromFormat:@"%%d%@d" withValue:1];
        }
        else if (components.hour >= 1) {
            return [self logicLocalizedStringFromFormat:@"%%d%@h" withValue:components.hour];
        }
        else if (components.minute >= 1) {
            return [self logicLocalizedStringFromFormat:@"%%d%@m" withValue:components.minute];
        }
        else if (components.second >= 3) {
            return [self logicLocalizedStringFromFormat:@"%%d%@s" withValue:components.second];
        }
        else {
            return [self logicLocalizedStringFromFormat:@"%%d%@s" withValue:components.second];
            //return DateToolsLocalizedStrings(@"Now"); //string not yet translated 2014.04.05
        }
        
    }
    
    - (NSString *) logicLocalizedStringFromFormat:(NSString *)format withValue:(NSInteger)value{
        NSString * localeFormat = [NSString stringWithFormat:format, [self getLocaleFormatUnderscoresWithValue:value]];
        return [NSString stringWithFormat:DateToolsLocalizedStrings(localeFormat), value];
    }
    
    - (NSString *)getLocaleFormatUnderscoresWithValue:(double)value{
        NSString *localeCode = [[[NSBundle mainBundle] preferredLocalizations] objectAtIndex:0];
        
        // Russian (ru) and Ukrainian (uk)
        if([localeCode isEqualToString:@"ru"] || [localeCode isEqualToString:@"uk"]) {
            int XY = (int)floor(value) % 100;
            int 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 @"__";
            }
        }
        
        // Add more languages here, which are have specific translation rules...
        
        return @"";
    }
    
    #pragma mark - Date Components Without Calendar
    /**
     *  Returns the era of the receiver. (0 for BC, 1 for AD for Gregorian)
     *
     *  @return NSInteger
     */
    - (NSInteger)era{
        return [self componentForDate:self type:DTDateComponentEra calendar:nil];
    }
    
    /**
     *  Returns the year of the receiver.
     *
     *  @return NSInteger
     */
    - (NSInteger)year{
        return [self componentForDate:self type:DTDateComponentYear calendar:nil];
    }
    
    /**
     *  Returns the month of the year of the receiver.
     *
     *  @return NSInteger
     */
    - (NSInteger)month{
        return [self componentForDate:self type:DTDateComponentMonth calendar:nil];
    }
    
    /**
     *  Returns the day of the month of the receiver.
     *
     *  @return NSInteger
     */
    - (NSInteger)day{
        return [self componentForDate:self type:DTDateComponentDay calendar:nil];
    }
    
    /**
     *  Returns the hour of the day of the receiver. (0-24)
     *
     *  @return NSInteger
     */
    - (NSInteger)hour{
        return [self componentForDate:self type:DTDateComponentHour calendar:nil];
    }
    
    /**
     *  Returns the minute of the receiver. (0-59)
     *
     *  @return NSInteger
     */
    - (NSInteger)minute{
        return [self componentForDate:self type:DTDateComponentMinute calendar:nil];
    }
    
    /**
     *  Returns the second of the receiver. (0-59)
     *
     *  @return NSInteger
     */
    - (NSInteger)second{
        return [self componentForDate:self type:DTDateComponentSecond calendar:nil];
    }
    
    /**
     *  Returns the day of the week of the receiver.
     *
     *  @return NSInteger
     */
    - (NSInteger)weekday{
        return [self componentForDate:self type:DTDateComponentWeekday calendar:nil];
    }
    
    /**
     *  Returns the ordinal for the day of the week of the receiver.
     *
     *  @return NSInteger
     */
    - (NSInteger)weekdayOrdinal{
        return [self componentForDate:self type:DTDateComponentWeekdayOrdinal calendar:nil];
    }
    
    /**
     *  Returns the quarter of the receiver.
     *
     *  @return NSInteger
     */
    - (NSInteger)quarter{
        return [self componentForDate:self type:DTDateComponentQuarter calendar:nil];
    }
    
    /**
     *  Returns the week of the month of the receiver.
     *
     *  @return NSInteger
     */
    - (NSInteger)weekOfMonth{
        return [self componentForDate:self type:DTDateComponentWeekOfMonth calendar:nil];
    }
    
    /**
     *  Returns the week of the year of the receiver.
     *
     *  @return NSInteger
     */
    - (NSInteger)weekOfYear{
        return [self componentForDate:self type:DTDateComponentWeekOfYear calendar:nil];
    }
    
    /**
     *  I honestly don't know much about this value...
     *
     *  @return NSInteger
     */
    - (NSInteger)yearForWeekOfYear{
        return [self componentForDate:self type:DTDateComponentYearForWeekOfYear calendar:nil];
    }
    
    /**
     *  Returns how many days are in the month of the receiver.
     *
     *  @return NSInteger
     */
    - (NSInteger)daysInMonth{
        NSCalendar *calendar = [NSCalendar currentCalendar];
        NSRange days = [calendar rangeOfUnit:NSCalendarUnitDay
                                      inUnit:NSCalendarUnitMonth
                                     forDate:self];
        return days.length;
    }
    
    /**
     *  Returns the day of the year of the receiver. (1-365 or 1-366 for leap year)
     *
     *  @return NSInteger
     */
    - (NSInteger)dayOfYear{
        return [self componentForDate:self type:DTDateComponentDayOfYear calendar:nil];
    }
    
    /**
     *  Returns how many days are in the year of the receiver.
     *
     *  @return NSInteger
     */
    -(NSInteger)daysInYear{
        if (self.isInLeapYear) {
            return 366;
        }
        
        return 365;
    }
    
    /**
     *  Returns whether the receiver falls in a leap year.
     *
     *  @return NSInteger
     */
    -(BOOL)isInLeapYear{
        NSCalendar *calendar = [[self class] implicitCalendar];
        NSDateComponents *dateComponents = [calendar components:allCalendarUnitFlags fromDate:self];
        
        if (dateComponents.year%400 == 0){
            return YES;
        }
        else if (dateComponents.year%100 == 0){
            return NO;
        }
        else if (dateComponents.year%4 == 0){
            return YES;
        }
        
        return NO;
    }
    
    - (BOOL)isToday {
        NSCalendar *cal = [NSCalendar currentCalendar];
        NSDateComponents *components = [cal components:(NSCalendarUnitEra|NSCalendarUnitYear|NSCalendarUnitMonth|NSCalendarUnitDay) fromDate:[NSDate date]];
        NSDate *today = [cal dateFromComponents:components];
        components = [cal components:(NSCalendarUnitEra|NSCalendarUnitYear|NSCalendarUnitMonth|NSCalendarUnitDay) fromDate:self];
        NSDate *otherDate = [cal dateFromComponents:components];
        
        return [today isEqualToDate:otherDate];
    }
    
    - (BOOL)isTomorrow {
        NSCalendar *cal = [NSCalendar currentCalendar];
        NSDateComponents *components = [cal components:(NSCalendarUnitEra|NSCalendarUnitYear|NSCalendarUnitMonth|NSCalendarUnitDay) fromDate:[[NSDate date] dateByAddingDays:1]];
        NSDate *tomorrow = [cal dateFromComponents:components];
        components = [cal components:(NSCalendarUnitEra|NSCalendarUnitYear|NSCalendarUnitMonth|NSCalendarUnitDay) fromDate:self];
        NSDate *otherDate = [cal dateFromComponents:components];
        
        return [tomorrow isEqualToDate:otherDate];
    }
    
    - (BOOL)isTheDayAfterTomorrow {
        NSCalendar *cal = [NSCalendar currentCalendar];
        NSDateComponents *components = [cal components:(NSCalendarUnitEra|NSCalendarUnitYear|NSCalendarUnitMonth|NSCalendarUnitDay) fromDate:[[NSDate date] dateByAddingDays:2]];
        NSDate *theDayAfterTomorrow = [cal dateFromComponents:components];
        components = [cal components:(NSCalendarUnitEra|NSCalendarUnitYear|NSCalendarUnitMonth|NSCalendarUnitDay) fromDate:self];
        NSDate *otherDate = [cal dateFromComponents:components];
        
        return [theDayAfterTomorrow isEqualToDate:otherDate];
    }
    
    -(BOOL)isYesterday{
        NSCalendar *cal = [NSCalendar currentCalendar];
        NSDateComponents *components = [cal components:(NSCalendarUnitEra|NSCalendarUnitYear|NSCalendarUnitMonth|NSCalendarUnitDay) fromDate:[[NSDate date] dateBySubtractingDays:1]];
        NSDate *tomorrow = [cal dateFromComponents:components];
        components = [cal components:(NSCalendarUnitEra|NSCalendarUnitYear|NSCalendarUnitMonth|NSCalendarUnitDay) fromDate:self];
        NSDate *otherDate = [cal dateFromComponents:components];
        
        return [tomorrow isEqualToDate:otherDate];
    }
    
    - (BOOL)isWeekend {
        NSCalendar *calendar            = [NSCalendar currentCalendar];
        NSRange weekdayRange            = [calendar maximumRangeOfUnit:NSCalendarUnitWeekday];
        NSDateComponents *components    = [calendar components:NSCalendarUnitWeekday
                                                      fromDate:self];
        NSUInteger weekdayOfSomeDate    = [components weekday];
        
        BOOL result = NO;
        
        if (weekdayOfSomeDate == weekdayRange.location || weekdayOfSomeDate == weekdayRange.length)
            result = YES;
        
        return result;
    }
    
    - (BOOL)isSameDayWithDate:(NSDate *)date {
        return self.year == date.year && self.month == date.month && self.day == date.day;
    }
    
    #pragma mark - Date Components With Calendar
    /**
     *  Returns the era of the receiver from a given calendar
     *
     *  @param calendar NSCalendar - The calendar to be used in the calculation
     *
     *  @return NSInteger - represents the era (0 for BC, 1 for AD for Gregorian)
     */
    - (NSInteger)eraWithCalendar:(NSCalendar *)calendar{
        return [self componentForDate:self type:DTDateComponentEra calendar:calendar];
    }
    
    /**
     *  Returns the year of the receiver from a given calendar
     *
     *  @param calendar NSCalendar - The calendar to be used in the calculation
     *
     *  @return NSInteger - represents the year as an integer
     */
    - (NSInteger)yearWithCalendar:(NSCalendar *)calendar{
        return [self componentForDate:self type:DTDateComponentYear calendar:calendar];
    }
    
    /**
     *  Returns the month of the receiver from a given calendar
     *
     *  @param calendar NSCalendar - The calendar to be used in the calculation
     *
     *  @return NSInteger - represents the month as an integer
     */
    - (NSInteger)monthWithCalendar:(NSCalendar *)calendar{
        return [self componentForDate:self type:DTDateComponentMonth calendar:calendar];
    }
    
    /**
     *  Returns the day of the month of the receiver from a given calendar
     *
     *  @param calendar NSCalendar - The calendar to be used in the calculation
     *
     *  @return NSInteger - represents the day of the month as an integer
     */
    - (NSInteger)dayWithCalendar:(NSCalendar *)calendar{
        return [self componentForDate:self type:DTDateComponentDay calendar:calendar];
    }
    
    /**
     *  Returns the hour of the day of the receiver from a given calendar
     *
     *  @param calendar NSCalendar - The calendar to be used in the calculation
     *
     *  @return NSInteger - represents the hour of the day as an integer
     */
    - (NSInteger)hourWithCalendar:(NSCalendar *)calendar{
        return [self componentForDate:self type:DTDateComponentHour calendar:calendar];
    }
    
    /**
     *  Returns the minute of the hour of the receiver from a given calendar
     *
     *  @param calendar NSCalendar - The calendar to be used in the calculation
     *
     *  @return NSInteger - represents the minute of the hour as an integer
     */
    - (NSInteger)minuteWithCalendar:(NSCalendar *)calendar{
        return [self componentForDate:self type:DTDateComponentMinute calendar:calendar];
    }
    
    /**
     *  Returns the second of the receiver from a given calendar
     *
     *  @param calendar NSCalendar - The calendar to be used in the calculation
     *
     *  @return NSInteger - represents the second as an integer
     */
    - (NSInteger)secondWithCalendar:(NSCalendar *)calendar{
        return [self componentForDate:self type:DTDateComponentSecond calendar:calendar];
    }
    
    /**
     *  Returns the weekday of the receiver from a given calendar
     *
     *  @param calendar NSCalendar - The calendar to be used in the calculation
     *
     *  @return NSInteger - represents the weekday as an integer
     */
    - (NSInteger)weekdayWithCalendar:(NSCalendar *)calendar{
        return [self componentForDate:self type:DTDateComponentWeekday calendar:calendar];
    }
    
    /**
     *  Returns the weekday ordinal of the receiver from a given calendar
     *
     *  @param calendar NSCalendar - The calendar to be used in the calculation
     *
     *  @return NSInteger - represents the weekday ordinal as an integer
     */
    - (NSInteger)weekdayOrdinalWithCalendar:(NSCalendar *)calendar{
        return [self componentForDate:self type:DTDateComponentWeekdayOrdinal calendar:calendar];
    }
    
    /**
     *  Returns the quarter of the receiver from a given calendar
     *
     *  @param calendar NSCalendar - The calendar to be used in the calculation
     *
     *  @return NSInteger - represents the quarter as an integer
     */
    - (NSInteger)quarterWithCalendar:(NSCalendar *)calendar{
        return [self componentForDate:self type:DTDateComponentQuarter calendar:calendar];
    }
    
    /**
     *  Returns the week of the month of the receiver from a given calendar
     *
     *  @param calendar NSCalendar - The calendar to be used in the calculation
     *
     *  @return NSInteger - represents the week of the month as an integer
     */
    - (NSInteger)weekOfMonthWithCalendar:(NSCalendar *)calendar{
        return [self componentForDate:self type:DTDateComponentWeekOfMonth calendar:calendar];
    }
    
    /**
     *  Returns the week of the year of the receiver from a given calendar
     *
     *  @param calendar NSCalendar - The calendar to be used in the calculation
     *
     *  @return NSInteger - represents the week of the year as an integer
     */
    - (NSInteger)weekOfYearWithCalendar:(NSCalendar *)calendar{
        return [self componentForDate:self type:DTDateComponentWeekOfYear calendar:calendar];
    }
    
    /**
     *  Returns the year for week of the year (???) of the receiver from a given calendar
     *
     *  @param calendar NSCalendar - The calendar to be used in the calculation
     *
     *  @return NSInteger - represents the year for week of the year as an integer
     */
    - (NSInteger)yearForWeekOfYearWithCalendar:(NSCalendar *)calendar{
        return [self componentForDate:self type:DTDateComponentYearForWeekOfYear calendar:calendar];
    }
    
    
    /**
     *  Returns the day of the year of the receiver from a given calendar
     *
     *  @param calendar NSCalendar - The calendar to be used in the calculation
     *
     *  @return NSInteger - represents the day of the year as an integer
     */
    - (NSInteger)dayOfYearWithCalendar:(NSCalendar *)calendar{
        return [self componentForDate:self type:DTDateComponentDayOfYear calendar:calendar];
    }
    
    /**
     *  Takes in a date, calendar and desired date component and returns the desired NSInteger
     *  representation for that component
     *
     *  @param date      NSDate - The date to be be mined for a desired component
     *  @param component DTDateComponent - The desired component (i.e. year, day, week, etc)
     *  @param calendar  NSCalendar - The calendar to be used in the processing (Defaults to Gregorian)
     *
     *  @return NSInteger
     */
    -(NSInteger)componentForDate:(NSDate *)date type:(DTDateComponent)component calendar:(NSCalendar *)calendar{
        if (!calendar) {
            calendar = [[self class] implicitCalendar];
        }
        
        unsigned int unitFlags = 0;
        
        if (component == DTDateComponentYearForWeekOfYear) {
            unitFlags = NSCalendarUnitYear | NSCalendarUnitQuarter | NSCalendarUnitMonth | NSCalendarUnitWeekOfYear | NSCalendarUnitWeekOfMonth | NSCalendarUnitDay | NSCalendarUnitHour | NSCalendarUnitMinute | NSCalendarUnitSecond | NSCalendarUnitEra | NSCalendarUnitWeekday | NSCalendarUnitWeekdayOrdinal | NSCalendarUnitWeekOfYear | NSCalendarUnitYearForWeekOfYear;
        }
        else {
            unitFlags = allCalendarUnitFlags;
        }
        
        NSDateComponents *dateComponents = [calendar components:unitFlags fromDate:date];
        
        switch (component) {
            case DTDateComponentEra:
                return [dateComponents era];
            case DTDateComponentYear:
                return [dateComponents year];
            case DTDateComponentMonth:
                return [dateComponents month];
            case DTDateComponentDay:
                return [dateComponents day];
            case DTDateComponentHour:
                return [dateComponents hour];
            case DTDateComponentMinute:
                return [dateComponents minute];
            case DTDateComponentSecond:
                return [dateComponents second];
            case DTDateComponentWeekday:
                return [dateComponents weekday];
            case DTDateComponentWeekdayOrdinal:
                return [dateComponents weekdayOrdinal];
            case DTDateComponentQuarter:
                return [dateComponents quarter];
            case DTDateComponentWeekOfMonth:
                return [dateComponents weekOfMonth];
            case DTDateComponentWeekOfYear:
                return [dateComponents weekOfYear];
            case DTDateComponentYearForWeekOfYear:
                return [dateComponents yearForWeekOfYear];
            case DTDateComponentDayOfYear:
                return [calendar ordinalityOfUnit:NSCalendarUnitDay inUnit:NSCalendarUnitYear forDate:date];
            default:
                break;
        }
        
        return 0;
    }
    
    #pragma mark - Date Creating
    + (NSDate *)dateWithYear:(NSInteger)year month:(NSInteger)month day:(NSInteger)day {
        
        return [self dateWithYear:year month:month day:day hour:0 minute:0 second:0];
    }
    
    + (NSDate *)dateWithYear:(NSInteger)year month:(NSInteger)month day:(NSInteger)day hour:(NSInteger)hour minute:(NSInteger)minute second:(NSInteger)second {
        
        NSDate *nsDate = nil;
        NSDateComponents *components = [[NSDateComponents alloc] init];
        
        components.year   = year;
        components.month  = month;
        components.day    = day;
        components.hour   = hour;
        components.minute = minute;
        components.second = second;
        
        nsDate = [[[self class] implicitCalendar] dateFromComponents:components];
        
        return nsDate;
    }
    
    + (NSDate *)dateWithString:(NSString *)dateString formatString:(NSString *)formatString {
        
        return [self dateWithString:dateString formatString:formatString timeZone:[NSTimeZone systemTimeZone]];
    }
    
    + (NSDate *)dateWithString:(NSString *)dateString formatString:(NSString *)formatString timeZone:(NSTimeZone *)timeZone {
        
        static NSDateFormatter *parser = nil;
        static dispatch_once_t onceToken;
        dispatch_once(&onceToken, ^{
            parser = [[NSDateFormatter alloc] init];
        });
        
        parser.dateStyle = NSDateFormatterNoStyle;
        parser.timeStyle = NSDateFormatterNoStyle;
        parser.timeZone = timeZone;
        parser.dateFormat = formatString;
        
        return [parser dateFromString:dateString];
    }
    
    
    #pragma mark - Date Editing
    #pragma mark Date By Adding
    /**
     *  Returns a date representing the receivers date shifted later by the provided number of years.
     *
     *  @param years NSInteger - Number of years to add
     *
     *  @return NSDate - Date modified by the number of desired years
     */
    - (NSDate *)dateByAddingYears:(NSInteger)years{
        NSCalendar *calendar = [[self class] implicitCalendar];
        NSDateComponents *components = [[NSDateComponents alloc] init];
        [components setYear:years];
        
        return [calendar dateByAddingComponents:components toDate:self options:0];
    }
    
    /**
     *  Returns a date representing the receivers date shifted later by the provided number of months.
     *
     *  @param months NSInteger - Number of months to add
     *
     *  @return NSDate - Date modified by the number of desired months
     */
    - (NSDate *)dateByAddingMonths:(NSInteger)months{
        NSCalendar *calendar = [[self class] implicitCalendar];
        NSDateComponents *components = [[NSDateComponents alloc] init];
        [components setMonth:months];
        
        return [calendar dateByAddingComponents:components toDate:self options:0];
    }
    
    /**
     *  Returns a date representing the receivers date shifted later by the provided number of weeks.
     *
     *  @param weeks NSInteger - Number of weeks to add
     *
     *  @return NSDate - Date modified by the number of desired weeks
     */
    - (NSDate *)dateByAddingWeeks:(NSInteger)weeks{
        NSCalendar *calendar = [[self class] implicitCalendar];
        NSDateComponents *components = [[NSDateComponents alloc] init];
        [components setWeekOfYear:weeks];
        
        return [calendar dateByAddingComponents:components toDate:self options:0];
    }
    
    /**
     *  Returns a date representing the receivers date shifted later by the provided number of days.
     *
     *  @param days NSInteger - Number of days to add
     *
     *  @return NSDate - Date modified by the number of desired days
     */
    - (NSDate *)dateByAddingDays:(NSInteger)days{
        NSCalendar *calendar = [[self class] implicitCalendar];
        NSDateComponents *components = [[NSDateComponents alloc] init];
        [components setDay:days];
        
        return [calendar dateByAddingComponents:components toDate:self options:0];
    }
    
    /**
     *  Returns a date representing the receivers date shifted later by the provided number of hours.
     *
     *  @param hours NSInteger - Number of hours to add
     *
     *  @return NSDate - Date modified by the number of desired hours
     */
    - (NSDate *)dateByAddingHours:(NSInteger)hours{
        NSCalendar *calendar = [[self class] implicitCalendar];
        NSDateComponents *components = [[NSDateComponents alloc] init];
        [components setHour:hours];
        
        return [calendar dateByAddingComponents:components toDate:self options:0];
    }
    
    /**
     *  Returns a date representing the receivers date shifted later by the provided number of minutes.
     *
     *  @param minutes NSInteger - Number of minutes to add
     *
     *  @return NSDate - Date modified by the number of desired minutes
     */
    - (NSDate *)dateByAddingMinutes:(NSInteger)minutes{
        NSCalendar *calendar = [[self class] implicitCalendar];
        NSDateComponents *components = [[NSDateComponents alloc] init];
        [components setMinute:minutes];
        
        return [calendar dateByAddingComponents:components toDate:self options:0];
    }
    
    /**
     *  Returns a date representing the receivers date shifted later by the provided number of seconds.
     *
     *  @param seconds NSInteger - Number of seconds to add
     *
     *  @return NSDate - Date modified by the number of desired seconds
     */
    - (NSDate *)dateByAddingSeconds:(NSInteger)seconds{
        NSCalendar *calendar = [[self class] implicitCalendar];
        NSDateComponents *components = [[NSDateComponents alloc] init];
        [components setSecond:seconds];
        
        return [calendar dateByAddingComponents:components toDate:self options:0];
    }
    
    #pragma mark Date By Subtracting
    /**
     *  Returns a date representing the receivers date shifted earlier by the provided number of years.
     *
     *  @param years NSInteger - Number of years to subtract
     *
     *  @return NSDate - Date modified by the number of desired years
     */
    - (NSDate *)dateBySubtractingYears:(NSInteger)years{
        NSCalendar *calendar = [[self class] implicitCalendar];
        NSDateComponents *components = [[NSDateComponents alloc] init];
        [components setYear:-1*years];
        
        return [calendar dateByAddingComponents:components toDate:self options:0];
    }
    
    /**
     *  Returns a date representing the receivers date shifted earlier by the provided number of months.
     *
     *  @param months months - Number of months to subtract
     *
     *  @return NSDate - Date modified by the number of desired months
     */
    - (NSDate *)dateBySubtractingMonths:(NSInteger)months{
        NSCalendar *calendar = [[self class] implicitCalendar];
        NSDateComponents *components = [[NSDateComponents alloc] init];
        [components setMonth:-1*months];
        
        return [calendar dateByAddingComponents:components toDate:self options:0];
    }
    
    /**
     *  Returns a date representing the receivers date shifted earlier by the provided number of weeks.
     *
     *  @param weeks NSInteger - Number of weeks to subtract
     *
     *  @return NSDate - Date modified by the number of desired weeks
     */
    - (NSDate *)dateBySubtractingWeeks:(NSInteger)weeks{
        NSCalendar *calendar = [[self class] implicitCalendar];
        NSDateComponents *components = [[NSDateComponents alloc] init];
        [components setWeekOfYear:-1*weeks];
        
        return [calendar dateByAddingComponents:components toDate:self options:0];
    }
    
    /**
     *  Returns a date representing the receivers date shifted earlier by the provided number of days.
     *
     *  @param days NSInteger - Number of days to subtract
     *
     *  @return NSDate - Date modified by the number of desired days
     */
    - (NSDate *)dateBySubtractingDays:(NSInteger)days{
        NSCalendar *calendar = [[self class] implicitCalendar];
        NSDateComponents *components = [[NSDateComponents alloc] init];
        [components setDay:-1*days];
        
        return [calendar dateByAddingComponents:components toDate:self options:0];
    }
    
    /**
     *  Returns a date representing the receivers date shifted earlier by the provided number of hours.
     *
     *  @param hours NSInteger - Number of hours to subtract
     *
     *  @return NSDate - Date modified by the number of desired hours
     */
    - (NSDate *)dateBySubtractingHours:(NSInteger)hours{
        NSCalendar *calendar = [[self class] implicitCalendar];
        NSDateComponents *components = [[NSDateComponents alloc] init];
        [components setHour:-1*hours];
        
        return [calendar dateByAddingComponents:components toDate:self options:0];
    }
    
    /**
     *  Returns a date representing the receivers date shifted earlier by the provided number of minutes.
     *
     *  @param minutes NSInteger - Number of minutes to subtract
     *
     *  @return NSDate - Date modified by the number of desired minutes
     */
    - (NSDate *)dateBySubtractingMinutes:(NSInteger)minutes{
        NSCalendar *calendar = [[self class] implicitCalendar];
        NSDateComponents *components = [[NSDateComponents alloc] init];
        [components setMinute:-1*minutes];
        
        return [calendar dateByAddingComponents:components toDate:self options:0];
    }
    
    /**
     *  Returns a date representing the receivers date shifted earlier by the provided number of seconds.
     *
     *  @param seconds NSInteger - Number of seconds to subtract
     *
     *  @return NSDate - Date modified by the number of desired seconds
     */
    - (NSDate *)dateBySubtractingSeconds:(NSInteger)seconds{
        NSCalendar *calendar = [[self class] implicitCalendar];
        NSDateComponents *components = [[NSDateComponents alloc] init];
        [components setSecond:-1*seconds];
        
        return [calendar dateByAddingComponents:components toDate:self options:0];
    }
    
    #pragma mark - Date Comparison
    #pragma mark Time From
    /**
     *  Returns an NSInteger representing the amount of time in years between the receiver and the provided date.
     *  If the receiver is earlier than the provided date, the returned value will be negative.
     *  Uses the default Gregorian calendar
     *
     *  @param date NSDate - The provided date for comparison
     *
     *  @return NSInteger - The NSInteger representation of the years between receiver and provided date
     */
    -(NSInteger)yearsFrom:(NSDate *)date{
        return [self yearsFrom:date calendar:nil];
    }
    
    /**
     *  Returns an NSInteger representing the amount of time in months between the receiver and the provided date.
     *  If the receiver is earlier than the provided date, the returned value will be negative.
     *  Uses the default Gregorian calendar
     *
     *  @param date NSDate - The provided date for comparison
     *
     *  @return NSInteger - The NSInteger representation of the years between receiver and provided date
     */
    -(NSInteger)monthsFrom:(NSDate *)date{
        return [self monthsFrom:date calendar:nil];
    }
    
    /**
     *  Returns an NSInteger representing the amount of time in weeks between the receiver and the provided date.
     *  If the receiver is earlier than the provided date, the returned value will be negative.
     *  Uses the default Gregorian calendar
     *
     *  @param date NSDate - The provided date for comparison
     *
     *  @return NSInteger - The double representation of the weeks between receiver and provided date
     */
    -(NSInteger)weeksFrom:(NSDate *)date{
        return [self weeksFrom:date calendar:nil];
    }
    
    /**
     *  Returns an NSInteger representing the amount of time in days between the receiver and the provided date.
     *  If the receiver is earlier than the provided date, the returned value will be negative.
     *  Uses the default Gregorian calendar
     *
     *  @param date NSDate - The provided date for comparison
     *
     *  @return NSInteger - The double representation of the days between receiver and provided date
     */
    -(NSInteger)daysFrom:(NSDate *)date{
        return [self daysFrom:date calendar:nil];
    }
    
    /**
     *  Returns an NSInteger representing the amount of time in hours between the receiver and the provided date.
     *  If the receiver is earlier than the provided date, the returned value will be negative.
     *
     *  @param date NSDate - The provided date for comparison
     *
     *  @return double - The double representation of the hours between receiver and provided date
     */
    -(double)hoursFrom:(NSDate *)date{
        return ([self timeIntervalSinceDate:date])/SECONDS_IN_HOUR;
    }
    
    /**
     *  Returns an NSInteger representing the amount of time in minutes between the receiver and the provided date.
     *  If the receiver is earlier than the provided date, the returned value will be negative.
     *
     *  @param date NSDate - The provided date for comparison
     *
     *  @return double - The double representation of the minutes between receiver and provided date
     */
    -(double)minutesFrom:(NSDate *)date{
        return ([self timeIntervalSinceDate:date])/SECONDS_IN_MINUTE;
    }
    
    /**
     *  Returns an NSInteger representing the amount of time in seconds between the receiver and the provided date.
     *  If the receiver is earlier than the provided date, the returned value will be negative.
     *
     *  @param date NSDate - The provided date for comparison
     *
     *  @return double - The double representation of the seconds between receiver and provided date
     */
    -(double)secondsFrom:(NSDate *)date{
        return [self timeIntervalSinceDate:date];
    }
    
    #pragma mark Time From With Calendar
    /**
     *  Returns an NSInteger representing the amount of time in years between the receiver and the provided date.
     *  If the receiver is earlier than the provided date, the returned value will be negative.
     *
     *  @param date     NSDate - The provided date for comparison
     *  @param calendar NSCalendar - The calendar to be used in the calculation
     *
     *  @return NSInteger - The double representation of the years between receiver and provided date
     */
    -(NSInteger)yearsFrom:(NSDate *)date calendar:(NSCalendar *)calendar{
        if (!calendar) {
            calendar = [[self class] implicitCalendar];
        }
        
        NSDate *earliest = [self earlierDate:date];
        NSDate *latest = (earliest == self) ? date : self;
        NSInteger multiplier = (earliest == self) ? -1 : 1;
        NSDateComponents *components = [calendar components:NSCalendarUnitYear fromDate:earliest toDate:latest options:0];
        return multiplier*components.year;
    }
    
    /**
     *  Returns an NSInteger representing the amount of time in months between the receiver and the provided date.
     *  If the receiver is earlier than the provided date, the returned value will be negative.
     *
     *  @param date     NSDate - The provided date for comparison
     *  @param calendar NSCalendar - The calendar to be used in the calculation
     *
     *  @return NSInteger - The double representation of the months between receiver and provided date
     */
    -(NSInteger)monthsFrom:(NSDate *)date calendar:(NSCalendar *)calendar{
        if (!calendar) {
            calendar = [[self class] implicitCalendar];
        }
        
        NSDate *earliest = [self earlierDate:date];
        NSDate *latest = (earliest == self) ? date : self;
        NSInteger multiplier = (earliest == self) ? -1 : 1;
        NSDateComponents *components = [calendar components:allCalendarUnitFlags fromDate:earliest toDate:latest options:0];
        return multiplier*(components.month + 12*components.year);
    }
    
    /**
     *  Returns an NSInteger representing the amount of time in weeks between the receiver and the provided date.
     *  If the receiver is earlier than the provided date, the returned value will be negative.
     *
     *  @param date     NSDate - The provided date for comparison
     *  @param calendar NSCalendar - The calendar to be used in the calculation
     *
     *  @return NSInteger - The double representation of the weeks between receiver and provided date
     */
    -(NSInteger)weeksFrom:(NSDate *)date calendar:(NSCalendar *)calendar{
        if (!calendar) {
            calendar = [[self class] implicitCalendar];
        }
        
        NSDate *earliest = [self earlierDate:date];
        NSDate *latest = (earliest == self) ? date : self;
        NSInteger multiplier = (earliest == self) ? -1 : 1;
        NSDateComponents *components = [calendar components:NSCalendarUnitWeekOfYear fromDate:earliest toDate:latest options:0];
        return multiplier*components.weekOfYear;
    }
    
    /**
     *  Returns an NSInteger representing the amount of time in days between the receiver and the provided date.
     *  If the receiver is earlier than the provided date, the returned value will be negative.
     *
     *  @param date     NSDate - The provided date for comparison
     *  @param calendar NSCalendar - The calendar to be used in the calculation
     *
     *  @return NSInteger - The double representation of the days between receiver and provided date
     */
    -(NSInteger)daysFrom:(NSDate *)date calendar:(NSCalendar *)calendar{
        if (!calendar) {
            calendar = [[self class] implicitCalendar];
        }
        
        NSDate *earliest = [self earlierDate:date];
        NSDate *latest = (earliest == self) ? date : self;
        NSInteger multiplier = (earliest == self) ? -1 : 1;
        NSDateComponents *components = [calendar components:NSCalendarUnitDay fromDate:earliest toDate:latest options:0];
        return multiplier*components.day;
    }
    
    #pragma mark Time Until
    /**
     *  Returns the number of years until the receiver's date. Returns 0 if the receiver is the same or earlier than now.
     *
     *  @return NSInteger representiation of years
     */
    -(NSInteger)yearsUntil{
        return [self yearsLaterThan:[NSDate date]];
    }
    
    /**
     *  Returns the number of months until the receiver's date. Returns 0 if the receiver is the same or earlier than now.
     *
     *  @return NSInteger representiation of months
     */
    -(NSInteger)monthsUntil{
        return [self monthsLaterThan:[NSDate date]];
    }
    
    /**
     *  Returns the number of weeks until the receiver's date. Returns 0 if the receiver is the same or earlier than now.
     *
     *  @return NSInteger representiation of weeks
     */
    -(NSInteger)weeksUntil{
        return [self weeksLaterThan:[NSDate date]];
    }
    
    /**
     *  Returns the number of days until the receiver's date. Returns 0 if the receiver is the same or earlier than now.
     *
     *  @return NSInteger representiation of days
     */
    -(NSInteger)daysUntil{
        return [self daysLaterThan:[NSDate date]];
    }
    
    /**
     *  Returns the number of hours until the receiver's date. Returns 0 if the receiver is the same or earlier than now.
     *
     *  @return double representiation of hours
     */
    -(double)hoursUntil{
        return [self hoursLaterThan:[NSDate date]];
    }
    
    /**
     *  Returns the number of minutes until the receiver's date. Returns 0 if the receiver is the same or earlier than now.
     *
     *  @return double representiation of minutes
     */
    -(double)minutesUntil{
        return [self minutesLaterThan:[NSDate date]];
    }
    
    /**
     *  Returns the number of seconds until the receiver's date. Returns 0 if the receiver is the same or earlier than now.
     *
     *  @return double representiation of seconds
     */
    -(double)secondsUntil{
        return [self secondsLaterThan:[NSDate date]];
    }
    
    #pragma mark Time Ago
    /**
     *  Returns the number of years the receiver's date is earlier than now. Returns 0 if the receiver is the same or later than now.
     *
     *  @return NSInteger representiation of years
     */
    -(NSInteger)yearsAgo{
        return [self yearsEarlierThan:[NSDate date]];
    }
    
    /**
     *  Returns the number of months the receiver's date is earlier than now. Returns 0 if the receiver is the same or later than now.
     *
     *  @return NSInteger representiation of months
     */
    -(NSInteger)monthsAgo{
        return [self monthsEarlierThan:[NSDate date]];
    }
    
    /**
     *  Returns the number of weeks the receiver's date is earlier than now. Returns 0 if the receiver is the same or later than now.
     *
     *  @return NSInteger representiation of weeks
     */
    -(NSInteger)weeksAgo{
        return [self weeksEarlierThan:[NSDate date]];
    }
    
    /**
     *  Returns the number of days the receiver's date is earlier than now. Returns 0 if the receiver is the same or later than now.
     *
     *  @return NSInteger representiation of days
     */
    -(NSInteger)daysAgo{
        return [self daysEarlierThan:[NSDate date]];
    }
    
    /**
     *  Returns the number of hours the receiver's date is earlier than now. Returns 0 if the receiver is the same or later than now.
     *
     *  @return double representiation of hours
     */
    -(double)hoursAgo{
        return [self hoursEarlierThan:[NSDate date]];
    }
    
    /**
     *  Returns the number of minutes the receiver's date is earlier than now. Returns 0 if the receiver is the same or later than now.
     *
     *  @return double representiation of minutes
     */
    -(double)minutesAgo{
        return [self minutesEarlierThan:[NSDate date]];
    }
    
    /**
     *  Returns the number of seconds the receiver's date is earlier than now. Returns 0 if the receiver is the same or later than now.
     *
     *  @return double representiation of seconds
     */
    -(double)secondsAgo{
        return [self secondsEarlierThan:[NSDate date]];
    }
    
    #pragma mark Earlier Than
    /**
     *  Returns the number of years the receiver's date is earlier than the provided comparison date.
     *  Returns 0 if the receiver's date is later than or equal to the provided comparison date.
     *
     *  @param date NSDate - Provided date for comparison
     *
     *  @return NSInteger representing the number of years
     */
    -(NSInteger)yearsEarlierThan:(NSDate *)date{
        return ABS(MIN([self yearsFrom:date], 0));
    }
    
    /**
     *  Returns the number of months the receiver's date is earlier than the provided comparison date.
     *  Returns 0 if the receiver's date is later than or equal to the provided comparison date.
     *
     *  @param date NSDate - Provided date for comparison
     *
     *  @return NSInteger representing the number of months
     */
    -(NSInteger)monthsEarlierThan:(NSDate *)date{
        return ABS(MIN([self monthsFrom:date], 0));
    }
    
    /**
     *  Returns the number of weeks the receiver's date is earlier than the provided comparison date.
     *  Returns 0 if the receiver's date is later than or equal to the provided comparison date.
     *
     *  @param date NSDate - Provided date for comparison
     *
     *  @return NSInteger representing the number of weeks
     */
    -(NSInteger)weeksEarlierThan:(NSDate *)date{
        return ABS(MIN([self weeksFrom:date], 0));
    }
    
    /**
     *  Returns the number of days the receiver's date is earlier than the provided comparison date.
     *  Returns 0 if the receiver's date is later than or equal to the provided comparison date.
     *
     *  @param date NSDate - Provided date for comparison
     *
     *  @return NSInteger representing the number of days
     */
    -(NSInteger)daysEarlierThan:(NSDate *)date{
        return ABS(MIN([self daysFrom:date], 0));
    }
    
    /**
     *  Returns the number of hours the receiver's date is earlier than the provided comparison date.
     *  Returns 0 if the receiver's date is later than or equal to the provided comparison date.
     *
     *  @param date NSDate - Provided date for comparison
     *
     *  @return double representing the number of hours
     */
    -(double)hoursEarlierThan:(NSDate *)date{
        return ABS(MIN([self hoursFrom:date], 0));
    }
    
    /**
     *  Returns the number of minutes the receiver's date is earlier than the provided comparison date.
     *  Returns 0 if the receiver's date is later than or equal to the provided comparison date.
     *
     *  @param date NSDate - Provided date for comparison
     *
     *  @return double representing the number of minutes
     */
    -(double)minutesEarlierThan:(NSDate *)date{
        return ABS(MIN([self minutesFrom:date], 0));
    }
    
    /**
     *  Returns the number of seconds the receiver's date is earlier than the provided comparison date.
     *  Returns 0 if the receiver's date is later than or equal to the provided comparison date.
     *
     *  @param date NSDate - Provided date for comparison
     *
     *  @return double representing the number of seconds
     */
    -(double)secondsEarlierThan:(NSDate *)date{
        return ABS(MIN([self secondsFrom:date], 0));
    }
    
    #pragma mark Later Than
    /**
     *  Returns the number of years the receiver's date is later than the provided comparison date.
     *  Returns 0 if the receiver's date is earlier than or equal to the provided comparison date.
     *
     *  @param date NSDate - Provided date for comparison
     *
     *  @return NSInteger representing the number of years
     */
    -(NSInteger)yearsLaterThan:(NSDate *)date{
        return MAX([self yearsFrom:date], 0);
    }
    
    /**
     *  Returns the number of months the receiver's date is later than the provided comparison date.
     *  Returns 0 if the receiver's date is earlier than or equal to the provided comparison date.
     *
     *  @param date NSDate - Provided date for comparison
     *
     *  @return NSInteger representing the number of months
     */
    -(NSInteger)monthsLaterThan:(NSDate *)date{
        return MAX([self monthsFrom:date], 0);
    }
    
    /**
     *  Returns the number of weeks the receiver's date is later than the provided comparison date.
     *  Returns 0 if the receiver's date is earlier than or equal to the provided comparison date.
     *
     *  @param date NSDate - Provided date for comparison
     *
     *  @return NSInteger representing the number of weeks
     */
    -(NSInteger)weeksLaterThan:(NSDate *)date{
        return MAX([self weeksFrom:date], 0);
    }
    
    /**
     *  Returns the number of days the receiver's date is later than the provided comparison date.
     *  Returns 0 if the receiver's date is earlier than or equal to the provided comparison date.
     *
     *  @param date NSDate - Provided date for comparison
     *
     *  @return NSInteger representing the number of days
     */
    -(NSInteger)daysLaterThan:(NSDate *)date{
        return MAX([self daysFrom:date], 0);
    }
    
    /**
     *  Returns the number of hours the receiver's date is later than the provided comparison date.
     *  Returns 0 if the receiver's date is earlier than or equal to the provided comparison date.
     *
     *  @param date NSDate - Provided date for comparison
     *
     *  @return double representing the number of hours
     */
    -(double)hoursLaterThan:(NSDate *)date{
        return MAX([self hoursFrom:date], 0);
    }
    
    /**
     *  Returns the number of minutes the receiver's date is later than the provided comparison date.
     *  Returns 0 if the receiver's date is earlier than or equal to the provided comparison date.
     *
     *  @param date NSDate - Provided date for comparison
     *
     *  @return double representing the number of minutes
     */
    -(double)minutesLaterThan:(NSDate *)date{
        return MAX([self minutesFrom:date], 0);
    }
    
    /**
     *  Returns the number of seconds the receiver's date is later than the provided comparison date.
     *  Returns 0 if the receiver's date is earlier than or equal to the provided comparison date.
     *
     *  @param date NSDate - Provided date for comparison
     *
     *  @return double representing the number of seconds
     */
    -(double)secondsLaterThan:(NSDate *)date{
        return MAX([self secondsFrom:date], 0);
    }
    
    
    #pragma mark Comparators
    /**
     *  Returns a YES if receiver is earlier than provided comparison date, otherwise returns NO
     *
     *  @param date NSDate - Provided date for comparison
     *
     *  @return BOOL representing comparison result
     */
    -(BOOL)isEarlierThan:(NSDate *)date{
        if (self.timeIntervalSince1970 < date.timeIntervalSince1970) {
            return YES;
        }
        return NO;
    }
    
    /**
     *  Returns a YES if receiver is later than provided comparison date, otherwise returns NO
     *
     *  @param date NSDate - Provided date for comparison
     *
     *  @return BOOL representing comparison result
     */
    -(BOOL)isLaterThan:(NSDate *)date{
        if (self.timeIntervalSince1970 > date.timeIntervalSince1970) {
            return YES;
        }
        return NO;
    }
    
    /**
     *  Returns a YES if receiver is earlier than or equal to the provided comparison date, otherwise returns NO
     *
     *  @param date NSDate - Provided date for comparison
     *
     *  @return BOOL representing comparison result
     */
    -(BOOL)isEarlierThanOrEqualTo:(NSDate *)date{
        if (self.timeIntervalSince1970 <= date.timeIntervalSince1970) {
            return YES;
        }
        return NO;
    }
    
    /**
     *  Returns a YES if receiver is later than or equal to provided comparison date, otherwise returns NO
     *
     *  @param date NSDate - Provided date for comparison
     *
     *  @return BOOL representing comparison result
     */
    -(BOOL)isLaterThanOrEqualTo:(NSDate *)date{
        if (self.timeIntervalSince1970 >= date.timeIntervalSince1970) {
            return YES;
        }
        return NO;
    }
    
    #pragma mark - Formatted Dates
    #pragma mark Formatted With Style
    /**
     *  Convenience method that returns a formatted string representing the receiver's date formatted to a given style
     *
     *  @param style NSDateFormatterStyle - Desired date formatting style
     *
     *  @return NSString representing the formatted date string
     */
    -(NSString *)formattedDateWithStyle:(NSDateFormatterStyle)style{
        return [self formattedDateWithStyle:style timeZone:[NSTimeZone systemTimeZone] locale:[NSLocale autoupdatingCurrentLocale]];
    }
    
    /**
     *  Convenience method that returns a formatted string representing the receiver's date formatted to a given style and time zone
     *
     *  @param style    NSDateFormatterStyle - Desired date formatting style
     *  @param timeZone NSTimeZone - Desired time zone
     *
     *  @return NSString representing the formatted date string
     */
    -(NSString *)formattedDateWithStyle:(NSDateFormatterStyle)style timeZone:(NSTimeZone *)timeZone{
        return [self formattedDateWithStyle:style timeZone:timeZone locale:[NSLocale autoupdatingCurrentLocale]];
    }
    
    /**
     *  Convenience method that returns a formatted string representing the receiver's date formatted to a given style and locale
     *
     *  @param style  NSDateFormatterStyle - Desired date formatting style
     *  @param locale NSLocale - Desired locale
     *
     *  @return NSString representing the formatted date string
     */
    -(NSString *)formattedDateWithStyle:(NSDateFormatterStyle)style locale:(NSLocale *)locale{
        return [self formattedDateWithStyle:style timeZone:[NSTimeZone systemTimeZone] locale:locale];
    }
    
    /**
     *  Convenience method that returns a formatted string representing the receiver's date formatted to a given style, time zone and locale
     *
     *  @param style    NSDateFormatterStyle - Desired date formatting style
     *  @param timeZone NSTimeZone - Desired time zone
     *  @param locale   NSLocale - Desired locale
     *
     *  @return NSString representing the formatted date string
     */
    -(NSString *)formattedDateWithStyle:(NSDateFormatterStyle)style timeZone:(NSTimeZone *)timeZone locale:(NSLocale *)locale{
        static NSDateFormatter *formatter = nil;
        static dispatch_once_t onceToken;
        dispatch_once(&onceToken, ^{
            formatter = [[NSDateFormatter alloc] init];
        });
        
        [formatter setDateStyle:style];
        [formatter setTimeZone:timeZone];
        [formatter setLocale:locale];
        return [formatter stringFromDate:self];
    }
    
    #pragma mark Formatted With Format
    /**
     *  Convenience method that returns a formatted string representing the receiver's date formatted to a given date format
     *
     *  @param format NSString - String representing the desired date format
     *
     *  @return NSString representing the formatted date string
     */
    -(NSString *)formattedDateWithFormat:(NSString *)format{
        return [self formattedDateWithFormat:format timeZone:[NSTimeZone systemTimeZone] locale:[NSLocale autoupdatingCurrentLocale]];
    }
    
    /**
     *  Convenience method that returns a formatted string representing the receiver's date formatted to a given date format and time zone
     *
     *  @param format   NSString - String representing the desired date format
     *  @param timeZone NSTimeZone - Desired time zone
     *
     *  @return NSString representing the formatted date string
     */
    -(NSString *)formattedDateWithFormat:(NSString *)format timeZone:(NSTimeZone *)timeZone{
        return [self formattedDateWithFormat:format timeZone:timeZone locale:[NSLocale autoupdatingCurrentLocale]];
    }
    
    /**
     *  Convenience method that returns a formatted string representing the receiver's date formatted to a given date format and locale
     *
     *  @param format NSString - String representing the desired date format
     *  @param locale NSLocale - Desired locale
     *
     *  @return NSString representing the formatted date string
     */
    -(NSString *)formattedDateWithFormat:(NSString *)format locale:(NSLocale *)locale{
        return [self formattedDateWithFormat:format timeZone:[NSTimeZone systemTimeZone] locale:locale];
    }
    
    /**
     *  Convenience method that returns a formatted string representing the receiver's date formatted to a given date format, time zone and locale
     *
     *  @param format   NSString - String representing the desired date format
     *  @param timeZone NSTimeZone - Desired time zone
     *  @param locale   NSLocale - Desired locale
     *
     *  @return NSString representing the formatted date string
     */
    -(NSString *)formattedDateWithFormat:(NSString *)format timeZone:(NSTimeZone *)timeZone locale:(NSLocale *)locale{
        static NSDateFormatter *formatter = nil;
        static dispatch_once_t onceToken;
        dispatch_once(&onceToken, ^{
            formatter = [[NSDateFormatter alloc] init];
        });
        
        [formatter setDateFormat:format];
        [formatter setTimeZone:timeZone];
        [formatter setLocale:locale];
        return [formatter stringFromDate:self];
    }
    
    #pragma mark - Helpers
    /**
     *  Class method that returns whether the given year is a leap year for the Gregorian Calendar
     *  Returns YES if year is a leap year, otherwise returns NO
     *
     *  @param year NSInteger - Year to evaluate
     *
     *  @return BOOL evaluation of year
     */
    +(BOOL)isLeapYear:(NSInteger)year{
        if (year%400){
            return YES;
        }
        else if (year%100){
            return NO;
        }
        else if (year%4){
            return YES;
        }
        
        return NO;
    }
    
    /**
     *  Retrieves the default calendar identifier used for all non-calendar-specified operations
     *
     *  @return NSString - NSCalendarIdentifier
     */
    +(NSString *)defaultCalendarIdentifier {
        return defaultCalendarIdentifier;
    }
    
    /**
     *  Sets the default calendar identifier used for all non-calendar-specified operations
     *
     *  @param identifier NSString - NSCalendarIdentifier
     */
    + (void)setDefaultCalendarIdentifier:(NSString *)identifier {
        defaultCalendarIdentifier = [identifier copy];
        implicitCalendar = [[NSCalendar alloc] initWithCalendarIdentifier:defaultCalendarIdentifier ?: NSCalendarIdentifierGregorian];
    }
    
    /**
     *  Retrieves a default NSCalendar instance, based on the value of defaultCalendarSetting
     *
     *  @return NSCalendar The current implicit calendar
     */
    + (NSCalendar *)implicitCalendar {
        return implicitCalendar;
    }
    
    @end
    
    

    相关文章

      网友评论

          本文标题:NSDate

          本文链接:https://www.haomeiwen.com/subject/jwqhzctx.html