diff --git a/DistanceOfTimeInWords.xcodeproj/project.pbxproj b/DistanceOfTimeInWords.xcodeproj/project.pbxproj index 1722705..551fbe5 100644 --- a/DistanceOfTimeInWords.xcodeproj/project.pbxproj +++ b/DistanceOfTimeInWords.xcodeproj/project.pbxproj @@ -7,7 +7,8 @@ objects = { /* Begin PBXBuildFile section */ - C701F2681359B29600468818 /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = C701F26A1359B29600468818 /* Localizable.strings */; }; + 5AD7DE05159E2D2C002BD260 /* DistanceOfTimeInWordsLocalizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = C701F26A1359B29600468818 /* DistanceOfTimeInWordsLocalizable.strings */; }; + C701F2681359B29600468818 /* DistanceOfTimeInWordsLocalizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = C701F26A1359B29600468818 /* DistanceOfTimeInWordsLocalizable.strings */; }; C7A88B62135460F2006F686D /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = C7A88B61135460F2006F686D /* UIKit.framework */; }; C7A88B64135460F2006F686D /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = C7A88B63135460F2006F686D /* Foundation.framework */; }; C7A88B66135460F2006F686D /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = C7A88B65135460F2006F686D /* CoreGraphics.framework */; }; @@ -37,9 +38,10 @@ /* End PBXContainerItemProxy section */ /* Begin PBXFileReference section */ - 69EAD0211589E57700975F75 /* zh-Hans */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "zh-Hans"; path = "zh-Hans.lproj/Localizable.strings"; sourceTree = ""; }; - C701F2691359B29600468818 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/Localizable.strings; sourceTree = ""; }; - C701F26B1359B2AA00468818 /* es */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = es; path = es.lproj/Localizable.strings; sourceTree = ""; }; + 5AD7DE04159E2D2C002BD260 /* pt */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = pt; path = pt.lproj/DistanceOfTimeInWordsLocalizable.strings; sourceTree = ""; }; + 69EAD0211589E57700975F75 /* zh-Hans */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "zh-Hans"; path = "zh-Hans.lproj/DistanceOfTimeInWordsLocalizable.strings"; sourceTree = ""; }; + C701F2691359B29600468818 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/DistanceOfTimeInWordsLocalizable.strings; sourceTree = ""; }; + C701F26B1359B2AA00468818 /* es */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = es; path = es.lproj/DistanceOfTimeInWordsLocalizable.strings; sourceTree = ""; }; C7A88B5D135460F2006F686D /* DistanceOfTimeInWords.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = DistanceOfTimeInWords.app; sourceTree = BUILT_PRODUCTS_DIR; }; C7A88B61135460F2006F686D /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; }; C7A88B63135460F2006F686D /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; @@ -140,7 +142,7 @@ C7A88B6A135460F2006F686D /* InfoPlist.strings */, C7A88B6D135460F2006F686D /* DistanceOfTimeInWords-Prefix.pch */, C7A88B6E135460F2006F686D /* main.m */, - C701F26A1359B29600468818 /* Localizable.strings */, + C701F26A1359B29600468818 /* DistanceOfTimeInWordsLocalizable.strings */, ); name = "Supporting Files"; sourceTree = ""; @@ -210,7 +212,6 @@ C7A88B54135460F2006F686D /* Project object */ = { isa = PBXProject; attributes = { - LastUpgradeCheck = 0430; ORGANIZATIONNAME = Grailbox; }; buildConfigurationList = C7A88B57135460F2006F686D /* Build configuration list for PBXProject "DistanceOfTimeInWords" */; @@ -221,6 +222,7 @@ en, es, "zh-Hans", + pt, ); mainGroup = C7A88B52135460F2006F686D; productRefGroup = C7A88B5E135460F2006F686D /* Products */; @@ -241,7 +243,8 @@ C7A88B6C135460F2006F686D /* InfoPlist.strings in Resources */, C7A88B75135460F2006F686D /* MainWindow.xib in Resources */, C7A88B7B135460F2006F686D /* DistanceOfTimeInWordsViewController.xib in Resources */, - C701F2681359B29600468818 /* Localizable.strings in Resources */, + C701F2681359B29600468818 /* DistanceOfTimeInWordsLocalizable.strings in Resources */, + 5AD7DE05159E2D2C002BD260 /* DistanceOfTimeInWordsLocalizable.strings in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -303,14 +306,15 @@ /* End PBXTargetDependency section */ /* Begin PBXVariantGroup section */ - C701F26A1359B29600468818 /* Localizable.strings */ = { + C701F26A1359B29600468818 /* DistanceOfTimeInWordsLocalizable.strings */ = { isa = PBXVariantGroup; children = ( C701F2691359B29600468818 /* en */, C701F26B1359B2AA00468818 /* es */, 69EAD0211589E57700975F75 /* zh-Hans */, + 5AD7DE04159E2D2C002BD260 /* pt */, ); - name = Localizable.strings; + name = DistanceOfTimeInWordsLocalizable.strings; sourceTree = ""; }; C7A88B6A135460F2006F686D /* InfoPlist.strings */ = { @@ -388,7 +392,6 @@ GCC_DYNAMIC_NO_PIC = NO; GCC_PRECOMPILE_PREFIX_HEADER = YES; GCC_PREFIX_HEADER = "DistanceOfTimeInWords/DistanceOfTimeInWords-Prefix.pch"; - GCC_VERSION = com.apple.compilers.llvm.clang.1_0; INFOPLIST_FILE = "DistanceOfTimeInWords/DistanceOfTimeInWords-Info.plist"; PRODUCT_NAME = "$(TARGET_NAME)"; WRAPPER_EXTENSION = app; @@ -402,7 +405,6 @@ COPY_PHASE_STRIP = YES; GCC_PRECOMPILE_PREFIX_HEADER = YES; GCC_PREFIX_HEADER = "DistanceOfTimeInWords/DistanceOfTimeInWords-Prefix.pch"; - GCC_VERSION = com.apple.compilers.llvm.clang.1_0; INFOPLIST_FILE = "DistanceOfTimeInWords/DistanceOfTimeInWords-Info.plist"; PRODUCT_NAME = "$(TARGET_NAME)"; VALIDATE_PRODUCT = YES; @@ -421,7 +423,6 @@ ); GCC_PRECOMPILE_PREFIX_HEADER = YES; GCC_PREFIX_HEADER = "DistanceOfTimeInWordsTests/DistanceOfTimeInWordsTests-Prefix.pch"; - GCC_VERSION = com.apple.compilers.llvm.clang.1_0; INFOPLIST_FILE = "DistanceOfTimeInWordsTests/DistanceOfTimeInWordsTests-Info.plist"; OTHER_LDFLAGS = ( "-framework", @@ -444,7 +445,6 @@ ); GCC_PRECOMPILE_PREFIX_HEADER = YES; GCC_PREFIX_HEADER = "DistanceOfTimeInWordsTests/DistanceOfTimeInWordsTests-Prefix.pch"; - GCC_VERSION = com.apple.compilers.llvm.clang.1_0; INFOPLIST_FILE = "DistanceOfTimeInWordsTests/DistanceOfTimeInWordsTests-Info.plist"; OTHER_LDFLAGS = ( "-framework", diff --git a/DistanceOfTimeInWords/NSDate+Formatting.h b/DistanceOfTimeInWords/NSDate+Formatting.h index 5af69ca..6c2a897 100644 --- a/DistanceOfTimeInWords/NSDate+Formatting.h +++ b/DistanceOfTimeInWords/NSDate+Formatting.h @@ -20,6 +20,15 @@ #import +// +// Distance of time in words to string components. +typedef enum DistanceOfTimeInWordsStringComponents { + kDOTIWStringComponentModifier = 1, // 00001 in binary. + kDOTIWStringComponentNumber = 2, // 00010 in binary. + kDOTIWStringComponentMeasure = 4, // 00100 in binary. + kDOTIWStringComponentDirection = 8, // 01000 in binary. + kDOTIWStringComponentJustNow = 16, // 10000 in binary (Disabled by default.) +} DistanceOfTimeInWordsStringComponents; @interface NSDate (formatting) @@ -28,4 +37,7 @@ - (NSString *)distanceOfTimeInWords; - (NSString *)distanceOfTimeInWords:(NSDate *)date; +- (NSString *)distanceOfTimeInWordsWithOptions:(NSUInteger)options; +- (NSString *)distanceOfTimeInWords:(NSDate *)date withOptions:(NSUInteger)options; + @end diff --git a/DistanceOfTimeInWords/NSDate+Formatting.m b/DistanceOfTimeInWords/NSDate+Formatting.m index e3e869b..be23a14 100644 --- a/DistanceOfTimeInWords/NSDate+Formatting.m +++ b/DistanceOfTimeInWords/NSDate+Formatting.m @@ -21,11 +21,14 @@ #import "NSDate+Formatting.h" -#define SECONDS_PER_MINUTE 60.0 -#define SECONDS_PER_HOUR 3600.0 -#define SECONDS_PER_DAY 86400.0 -#define SECONDS_PER_MONTH 2592000.0 -#define SECONDS_PER_YEAR 31536000.0 +#define SECONDS_JUST_NOW_LIMIT 5.0 +#define SECONDS_PER_MINUTE 60.0 +#define SECONDS_PER_HOUR 3600.0 +#define SECONDS_PER_DAY 86400.0 +#define SECONDS_PER_MONTH 2592000.0 +#define SECONDS_PER_YEAR 31536000.0 + +#define LOCALIZED_STRING_TABLE_NAME @"DistanceOfTimeInWordsLocalizable" @implementation NSDate (formatting) @@ -50,24 +53,44 @@ - (NSString *)distanceOfTimeInWords { } - (NSString *)distanceOfTimeInWords:(NSDate *)date { - NSString *Ago = NSLocalizedString(@"ago", @"Denotes past dates"); - NSString *FromNow = NSLocalizedString(@"from now", @"Denotes future dates"); - NSString *LessThan = NSLocalizedString(@"Less than", @"Indicates a less-than number"); - NSString *About = NSLocalizedString(@"About", @"Indicates an approximate number"); - NSString *Over = NSLocalizedString(@"Over", @"Indicates an exceeding number"); - NSString *Almost = NSLocalizedString(@"Almost", @"Indicates an approaching number"); - //NSString *Second = NSLocalizedString(@"second", @"One second in time"); - NSString *Seconds = NSLocalizedString(@"seconds", @"More than one second in time"); - NSString *Minute = NSLocalizedString(@"minute", @"One minute in time"); - NSString *Minutes = NSLocalizedString(@"minutes", @"More than one minute in time"); - NSString *Hour = NSLocalizedString(@"hour", @"One hour in time"); - NSString *Hours = NSLocalizedString(@"hours", @"More than one hour in time"); - NSString *Day = NSLocalizedString(@"day", @"One day in time"); - NSString *Days = NSLocalizedString(@"days", @"More than one day in time"); - NSString *Month = NSLocalizedString(@"month", @"One month in time"); - NSString *Months = NSLocalizedString(@"months", @"More than one month in time"); - NSString *Year = NSLocalizedString(@"year", @"One year in time"); - NSString *Years = NSLocalizedString(@"years", @"More than one year in time"); + + NSUInteger allOptionsEnabledByDefault = + kDOTIWStringComponentModifier | + kDOTIWStringComponentNumber | + kDOTIWStringComponentMeasure | + kDOTIWStringComponentDirection; + + return [self distanceOfTimeInWords:date withOptions:allOptionsEnabledByDefault]; +} + +- (NSString *)distanceOfTimeInWordsWithOptions:(NSUInteger)options { + return [self distanceOfTimeInWords:[NSDate date] withOptions:options]; +} + +- (NSString *)distanceOfTimeInWords:(NSDate *)date withOptions:(NSUInteger)options { + + if (options & kDOTIWStringComponentJustNow) + if (fabs([self timeIntervalSinceDate:date]) < SECONDS_JUST_NOW_LIMIT) + return NSLocalizedStringFromTable(@"Just now", LOCALIZED_STRING_TABLE_NAME, @"Indicates a recent action"); + + NSString *Ago = NSLocalizedStringFromTable(@"ago", LOCALIZED_STRING_TABLE_NAME, @"Denotes past dates"); + NSString *FromNow = NSLocalizedStringFromTable(@"from now", LOCALIZED_STRING_TABLE_NAME, @"Denotes future dates"); + NSString *LessThan = NSLocalizedStringFromTable(@"Less than", LOCALIZED_STRING_TABLE_NAME, @"Indicates a less-than number"); + NSString *About = NSLocalizedStringFromTable(@"About", LOCALIZED_STRING_TABLE_NAME, @"Indicates an approximate number"); + NSString *Over = NSLocalizedStringFromTable(@"Over", LOCALIZED_STRING_TABLE_NAME, @"Indicates an exceeding number"); + NSString *Almost = NSLocalizedStringFromTable(@"Almost", LOCALIZED_STRING_TABLE_NAME, @"Indicates an approaching number"); + //NSString *Second = NSLocalizedStringFromTable(@"second", LOCALIZED_STRING_TABLE_NAME, @"One second in time"); + NSString *Seconds = NSLocalizedStringFromTable(@"seconds", LOCALIZED_STRING_TABLE_NAME, @"More than one second in time"); + NSString *Minute = NSLocalizedStringFromTable(@"minute", LOCALIZED_STRING_TABLE_NAME, @"One minute in time"); + NSString *Minutes = NSLocalizedStringFromTable(@"minutes", LOCALIZED_STRING_TABLE_NAME, @"More than one minute in time"); + NSString *Hour = NSLocalizedStringFromTable(@"hour", LOCALIZED_STRING_TABLE_NAME, @"One hour in time"); + NSString *Hours = NSLocalizedStringFromTable(@"hours", LOCALIZED_STRING_TABLE_NAME, @"More than one hour in time"); + NSString *Day = NSLocalizedStringFromTable(@"day", LOCALIZED_STRING_TABLE_NAME, @"One day in time"); + NSString *Days = NSLocalizedStringFromTable(@"days", LOCALIZED_STRING_TABLE_NAME, @"More than one day in time"); + NSString *Month = NSLocalizedStringFromTable(@"month", LOCALIZED_STRING_TABLE_NAME, @"One month in time"); + NSString *Months = NSLocalizedStringFromTable(@"months", LOCALIZED_STRING_TABLE_NAME, @"More than one month in time"); + NSString *Year = NSLocalizedStringFromTable(@"year", LOCALIZED_STRING_TABLE_NAME, @"One year in time"); + NSString *Years = NSLocalizedStringFromTable(@"years", LOCALIZED_STRING_TABLE_NAME, @"More than one year in time"); NSTimeInterval since = [self timeIntervalSinceDate:date]; NSString *direction = since <= 0.0 ? Ago : FromNow; @@ -166,7 +189,19 @@ - (NSString *)distanceOfTimeInWords:(NSDate *)date { if ([modifier length] > 0) { modifier = [modifier stringByAppendingString:@" "]; } - return [NSString stringWithFormat:@"%@%d %@ %@", modifier, number, measure, direction]; + + NSMutableString *resultString = [NSMutableString string]; + + if (options & kDOTIWStringComponentModifier) + [resultString appendString:[NSString stringWithFormat:@"%@", modifier]]; + if (options & kDOTIWStringComponentNumber) + [resultString appendString:[NSString stringWithFormat:@"%d", number]]; + if (options & kDOTIWStringComponentMeasure) + [resultString appendString:[NSString stringWithFormat:@" %@", measure]]; + if (options & kDOTIWStringComponentDirection) + [resultString appendString:[NSString stringWithFormat:@" %@", direction]]; + + return resultString; } @end diff --git a/DistanceOfTimeInWords/en.lproj/Localizable.strings b/DistanceOfTimeInWords/en.lproj/DistanceOfTimeInWordsLocalizable.strings similarity index 90% rename from DistanceOfTimeInWords/en.lproj/Localizable.strings rename to DistanceOfTimeInWords/en.lproj/DistanceOfTimeInWordsLocalizable.strings index 538e292..a5f42f0 100644 Binary files a/DistanceOfTimeInWords/en.lproj/Localizable.strings and b/DistanceOfTimeInWords/en.lproj/DistanceOfTimeInWordsLocalizable.strings differ diff --git a/DistanceOfTimeInWords/es.lproj/Localizable.strings b/DistanceOfTimeInWords/es.lproj/DistanceOfTimeInWordsLocalizable.strings similarity index 90% rename from DistanceOfTimeInWords/es.lproj/Localizable.strings rename to DistanceOfTimeInWords/es.lproj/DistanceOfTimeInWordsLocalizable.strings index f48ab45..9bf6e50 100644 Binary files a/DistanceOfTimeInWords/es.lproj/Localizable.strings and b/DistanceOfTimeInWords/es.lproj/DistanceOfTimeInWordsLocalizable.strings differ diff --git a/DistanceOfTimeInWords/pt.lproj/DistanceOfTimeInWordsLocalizable.strings b/DistanceOfTimeInWords/pt.lproj/DistanceOfTimeInWordsLocalizable.strings new file mode 100644 index 0000000..d94298b Binary files /dev/null and b/DistanceOfTimeInWords/pt.lproj/DistanceOfTimeInWordsLocalizable.strings differ diff --git a/DistanceOfTimeInWords/zh-Hans.lproj/Localizable.strings b/DistanceOfTimeInWords/zh-Hans.lproj/DistanceOfTimeInWordsLocalizable.strings similarity index 89% rename from DistanceOfTimeInWords/zh-Hans.lproj/Localizable.strings rename to DistanceOfTimeInWords/zh-Hans.lproj/DistanceOfTimeInWordsLocalizable.strings index da8dd57..ec8ba26 100644 Binary files a/DistanceOfTimeInWords/zh-Hans.lproj/Localizable.strings and b/DistanceOfTimeInWords/zh-Hans.lproj/DistanceOfTimeInWordsLocalizable.strings differ diff --git a/README.md b/README.md index 1292ccb..7bd5d2f 100644 --- a/README.md +++ b/README.md @@ -44,6 +44,41 @@ The next two relate to each other. Calling `distanceOfTimeInWords` with no param * `[[NSDate date] distanceOfTimeInWords];` * `[[NSDate date] distanceOfTimeInWords:[[NSDate date] dateByAddingTimeInterval:86400]];` +Formatting date strings +---------------------------- +These two methods are now available for formatting resulting date strings: + +* `- (NSString *)distanceOfTimeInWordsWithOptions:(NSUInteger)options;` +* `- (NSString *)distanceOfTimeInWords:(NSDate *)date withOptions:(NSUInteger)options;` + +Both presented methods are accepting a bitmask formed with the following options: + +- kDOTIWStringComponentModifier; +- kDOTIWStringComponentNumber; +- kDOTIWStringComponentMeasure; +- kDOTIWStringComponentDirection; +- kDOTIWStringComponentJustNow; `Disabled by default.` + +For instance: + + [[NSDate date] distanceOfTimeInWords]; + +Results "`Less than 5 seconds ago`". + + NSUInteger dotiwOptions = kDOTIWStringComponentNumber | kDOTIWStringComponentMeasure; + + [[NSDate date] distanceOfTimeInWordsWithOptions:dotiwOptions] + +Results "`5 seconds`". + + dotiwOptions = kDOTIWStringComponentNumber | kDOTIWStringComponentMeasure | kDOTIWStringComponentJustNow; + + [[NSDate date] distanceOfTimeInWordsWithOptions:dotiwOptions] + + [[NSDate dateWithTimeInterval:10.0 sinceDate:oldDate] distanceOfTimeInWords:oldDate withOptions:options]; + +Results "`Just now`" for the first call and "`10 seconds`" for the second call (i.e., the `kDOTIWStringComponentJustNow` component overrides others while the time interval between the defined dates (e.g. the received date and oldDate) is smaller than 5 (five) seconds). + Localization ------------ -`NSDate+Formatting` uses localized strings, so if you localize your app and provide strings for all that `NSDate+Formatting` uses, your returned string will be localized. The app provides both english and Spanish localizations. +`NSDate+Formatting` uses localized strings, so if you localize your app and provide strings for all that `NSDate+Formatting` uses, your returned string will be localized. The app provides English, Spanish, Chinese and Portuguese localizations.