├── LICENSE.md ├── NSDate_Extensions.xcodeproj ├── project.pbxproj └── project.xcworkspace │ └── contents.xcworkspacedata ├── NSDate_Extensions ├── AppDelegate.swift ├── Base.lproj │ ├── LaunchScreen.xib │ └── Main.storyboard ├── Images.xcassets │ └── AppIcon.appiconset │ │ └── Contents.json ├── Info.plist ├── NSDate+Comparable.swift ├── NSDate+Count.swift ├── NSDate+Main.swift ├── NSDate+Periods.swift └── ViewController.swift ├── NSDate_ExtensionsTests ├── Info.plist └── NSDate_ExtensionsTests.swift └── README.md /LICENSE.md: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2016 Joe Christopher Paul Amanse 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /NSDate_Extensions.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | DF5FA97C1B031C1A00EFDA42 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = DF5FA97B1B031C1A00EFDA42 /* AppDelegate.swift */; }; 11 | DF5FA97E1B031C1A00EFDA42 /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = DF5FA97D1B031C1A00EFDA42 /* ViewController.swift */; }; 12 | DF5FA9811B031C1A00EFDA42 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = DF5FA97F1B031C1A00EFDA42 /* Main.storyboard */; }; 13 | DF5FA9831B031C1A00EFDA42 /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = DF5FA9821B031C1A00EFDA42 /* Images.xcassets */; }; 14 | DF5FA9861B031C1A00EFDA42 /* LaunchScreen.xib in Resources */ = {isa = PBXBuildFile; fileRef = DF5FA9841B031C1A00EFDA42 /* LaunchScreen.xib */; }; 15 | DF5FA9921B031C1A00EFDA42 /* NSDate_ExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = DF5FA9911B031C1A00EFDA42 /* NSDate_ExtensionsTests.swift */; }; 16 | DF5FA99C1B031C9100EFDA42 /* NSDate+Main.swift in Sources */ = {isa = PBXBuildFile; fileRef = DF5FA99B1B031C9100EFDA42 /* NSDate+Main.swift */; }; 17 | DF5FA99F1B031E1100EFDA42 /* NSDate+Comparable.swift in Sources */ = {isa = PBXBuildFile; fileRef = DF5FA99E1B031E1000EFDA42 /* NSDate+Comparable.swift */; }; 18 | DF5FA9A11B031E9C00EFDA42 /* NSDate+Periods.swift in Sources */ = {isa = PBXBuildFile; fileRef = DF5FA9A01B031E9C00EFDA42 /* NSDate+Periods.swift */; }; 19 | DF789A4C1B03CBF000F16AA7 /* NSDate+Count.swift in Sources */ = {isa = PBXBuildFile; fileRef = DF789A4B1B03CBF000F16AA7 /* NSDate+Count.swift */; }; 20 | /* End PBXBuildFile section */ 21 | 22 | /* Begin PBXContainerItemProxy section */ 23 | DF5FA98C1B031C1A00EFDA42 /* PBXContainerItemProxy */ = { 24 | isa = PBXContainerItemProxy; 25 | containerPortal = DF5FA96E1B031C1900EFDA42 /* Project object */; 26 | proxyType = 1; 27 | remoteGlobalIDString = DF5FA9751B031C1900EFDA42; 28 | remoteInfo = NSDate_Extensions; 29 | }; 30 | /* End PBXContainerItemProxy section */ 31 | 32 | /* Begin PBXFileReference section */ 33 | DF5FA9761B031C1900EFDA42 /* NSDate_Extensions.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = NSDate_Extensions.app; sourceTree = BUILT_PRODUCTS_DIR; }; 34 | DF5FA97A1B031C1A00EFDA42 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 35 | DF5FA97B1B031C1A00EFDA42 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; 36 | DF5FA97D1B031C1A00EFDA42 /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = ""; }; 37 | DF5FA9801B031C1A00EFDA42 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; 38 | DF5FA9821B031C1A00EFDA42 /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = ""; }; 39 | DF5FA9851B031C1A00EFDA42 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/LaunchScreen.xib; sourceTree = ""; }; 40 | DF5FA98B1B031C1A00EFDA42 /* NSDate_ExtensionsTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = NSDate_ExtensionsTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 41 | DF5FA9901B031C1A00EFDA42 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 42 | DF5FA9911B031C1A00EFDA42 /* NSDate_ExtensionsTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NSDate_ExtensionsTests.swift; sourceTree = ""; }; 43 | DF5FA99B1B031C9100EFDA42 /* NSDate+Main.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "NSDate+Main.swift"; sourceTree = ""; }; 44 | DF5FA99E1B031E1000EFDA42 /* NSDate+Comparable.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "NSDate+Comparable.swift"; sourceTree = ""; }; 45 | DF5FA9A01B031E9C00EFDA42 /* NSDate+Periods.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "NSDate+Periods.swift"; sourceTree = ""; }; 46 | DF789A4B1B03CBF000F16AA7 /* NSDate+Count.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "NSDate+Count.swift"; sourceTree = ""; }; 47 | DF789A4D1B03DB2100F16AA7 /* README.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; path = README.md; sourceTree = ""; }; 48 | DF789A4E1B03DB3700F16AA7 /* LICENSE.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; path = LICENSE.md; sourceTree = ""; }; 49 | /* End PBXFileReference section */ 50 | 51 | /* Begin PBXFrameworksBuildPhase section */ 52 | DF5FA9731B031C1900EFDA42 /* Frameworks */ = { 53 | isa = PBXFrameworksBuildPhase; 54 | buildActionMask = 2147483647; 55 | files = ( 56 | ); 57 | runOnlyForDeploymentPostprocessing = 0; 58 | }; 59 | DF5FA9881B031C1A00EFDA42 /* Frameworks */ = { 60 | isa = PBXFrameworksBuildPhase; 61 | buildActionMask = 2147483647; 62 | files = ( 63 | ); 64 | runOnlyForDeploymentPostprocessing = 0; 65 | }; 66 | /* End PBXFrameworksBuildPhase section */ 67 | 68 | /* Begin PBXGroup section */ 69 | DF5FA96D1B031C1900EFDA42 = { 70 | isa = PBXGroup; 71 | children = ( 72 | DF789A4E1B03DB3700F16AA7 /* LICENSE.md */, 73 | DF789A4D1B03DB2100F16AA7 /* README.md */, 74 | DF5FA9781B031C1900EFDA42 /* NSDate_Extensions */, 75 | DF5FA98E1B031C1A00EFDA42 /* NSDate_ExtensionsTests */, 76 | DF5FA9771B031C1900EFDA42 /* Products */, 77 | ); 78 | sourceTree = ""; 79 | }; 80 | DF5FA9771B031C1900EFDA42 /* Products */ = { 81 | isa = PBXGroup; 82 | children = ( 83 | DF5FA9761B031C1900EFDA42 /* NSDate_Extensions.app */, 84 | DF5FA98B1B031C1A00EFDA42 /* NSDate_ExtensionsTests.xctest */, 85 | ); 86 | name = Products; 87 | sourceTree = ""; 88 | }; 89 | DF5FA9781B031C1900EFDA42 /* NSDate_Extensions */ = { 90 | isa = PBXGroup; 91 | children = ( 92 | DF5FA97B1B031C1A00EFDA42 /* AppDelegate.swift */, 93 | DF5FA99D1B031CD200EFDA42 /* NSDate+Utilities */, 94 | DF5FA97D1B031C1A00EFDA42 /* ViewController.swift */, 95 | DF5FA97F1B031C1A00EFDA42 /* Main.storyboard */, 96 | DF5FA9821B031C1A00EFDA42 /* Images.xcassets */, 97 | DF5FA9841B031C1A00EFDA42 /* LaunchScreen.xib */, 98 | DF5FA9791B031C1A00EFDA42 /* Supporting Files */, 99 | ); 100 | path = NSDate_Extensions; 101 | sourceTree = ""; 102 | }; 103 | DF5FA9791B031C1A00EFDA42 /* Supporting Files */ = { 104 | isa = PBXGroup; 105 | children = ( 106 | DF5FA97A1B031C1A00EFDA42 /* Info.plist */, 107 | ); 108 | name = "Supporting Files"; 109 | sourceTree = ""; 110 | }; 111 | DF5FA98E1B031C1A00EFDA42 /* NSDate_ExtensionsTests */ = { 112 | isa = PBXGroup; 113 | children = ( 114 | DF5FA9911B031C1A00EFDA42 /* NSDate_ExtensionsTests.swift */, 115 | DF5FA98F1B031C1A00EFDA42 /* Supporting Files */, 116 | ); 117 | path = NSDate_ExtensionsTests; 118 | sourceTree = ""; 119 | }; 120 | DF5FA98F1B031C1A00EFDA42 /* Supporting Files */ = { 121 | isa = PBXGroup; 122 | children = ( 123 | DF5FA9901B031C1A00EFDA42 /* Info.plist */, 124 | ); 125 | name = "Supporting Files"; 126 | sourceTree = ""; 127 | }; 128 | DF5FA99D1B031CD200EFDA42 /* NSDate+Utilities */ = { 129 | isa = PBXGroup; 130 | children = ( 131 | DF5FA99B1B031C9100EFDA42 /* NSDate+Main.swift */, 132 | DF5FA99E1B031E1000EFDA42 /* NSDate+Comparable.swift */, 133 | DF5FA9A01B031E9C00EFDA42 /* NSDate+Periods.swift */, 134 | DF789A4B1B03CBF000F16AA7 /* NSDate+Count.swift */, 135 | ); 136 | name = "NSDate+Utilities"; 137 | sourceTree = ""; 138 | }; 139 | /* End PBXGroup section */ 140 | 141 | /* Begin PBXNativeTarget section */ 142 | DF5FA9751B031C1900EFDA42 /* NSDate_Extensions */ = { 143 | isa = PBXNativeTarget; 144 | buildConfigurationList = DF5FA9951B031C1A00EFDA42 /* Build configuration list for PBXNativeTarget "NSDate_Extensions" */; 145 | buildPhases = ( 146 | DF5FA9721B031C1900EFDA42 /* Sources */, 147 | DF5FA9731B031C1900EFDA42 /* Frameworks */, 148 | DF5FA9741B031C1900EFDA42 /* Resources */, 149 | ); 150 | buildRules = ( 151 | ); 152 | dependencies = ( 153 | ); 154 | name = NSDate_Extensions; 155 | productName = NSDate_Extensions; 156 | productReference = DF5FA9761B031C1900EFDA42 /* NSDate_Extensions.app */; 157 | productType = "com.apple.product-type.application"; 158 | }; 159 | DF5FA98A1B031C1A00EFDA42 /* NSDate_ExtensionsTests */ = { 160 | isa = PBXNativeTarget; 161 | buildConfigurationList = DF5FA9981B031C1A00EFDA42 /* Build configuration list for PBXNativeTarget "NSDate_ExtensionsTests" */; 162 | buildPhases = ( 163 | DF5FA9871B031C1A00EFDA42 /* Sources */, 164 | DF5FA9881B031C1A00EFDA42 /* Frameworks */, 165 | DF5FA9891B031C1A00EFDA42 /* Resources */, 166 | ); 167 | buildRules = ( 168 | ); 169 | dependencies = ( 170 | DF5FA98D1B031C1A00EFDA42 /* PBXTargetDependency */, 171 | ); 172 | name = NSDate_ExtensionsTests; 173 | productName = NSDate_ExtensionsTests; 174 | productReference = DF5FA98B1B031C1A00EFDA42 /* NSDate_ExtensionsTests.xctest */; 175 | productType = "com.apple.product-type.bundle.unit-test"; 176 | }; 177 | /* End PBXNativeTarget section */ 178 | 179 | /* Begin PBXProject section */ 180 | DF5FA96E1B031C1900EFDA42 /* Project object */ = { 181 | isa = PBXProject; 182 | attributes = { 183 | LastSwiftMigration = 0730; 184 | LastSwiftUpdateCheck = 0730; 185 | LastUpgradeCheck = 0630; 186 | ORGANIZATIONNAME = "Joe Christopher Paul Amanse"; 187 | TargetAttributes = { 188 | DF5FA9751B031C1900EFDA42 = { 189 | CreatedOnToolsVersion = 6.3.1; 190 | }; 191 | DF5FA98A1B031C1A00EFDA42 = { 192 | CreatedOnToolsVersion = 6.3.1; 193 | TestTargetID = DF5FA9751B031C1900EFDA42; 194 | }; 195 | }; 196 | }; 197 | buildConfigurationList = DF5FA9711B031C1900EFDA42 /* Build configuration list for PBXProject "NSDate_Extensions" */; 198 | compatibilityVersion = "Xcode 3.2"; 199 | developmentRegion = English; 200 | hasScannedForEncodings = 0; 201 | knownRegions = ( 202 | en, 203 | Base, 204 | ); 205 | mainGroup = DF5FA96D1B031C1900EFDA42; 206 | productRefGroup = DF5FA9771B031C1900EFDA42 /* Products */; 207 | projectDirPath = ""; 208 | projectRoot = ""; 209 | targets = ( 210 | DF5FA9751B031C1900EFDA42 /* NSDate_Extensions */, 211 | DF5FA98A1B031C1A00EFDA42 /* NSDate_ExtensionsTests */, 212 | ); 213 | }; 214 | /* End PBXProject section */ 215 | 216 | /* Begin PBXResourcesBuildPhase section */ 217 | DF5FA9741B031C1900EFDA42 /* Resources */ = { 218 | isa = PBXResourcesBuildPhase; 219 | buildActionMask = 2147483647; 220 | files = ( 221 | DF5FA9811B031C1A00EFDA42 /* Main.storyboard in Resources */, 222 | DF5FA9861B031C1A00EFDA42 /* LaunchScreen.xib in Resources */, 223 | DF5FA9831B031C1A00EFDA42 /* Images.xcassets in Resources */, 224 | ); 225 | runOnlyForDeploymentPostprocessing = 0; 226 | }; 227 | DF5FA9891B031C1A00EFDA42 /* Resources */ = { 228 | isa = PBXResourcesBuildPhase; 229 | buildActionMask = 2147483647; 230 | files = ( 231 | ); 232 | runOnlyForDeploymentPostprocessing = 0; 233 | }; 234 | /* End PBXResourcesBuildPhase section */ 235 | 236 | /* Begin PBXSourcesBuildPhase section */ 237 | DF5FA9721B031C1900EFDA42 /* Sources */ = { 238 | isa = PBXSourcesBuildPhase; 239 | buildActionMask = 2147483647; 240 | files = ( 241 | DF789A4C1B03CBF000F16AA7 /* NSDate+Count.swift in Sources */, 242 | DF5FA97E1B031C1A00EFDA42 /* ViewController.swift in Sources */, 243 | DF5FA97C1B031C1A00EFDA42 /* AppDelegate.swift in Sources */, 244 | DF5FA9A11B031E9C00EFDA42 /* NSDate+Periods.swift in Sources */, 245 | DF5FA99F1B031E1100EFDA42 /* NSDate+Comparable.swift in Sources */, 246 | DF5FA99C1B031C9100EFDA42 /* NSDate+Main.swift in Sources */, 247 | ); 248 | runOnlyForDeploymentPostprocessing = 0; 249 | }; 250 | DF5FA9871B031C1A00EFDA42 /* Sources */ = { 251 | isa = PBXSourcesBuildPhase; 252 | buildActionMask = 2147483647; 253 | files = ( 254 | DF5FA9921B031C1A00EFDA42 /* NSDate_ExtensionsTests.swift in Sources */, 255 | ); 256 | runOnlyForDeploymentPostprocessing = 0; 257 | }; 258 | /* End PBXSourcesBuildPhase section */ 259 | 260 | /* Begin PBXTargetDependency section */ 261 | DF5FA98D1B031C1A00EFDA42 /* PBXTargetDependency */ = { 262 | isa = PBXTargetDependency; 263 | target = DF5FA9751B031C1900EFDA42 /* NSDate_Extensions */; 264 | targetProxy = DF5FA98C1B031C1A00EFDA42 /* PBXContainerItemProxy */; 265 | }; 266 | /* End PBXTargetDependency section */ 267 | 268 | /* Begin PBXVariantGroup section */ 269 | DF5FA97F1B031C1A00EFDA42 /* Main.storyboard */ = { 270 | isa = PBXVariantGroup; 271 | children = ( 272 | DF5FA9801B031C1A00EFDA42 /* Base */, 273 | ); 274 | name = Main.storyboard; 275 | sourceTree = ""; 276 | }; 277 | DF5FA9841B031C1A00EFDA42 /* LaunchScreen.xib */ = { 278 | isa = PBXVariantGroup; 279 | children = ( 280 | DF5FA9851B031C1A00EFDA42 /* Base */, 281 | ); 282 | name = LaunchScreen.xib; 283 | sourceTree = ""; 284 | }; 285 | /* End PBXVariantGroup section */ 286 | 287 | /* Begin XCBuildConfiguration section */ 288 | DF5FA9931B031C1A00EFDA42 /* Debug */ = { 289 | isa = XCBuildConfiguration; 290 | buildSettings = { 291 | ALWAYS_SEARCH_USER_PATHS = NO; 292 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 293 | CLANG_CXX_LIBRARY = "libc++"; 294 | CLANG_ENABLE_MODULES = YES; 295 | CLANG_ENABLE_OBJC_ARC = YES; 296 | CLANG_WARN_BOOL_CONVERSION = YES; 297 | CLANG_WARN_CONSTANT_CONVERSION = YES; 298 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 299 | CLANG_WARN_EMPTY_BODY = YES; 300 | CLANG_WARN_ENUM_CONVERSION = YES; 301 | CLANG_WARN_INT_CONVERSION = YES; 302 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 303 | CLANG_WARN_UNREACHABLE_CODE = YES; 304 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 305 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 306 | COPY_PHASE_STRIP = NO; 307 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 308 | ENABLE_STRICT_OBJC_MSGSEND = YES; 309 | GCC_C_LANGUAGE_STANDARD = gnu99; 310 | GCC_DYNAMIC_NO_PIC = NO; 311 | GCC_NO_COMMON_BLOCKS = YES; 312 | GCC_OPTIMIZATION_LEVEL = 0; 313 | GCC_PREPROCESSOR_DEFINITIONS = ( 314 | "DEBUG=1", 315 | "$(inherited)", 316 | ); 317 | GCC_SYMBOLS_PRIVATE_EXTERN = NO; 318 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 319 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 320 | GCC_WARN_UNDECLARED_SELECTOR = YES; 321 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 322 | GCC_WARN_UNUSED_FUNCTION = YES; 323 | GCC_WARN_UNUSED_VARIABLE = YES; 324 | IPHONEOS_DEPLOYMENT_TARGET = 8.3; 325 | MTL_ENABLE_DEBUG_INFO = YES; 326 | ONLY_ACTIVE_ARCH = YES; 327 | SDKROOT = iphoneos; 328 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 329 | TARGETED_DEVICE_FAMILY = "1,2"; 330 | }; 331 | name = Debug; 332 | }; 333 | DF5FA9941B031C1A00EFDA42 /* Release */ = { 334 | isa = XCBuildConfiguration; 335 | buildSettings = { 336 | ALWAYS_SEARCH_USER_PATHS = NO; 337 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 338 | CLANG_CXX_LIBRARY = "libc++"; 339 | CLANG_ENABLE_MODULES = YES; 340 | CLANG_ENABLE_OBJC_ARC = YES; 341 | CLANG_WARN_BOOL_CONVERSION = YES; 342 | CLANG_WARN_CONSTANT_CONVERSION = YES; 343 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 344 | CLANG_WARN_EMPTY_BODY = YES; 345 | CLANG_WARN_ENUM_CONVERSION = YES; 346 | CLANG_WARN_INT_CONVERSION = YES; 347 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 348 | CLANG_WARN_UNREACHABLE_CODE = YES; 349 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 350 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 351 | COPY_PHASE_STRIP = NO; 352 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 353 | ENABLE_NS_ASSERTIONS = NO; 354 | ENABLE_STRICT_OBJC_MSGSEND = YES; 355 | GCC_C_LANGUAGE_STANDARD = gnu99; 356 | GCC_NO_COMMON_BLOCKS = YES; 357 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 358 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 359 | GCC_WARN_UNDECLARED_SELECTOR = YES; 360 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 361 | GCC_WARN_UNUSED_FUNCTION = YES; 362 | GCC_WARN_UNUSED_VARIABLE = YES; 363 | IPHONEOS_DEPLOYMENT_TARGET = 8.3; 364 | MTL_ENABLE_DEBUG_INFO = NO; 365 | SDKROOT = iphoneos; 366 | TARGETED_DEVICE_FAMILY = "1,2"; 367 | VALIDATE_PRODUCT = YES; 368 | }; 369 | name = Release; 370 | }; 371 | DF5FA9961B031C1A00EFDA42 /* Debug */ = { 372 | isa = XCBuildConfiguration; 373 | buildSettings = { 374 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 375 | INFOPLIST_FILE = NSDate_Extensions/Info.plist; 376 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 377 | PRODUCT_NAME = "$(TARGET_NAME)"; 378 | }; 379 | name = Debug; 380 | }; 381 | DF5FA9971B031C1A00EFDA42 /* Release */ = { 382 | isa = XCBuildConfiguration; 383 | buildSettings = { 384 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 385 | INFOPLIST_FILE = NSDate_Extensions/Info.plist; 386 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 387 | PRODUCT_NAME = "$(TARGET_NAME)"; 388 | }; 389 | name = Release; 390 | }; 391 | DF5FA9991B031C1A00EFDA42 /* Debug */ = { 392 | isa = XCBuildConfiguration; 393 | buildSettings = { 394 | BUNDLE_LOADER = "$(TEST_HOST)"; 395 | FRAMEWORK_SEARCH_PATHS = ( 396 | "$(SDKROOT)/Developer/Library/Frameworks", 397 | "$(inherited)", 398 | ); 399 | GCC_PREPROCESSOR_DEFINITIONS = ( 400 | "DEBUG=1", 401 | "$(inherited)", 402 | ); 403 | INFOPLIST_FILE = NSDate_ExtensionsTests/Info.plist; 404 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 405 | PRODUCT_NAME = "$(TARGET_NAME)"; 406 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/NSDate_Extensions.app/NSDate_Extensions"; 407 | }; 408 | name = Debug; 409 | }; 410 | DF5FA99A1B031C1A00EFDA42 /* Release */ = { 411 | isa = XCBuildConfiguration; 412 | buildSettings = { 413 | BUNDLE_LOADER = "$(TEST_HOST)"; 414 | FRAMEWORK_SEARCH_PATHS = ( 415 | "$(SDKROOT)/Developer/Library/Frameworks", 416 | "$(inherited)", 417 | ); 418 | INFOPLIST_FILE = NSDate_ExtensionsTests/Info.plist; 419 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 420 | PRODUCT_NAME = "$(TARGET_NAME)"; 421 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/NSDate_Extensions.app/NSDate_Extensions"; 422 | }; 423 | name = Release; 424 | }; 425 | /* End XCBuildConfiguration section */ 426 | 427 | /* Begin XCConfigurationList section */ 428 | DF5FA9711B031C1900EFDA42 /* Build configuration list for PBXProject "NSDate_Extensions" */ = { 429 | isa = XCConfigurationList; 430 | buildConfigurations = ( 431 | DF5FA9931B031C1A00EFDA42 /* Debug */, 432 | DF5FA9941B031C1A00EFDA42 /* Release */, 433 | ); 434 | defaultConfigurationIsVisible = 0; 435 | defaultConfigurationName = Release; 436 | }; 437 | DF5FA9951B031C1A00EFDA42 /* Build configuration list for PBXNativeTarget "NSDate_Extensions" */ = { 438 | isa = XCConfigurationList; 439 | buildConfigurations = ( 440 | DF5FA9961B031C1A00EFDA42 /* Debug */, 441 | DF5FA9971B031C1A00EFDA42 /* Release */, 442 | ); 443 | defaultConfigurationIsVisible = 0; 444 | defaultConfigurationName = Release; 445 | }; 446 | DF5FA9981B031C1A00EFDA42 /* Build configuration list for PBXNativeTarget "NSDate_ExtensionsTests" */ = { 447 | isa = XCConfigurationList; 448 | buildConfigurations = ( 449 | DF5FA9991B031C1A00EFDA42 /* Debug */, 450 | DF5FA99A1B031C1A00EFDA42 /* Release */, 451 | ); 452 | defaultConfigurationIsVisible = 0; 453 | defaultConfigurationName = Release; 454 | }; 455 | /* End XCConfigurationList section */ 456 | }; 457 | rootObject = DF5FA96E1B031C1900EFDA42 /* Project object */; 458 | } 459 | -------------------------------------------------------------------------------- /NSDate_Extensions.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /NSDate_Extensions/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.swift 3 | // NSDate_Extensions 4 | // 5 | // Created by Chris Amanse on 5/12/15. 6 | // Copyright (c) 2015 Joe Christopher Paul Amanse. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | @UIApplicationMain 12 | class AppDelegate: UIResponder, UIApplicationDelegate { 13 | 14 | var window: UIWindow? 15 | 16 | 17 | func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool { 18 | // Override point for customization after application launch. 19 | return true 20 | } 21 | 22 | func applicationWillResignActive(application: UIApplication) { 23 | // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. 24 | // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game. 25 | } 26 | 27 | func applicationDidEnterBackground(application: UIApplication) { 28 | // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. 29 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. 30 | } 31 | 32 | func applicationWillEnterForeground(application: UIApplication) { 33 | // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background. 34 | } 35 | 36 | func applicationDidBecomeActive(application: UIApplication) { 37 | // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. 38 | } 39 | 40 | func applicationWillTerminate(application: UIApplication) { 41 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. 42 | } 43 | 44 | 45 | } 46 | 47 | -------------------------------------------------------------------------------- /NSDate_Extensions/Base.lproj/LaunchScreen.xib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 20 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | -------------------------------------------------------------------------------- /NSDate_Extensions/Base.lproj/Main.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /NSDate_Extensions/Images.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "iphone", 5 | "size" : "29x29", 6 | "scale" : "2x" 7 | }, 8 | { 9 | "idiom" : "iphone", 10 | "size" : "29x29", 11 | "scale" : "3x" 12 | }, 13 | { 14 | "idiom" : "iphone", 15 | "size" : "40x40", 16 | "scale" : "2x" 17 | }, 18 | { 19 | "idiom" : "iphone", 20 | "size" : "40x40", 21 | "scale" : "3x" 22 | }, 23 | { 24 | "idiom" : "iphone", 25 | "size" : "60x60", 26 | "scale" : "2x" 27 | }, 28 | { 29 | "idiom" : "iphone", 30 | "size" : "60x60", 31 | "scale" : "3x" 32 | }, 33 | { 34 | "idiom" : "ipad", 35 | "size" : "29x29", 36 | "scale" : "1x" 37 | }, 38 | { 39 | "idiom" : "ipad", 40 | "size" : "29x29", 41 | "scale" : "2x" 42 | }, 43 | { 44 | "idiom" : "ipad", 45 | "size" : "40x40", 46 | "scale" : "1x" 47 | }, 48 | { 49 | "idiom" : "ipad", 50 | "size" : "40x40", 51 | "scale" : "2x" 52 | }, 53 | { 54 | "idiom" : "ipad", 55 | "size" : "76x76", 56 | "scale" : "1x" 57 | }, 58 | { 59 | "idiom" : "ipad", 60 | "size" : "76x76", 61 | "scale" : "2x" 62 | } 63 | ], 64 | "info" : { 65 | "version" : 1, 66 | "author" : "xcode" 67 | } 68 | } -------------------------------------------------------------------------------- /NSDate_Extensions/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | com.joechristopherpaulamanse.$(PRODUCT_NAME:rfc1034identifier) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | APPL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1 23 | LSRequiresIPhoneOS 24 | 25 | UILaunchStoryboardName 26 | LaunchScreen 27 | UIMainStoryboardFile 28 | Main 29 | UIRequiredDeviceCapabilities 30 | 31 | armv7 32 | 33 | UISupportedInterfaceOrientations 34 | 35 | UIInterfaceOrientationPortrait 36 | UIInterfaceOrientationLandscapeLeft 37 | UIInterfaceOrientationLandscapeRight 38 | 39 | UISupportedInterfaceOrientations~ipad 40 | 41 | UIInterfaceOrientationPortrait 42 | UIInterfaceOrientationPortraitUpsideDown 43 | UIInterfaceOrientationLandscapeLeft 44 | UIInterfaceOrientationLandscapeRight 45 | 46 | 47 | 48 | -------------------------------------------------------------------------------- /NSDate_Extensions/NSDate+Comparable.swift: -------------------------------------------------------------------------------- 1 | // 2 | // NSDate+Comparable.swift 3 | // NSDate_Extensions 4 | // 5 | // Created by Chris Amanse on 5/12/15. 6 | // Copyright (c) 2015 Joe Christopher Paul Amanse. All rights reserved. 7 | // 8 | // This code is licensed under the MIT License 9 | // 10 | // Permission is hereby granted, free of charge, to any person obtaining a copy 11 | // of this software and associated documentation files (the "Software"), to deal 12 | // in the Software without restriction, including without limitation the rights 13 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 14 | // copies of the Software, and to permit persons to whom the Software is 15 | // furnished to do so, subject to the following conditions: 16 | // 17 | // The above copyright notice and this permission notice shall be included in 18 | // all copies or substantial portions of the Software. 19 | // 20 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 21 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 22 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 23 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 24 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 25 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 26 | // THE SOFTWARE. 27 | 28 | import Foundation 29 | 30 | public func ==(lhs: NSDate, rhs: NSDate) -> Bool { 31 | return lhs.isEqualToDate(rhs) 32 | } 33 | 34 | extension NSDate: Comparable { } 35 | public func <(lhs: NSDate, rhs: NSDate) -> Bool { 36 | return lhs.compare(rhs) == .OrderedAscending 37 | } 38 | 39 | public func >(lhs: NSDate, rhs: NSDate) -> Bool { 40 | return lhs.compare(rhs) == .OrderedDescending 41 | } 42 | 43 | public func <=(lhs: NSDate, rhs: NSDate) -> Bool { 44 | return lhs < rhs || lhs.compare(rhs) == .OrderedSame 45 | } 46 | 47 | public func >=(lhs: NSDate, rhs: NSDate) -> Bool { 48 | return lhs > rhs || lhs.compare(rhs) == .OrderedSame 49 | } -------------------------------------------------------------------------------- /NSDate_Extensions/NSDate+Count.swift: -------------------------------------------------------------------------------- 1 | // 2 | // NSDate+Count.swift 3 | // NSDate_Extensions 4 | // 5 | // Created by Chris Amanse on 5/13/15. 6 | // Copyright (c) 2015 Joe Christopher Paul Amanse. All rights reserved. 7 | // 8 | // This code is licensed under the MIT License 9 | // 10 | // Permission is hereby granted, free of charge, to any person obtaining a copy 11 | // of this software and associated documentation files (the "Software"), to deal 12 | // in the Software without restriction, including without limitation the rights 13 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 14 | // copies of the Software, and to permit persons to whom the Software is 15 | // furnished to do so, subject to the following conditions: 16 | // 17 | // The above copyright notice and this permission notice shall be included in 18 | // all copies or substantial portions of the Software. 19 | // 20 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 21 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 22 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 23 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 24 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 25 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 26 | // THE SOFTWARE. 27 | 28 | import Foundation 29 | 30 | extension NSDate { 31 | func count(unit: NSDateUnit, toDate date: NSDate) -> Int { 32 | return Int(preciseCount(unit, toDate: date)) 33 | } 34 | func preciseCount(unit: NSDateUnit, toDate date: NSDate) -> Double { 35 | return date.timeIntervalSinceDate(self).count(unit) 36 | } 37 | 38 | class func count(unit: NSDateUnit, inA largerUnit: NSDateUnit, fromDate date: NSDate) -> Int { 39 | return Int(NSDate.preciseCount(unit, inA: largerUnit, fromDate: date)) 40 | } 41 | 42 | class func preciseCount(unit: NSDateUnit, inA largerUnit: NSDateUnit, fromDate date: NSDate) -> Double { 43 | if unit.rawValue < largerUnit.rawValue { 44 | let startDate = date.startOf(largerUnit) 45 | return startDate.preciseCount(unit, toDate: startDate.next(largerUnit)) 46 | } else if unit.rawValue == largerUnit.rawValue { 47 | return 1 48 | } 49 | return 0 50 | } 51 | 52 | } -------------------------------------------------------------------------------- /NSDate_Extensions/NSDate+Main.swift: -------------------------------------------------------------------------------- 1 | // 2 | // NSDate+Main.swift 3 | // NSDate_Extensions 4 | // 5 | // Created by Chris Amanse on 5/12/15. 6 | // Copyright (c) 2015 Joe Christopher Paul Amanse. All rights reserved. 7 | // 8 | // This code is licensed under the MIT License 9 | // 10 | // Permission is hereby granted, free of charge, to any person obtaining a copy 11 | // of this software and associated documentation files (the "Software"), to deal 12 | // in the Software without restriction, including without limitation the rights 13 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 14 | // copies of the Software, and to permit persons to whom the Software is 15 | // furnished to do so, subject to the following conditions: 16 | // 17 | // The above copyright notice and this permission notice shall be included in 18 | // all copies or substantial portions of the Software. 19 | // 20 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 21 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 22 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 23 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 24 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 25 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 26 | // THE SOFTWARE. 27 | 28 | import Foundation 29 | 30 | // MARK: - NSDate Units 31 | 32 | public enum NSDateUnit: Int { 33 | case Second = 1 34 | case Minute 35 | case Hour 36 | case Day 37 | case Week 38 | case Month 39 | case Year 40 | } 41 | 42 | // MARK: - NSTimeInterval Utilities 43 | extension NSTimeInterval { 44 | var seconds: NSTimeInterval { 45 | return self 46 | } 47 | var minutes: NSTimeInterval { 48 | return self * 60 49 | } 50 | var hours: NSTimeInterval { 51 | return self.minutes * 60 52 | } 53 | var days: NSTimeInterval { 54 | return self.hours * 24 55 | } 56 | var weeks: NSTimeInterval { 57 | return self.days * 7 58 | } 59 | 60 | func count(unit: NSDateUnit) -> Double { 61 | switch unit { 62 | case .Second: 63 | return self 64 | case .Minute: 65 | return self / 1.minutes 66 | case .Hour: 67 | return self / 1.hours 68 | case .Day: 69 | return self / 1.days 70 | case .Week: 71 | return self / 1.weeks 72 | case .Month: 73 | return self / 31.days // Inaccurate - not all months have 31 days, maybe modify to get days in current month? 74 | case .Year: 75 | return self / 365.days // Inaccurate - not all years have 365 days 76 | } 77 | } 78 | } 79 | 80 | // MARK: - NSDate Utilities 81 | 82 | extension NSDate { 83 | // For shorter call of current calendar within NSDate instance 84 | var calendar: NSCalendar { 85 | return NSCalendar.currentCalendar() 86 | } 87 | 88 | // MARK: - Date Creation 89 | class func dateWithYear(year: Int, month: Int, andDay day: Int) -> NSDate? { 90 | let components = NSDateComponents() 91 | components.month = month 92 | components.day = day 93 | components.year = year 94 | 95 | return NSCalendar.currentCalendar().dateFromComponents(components) 96 | } 97 | class func dateWithYear(year: Int, month: Int, day: Int, hour: Int, minute: Int, andSecond second: Int) -> NSDate? { 98 | let components = NSDateComponents() 99 | components.month = month 100 | components.day = day 101 | components.year = year 102 | components.hour = hour 103 | components.minute = minute 104 | components.second = second 105 | 106 | return NSCalendar.currentCalendar().dateFromComponents(components) 107 | } 108 | 109 | class func dateFromString(dateString: String, withFormat format: String) -> NSDate? { 110 | let dateFormatter = NSDateFormatter() 111 | dateFormatter.dateFormat = format 112 | return dateFormatter.dateFromString(dateString) 113 | } 114 | class func dateFromComponents(components: NSDateComponents) -> NSDate? { 115 | return NSCalendar.currentCalendar().dateFromComponents(components) 116 | } 117 | 118 | class func today() -> NSDate { 119 | return NSDate() 120 | } 121 | class func yesterday() -> NSDate { 122 | return NSDate().dateByAddingTimeInterval(-1.days) 123 | } 124 | class func tomorrow() -> NSDate { 125 | return NSDate().dateByAddingTimeInterval(1.days) 126 | } 127 | 128 | // MARK: - Conversion 129 | func toStringWithFormat(format: String) -> String { 130 | let dateFormatter = NSDateFormatter() 131 | dateFormatter.dateFormat = format 132 | return dateFormatter.stringFromDate(self) 133 | } 134 | 135 | // MARK: - Components using Units 136 | func getComponents(unitFlags: NSCalendarUnit) -> NSDateComponents { 137 | return calendar.components(unitFlags, fromDate: self) 138 | } 139 | 140 | // MARK: Calendar Units 141 | var era: Int { 142 | return calendar.component(.Era, fromDate: self) 143 | } 144 | var year: Int { 145 | return calendar.component(.Year, fromDate: self) 146 | } 147 | var month: Int { 148 | return calendar.component(.Month, fromDate: self) 149 | } 150 | var day: Int { 151 | return calendar.component(.Day, fromDate: self) 152 | } 153 | var hour: Int { 154 | return calendar.component(.Hour, fromDate: self) 155 | } 156 | var minute: Int { 157 | return calendar.component(.Minute, fromDate: self) 158 | } 159 | var second: Int { 160 | return calendar.component(.Second, fromDate: self) 161 | } 162 | var weekday: Int { 163 | return calendar.component(.Weekday, fromDate: self) 164 | } 165 | var weekdayOrdinal: Int { 166 | return calendar.component(.WeekdayOrdinal, fromDate: self) 167 | } 168 | var quarter: Int { 169 | return calendar.component(.Quarter, fromDate: self) 170 | } 171 | var weekOfMonth: Int { 172 | return calendar.component(.WeekOfMonth, fromDate: self) 173 | } 174 | var weekOfYear: Int { 175 | return calendar.component(.WeekOfYear, fromDate: self) 176 | } 177 | var nanosecond: Int { 178 | return calendar.component(.Nanosecond, fromDate: self) 179 | } 180 | 181 | var isToday: Bool { 182 | return calendar.isDateInToday(self) 183 | } 184 | var isTomorrow: Bool { 185 | return calendar.isDateInTomorrow(self) 186 | } 187 | var isYesterday: Bool { 188 | return calendar.isDateInYesterday(self) 189 | } 190 | var isWeekend: Bool { 191 | return calendar.isDateInWeekend(self) 192 | } 193 | var isWeekday: Bool { 194 | return !isWeekend 195 | } 196 | } 197 | -------------------------------------------------------------------------------- /NSDate_Extensions/NSDate+Periods.swift: -------------------------------------------------------------------------------- 1 | // 2 | // NSDate+Periods.swift 3 | // NSDate_Extensions 4 | // 5 | // Created by Chris Amanse on 5/12/15. 6 | // Copyright (c) 2015 Joe Christopher Paul Amanse. All rights reserved. 7 | // 8 | // This code is licensed under the MIT License 9 | // 10 | // Permission is hereby granted, free of charge, to any person obtaining a copy 11 | // of this software and associated documentation files (the "Software"), to deal 12 | // in the Software without restriction, including without limitation the rights 13 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 14 | // copies of the Software, and to permit persons to whom the Software is 15 | // furnished to do so, subject to the following conditions: 16 | // 17 | // The above copyright notice and this permission notice shall be included in 18 | // all copies or substantial portions of the Software. 19 | // 20 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 21 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 22 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 23 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 24 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 25 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 26 | // THE SOFTWARE. 27 | 28 | import Foundation 29 | 30 | extension NSDate { 31 | func startOf(unit: NSDateUnit) -> NSDate { 32 | switch unit { 33 | case .Second: 34 | return NSDate.dateWithYear(year, month: month, day: day, hour: hour, minute: minute, andSecond: second)! 35 | case .Minute: 36 | return NSDate.dateWithYear(year, month: month, day: day, hour: hour, minute: minute, andSecond: 0)! 37 | case .Hour: 38 | return NSDate.dateWithYear(year, month: month, day: day, hour: hour, minute: 0, andSecond: 0)! 39 | case .Day: 40 | return calendar.startOfDayForDate(self) 41 | case .Week: 42 | let components = NSDateComponents() 43 | components.year = year 44 | components.month = month 45 | components.weekOfMonth = weekOfMonth 46 | components.weekday = 1 47 | 48 | return calendar.dateFromComponents(components)! 49 | case .Month: 50 | return NSDate.dateWithYear(year, month: month, andDay: 1)! 51 | 52 | case .Year: 53 | return NSDate.dateWithYear(year, month: 1, andDay: 1)! 54 | } 55 | } 56 | 57 | func endOf(unit: NSDateUnit) -> NSDate { 58 | switch unit { 59 | case .Second: 60 | let components = NSDateComponents() 61 | components.year = year 62 | components.month = month 63 | components.day = day 64 | components.hour = hour 65 | components.minute = minute 66 | components.second = second 67 | components.nanosecond = 999999999 68 | 69 | return calendar.dateFromComponents(components)! 70 | case .Minute: 71 | return NSDate.dateWithYear(year, month: month, day: day, hour: hour, minute: minute, andSecond: 59)! 72 | case .Hour: 73 | return NSDate.dateWithYear(year, month: month, day: day, hour: hour, minute: 59, andSecond: 59)! 74 | case .Day: 75 | return NSDate.dateWithYear(year, month: month, day: day, hour: 23, minute: 59, andSecond: 59)! 76 | case .Week: 77 | let components = NSDateComponents() 78 | components.year = year 79 | components.month = month 80 | components.weekOfMonth = weekOfMonth 81 | components.weekday = 7 82 | components.hour = 23 83 | components.minute = 59 84 | components.second = 59 85 | 86 | return calendar.dateFromComponents(components)! 87 | case .Month: 88 | let daysInMonth = calendar.rangeOfUnit(.Day, inUnit: .Month, forDate: self).length 89 | 90 | return NSDate.dateWithYear(year, month: month, day: daysInMonth, hour: 23, minute: 59, andSecond: 59)! 91 | case .Year: 92 | return NSDate.dateWithYear(year, month: 12, day: 31, hour: 23, minute: 59, andSecond: 59)! 93 | } 94 | } 95 | 96 | func next(unit: NSDateUnit) -> NSDate { 97 | switch unit { 98 | case .Second: 99 | return self.dateByAddingTimeInterval(1.seconds) 100 | case .Minute: 101 | return self.dateByAddingTimeInterval(1.minutes) 102 | case .Hour: 103 | return self.dateByAddingTimeInterval(1.hours) 104 | case .Day: 105 | return self.dateByAddingTimeInterval(1.days) 106 | case .Week: 107 | return self.dateByAddingTimeInterval(1.weeks) 108 | case .Month: 109 | return NSDate.dateWithYear(year, month: month+1, day: day, hour: hour, minute: minute, andSecond: second)! 110 | case .Year: 111 | return NSDate.dateWithYear(year+1, month: month, day: day, hour: hour, minute: minute, andSecond: second)! 112 | } 113 | } 114 | func previous(unit: NSDateUnit) -> NSDate { 115 | switch unit { 116 | case .Second: 117 | return self.dateByAddingTimeInterval(-1.seconds) 118 | case .Minute: 119 | return self.dateByAddingTimeInterval(-1.minutes) 120 | case .Hour: 121 | return self.dateByAddingTimeInterval(-1.hours) 122 | case .Day: 123 | return self.dateByAddingTimeInterval(-1.days) 124 | case .Week: 125 | return self.dateByAddingTimeInterval(-1.weeks) 126 | case .Month: 127 | return NSDate.dateWithYear(year, month: month-1, day: day, hour: hour, minute: minute, andSecond: second)! 128 | case .Year: 129 | return NSDate.dateWithYear(year-1, month: month, day: day, hour: hour, minute: minute, andSecond: second)! 130 | } 131 | } 132 | } 133 | -------------------------------------------------------------------------------- /NSDate_Extensions/ViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.swift 3 | // NSDate_Extensions 4 | // 5 | // Created by Chris Amanse on 5/12/15. 6 | // Copyright (c) 2015 Joe Christopher Paul Amanse. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | class ViewController: UIViewController { 12 | 13 | override func viewDidLoad() { 14 | super.viewDidLoad() 15 | // Do any additional setup after loading the view, typically from a nib. 16 | } 17 | 18 | override func didReceiveMemoryWarning() { 19 | super.didReceiveMemoryWarning() 20 | // Dispose of any resources that can be recreated. 21 | } 22 | 23 | 24 | } 25 | 26 | -------------------------------------------------------------------------------- /NSDate_ExtensionsTests/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | com.joechristopherpaulamanse.$(PRODUCT_NAME:rfc1034identifier) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | BNDL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1 23 | 24 | 25 | -------------------------------------------------------------------------------- /NSDate_ExtensionsTests/NSDate_ExtensionsTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // NSDate_ExtensionsTests.swift 3 | // NSDate_ExtensionsTests 4 | // 5 | // Created by Chris Amanse on 5/12/15. 6 | // Copyright (c) 2015 Joe Christopher Paul Amanse. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | import XCTest 11 | 12 | class NSDate_ExtensionsTests: XCTestCase { 13 | 14 | override func setUp() { 15 | super.setUp() 16 | // Put setup code here. This method is called before the invocation of each test method in the class. 17 | } 18 | 19 | override func tearDown() { 20 | // Put teardown code here. This method is called after the invocation of each test method in the class. 21 | super.tearDown() 22 | } 23 | 24 | func testExample() { 25 | // This is an example of a functional test case. 26 | XCTAssert(true, "Pass") 27 | } 28 | 29 | func testPerformanceExample() { 30 | // This is an example of a performance test case. 31 | self.measureBlock() { 32 | // Put the code you want to measure the time of here. 33 | } 34 | } 35 | 36 | } 37 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # iOS - NSDate Utilities 2 | Powerful extensions for NSDate in Swift. 3 | 4 | # Installation 5 | 6 | Import only what you need: 7 | * NSDate+Main.swift - *required* 8 | * NSDate+Comparable.swift 9 | * NSDate+Periods.swift 10 | * NSDate+Periods.swift 11 | 12 | # Usage 13 | 14 | ## NSTimeInterval extension: 15 | 16 | ```swift 17 | var seconds = 2.seconds // 2 (as NSTimeInterval) 18 | seconds = 3.minutes // 3*60 = 180 19 | seconds = 1.hours // 1*60*60 = 3600 20 | seconds = 1.days // 1*60*60*24 = 86400 21 | seconds = 1.weeks // 1*60*60*24*7 = 604800 22 | 23 | let minutesIn3600Seconds = 3600.preciseCount(.Minute) // 60.0 (as Double - since there is exactly 60 minutes in 3600 seconds) 24 | let minutes = 30.preciseCount(.Minute) // 0.5 (Half a minute) 25 | let hoursInWeek = 1.week.preciseCount(.Hour) // 168.0 (24 hours * 7 days) 26 | 27 | // You can use the rest of the NSDateUnit values to count the desired unit 28 | ``` 29 | 30 | ## NSDate+Main.swift: 31 | 32 | ### NSDate Creation 33 | 34 | ```swift 35 | NSDate().calendar // Shortcut for NSCalendar.currentCalendar() - used in the extensions 36 | NSDate.dateWithYear(2015, month: 6, andDay: 28) // Creates date of June 28, 2015 at 12 AM 37 | NSDate.dateWithYear(2015, month: 1, day: 1, hour: 14, minute: 5, andSecond: 30) // Creates date of January 1, 2015 at 2:05:30 PM 38 | 39 | NSDate.today() // Today same time 40 | NSDate.tomorrow() // Tomorrow same time 41 | NSDate.yeasterday() // Yesterday same time 42 | 43 | NSDate.dateFromString(dateString: "03-30-2015", withFormat: "MM-dd-yyyy") // March 30, 2015 12AM 44 | 45 | let components = NSDateComponents() 46 | components.year = 2015 47 | components.month = 3 48 | components.day = 30 49 | 50 | NSDate.dateFromComponents(components) // March 30, 2015 12AM 51 | ``` 52 | 53 | ### Components and Conversion 54 | 55 | ```swift 56 | NSDate.dateWithYear(2015, month: 11, andDay: 23).toStringWithFormat("MM-dd-yyyy") // "11-23-2015" 57 | 58 | let christmas = NSDate.dateWithYear(2015, month: 12, andDay: 25) 59 | christmas.getComponents(NSCalendarUnit.CalendarUnitDay).day // 25 60 | christmas.year // 2015 61 | christmas.month // 12 62 | christmas.day // 25 63 | christmas.hour // 0 - since it's 12:00:00 AM 64 | christmas.minute // 0 65 | christmas.second // 0 66 | ``` 67 | 68 | ### Check relative date 69 | 70 | ```swift 71 | NSDate().isToday == true 72 | NSDate.tomorrow().isTomorrow == true 73 | NSDate.yesterday().isYesterday == true 74 | 75 | NSDate().isWeekend // Check if date is a weekend 76 | NSDate().isWeekday 77 | ``` 78 | 79 | ## NSDate+Comparable.swift: 80 | 81 | Compare dates using operators. 82 | 83 | ```swift 84 | let today = NSDate() 85 | today < NSDate.tomorrow() // True 86 | today > NSDate.yesterday() // True 87 | today == today // True 88 | today != NSDate.tomorrow() 89 | ``` 90 | 91 | ## NSDate+Periods.swift: 92 | 93 | Get start, end, next, or previous of a unit (Year, Month, Day, Week, Hour, Minute, Second) of a date. 94 | 95 | ```swift 96 | let date = NSDate.dateWithYear(2015, month: 10, day: 20, hour: 8, minute: 40, second: 9) // Oct 20, 2015 8:40:09 AM 97 | date.startOf(.Day) // Oct 20, 2015 at 12 AM 98 | date.startOf(.Month) // Oct 1, 2015, 12 AM 99 | date.startOf(.Year) // Jan 1, 2015, 12 AM 100 | // You can also use .Second, .Minute, .Hour, and .Week 101 | 102 | date.endOf(.Day) // Oct 20, 2015 at 11:59:59 PM 103 | date.endOf(.Month) // Oct 31, 2015, 11:59:59 PM 104 | date.endOf(.Year) // Dec 31, 2015, 11:59:59 PM 105 | // You can also use .Second, .Minute, .Hour, and .Week 106 | 107 | date.next(.Day) // Oct 21, 2015 at 8:40:09 AM 108 | date.next(.Month) // Nov 20, 2015, 8:40:09 AM 109 | date.next(.Year) // Oct 20, 2016, 8:40:09 AM 110 | // You can also use .Second, .Minute, .Hour, and .Week 111 | 112 | date.previous(.Day) // Oct 19, 2015 at 8:40:09 AM 113 | date.previous(.Month) // Sept 20, 2015, 8:40:09 AM 114 | date.previous(.Year) // Oct 20, 2014, 8:40:09 AM 115 | // You can also use .Second, .Minute, .Hour, and .Week 116 | ``` 117 | 118 | ## NSDate+Count.swift 119 | 120 | Count units from date to another date. 121 | 122 | ```swift 123 | let today = NSDate() 124 | let tomorrow = today.next(.Day) 125 | today.count(.Day, toDate: tomorrow) // 1 126 | today.preciseCount(.Day, toDate: tomorrow) // 1.0 127 | today.count(.Hour, toDate: tomorrow) // 24 128 | 129 | // Difference between count and preciseCount 130 | let startOfDay = today.startOf(.Day) 131 | let lunch = NSDate.dateWithYear(startOfDay.year, month: startOfMonth.month, day: startOfMonth.day, hour: 12, minute: 0, andSecond: 0) 132 | startOfDay.count(.Day, toDate: lunch) // 0 133 | startOfDay.preciseCount(.Day, toDate: lunch) // 0.5 (Half a day or 12 hours) 134 | startOfDay.preciseCount(.Hour, toDate: lunch) // 12 (hours) 135 | ``` 136 | 137 | Count units from a larger unit based on a given date. 138 | 139 | ```swift 140 | let daysInMonthToday = NSDate.count(.Day, inA: .Month, fromDate: NSDate.today()) // Count days in current month 141 | let daysInYearToday = NSDate.preciseCount(.Day, inA: .Year, fromDate: NSDate.today()) // Count days in year precisely 142 | ``` 143 | 144 | # License 145 | Copyright (c) 2016 Joe Christopher Paul Amanse 146 | 147 | This software is distributed under the [MIT License](./LICENSE.md). 148 | --------------------------------------------------------------------------------