├── .gitignore ├── DateExtension.xcodeproj ├── project.pbxproj ├── project.xcworkspace │ └── contents.xcworkspacedata └── xcuserdata │ └── aleite.xcuserdatad │ └── xcschemes │ ├── DateExtension.xcscheme │ └── xcschememanagement.plist ├── DateExtension ├── AppDelegate.swift ├── DateExtension.swift ├── Images.xcassets │ ├── AppIcon.appiconset │ │ └── Contents.json │ └── LaunchImage.launchimage │ │ └── Contents.json └── Info.plist ├── DateExtensionTests ├── DateExtensionTests.swift └── Info.plist ├── LICENSE ├── README.md └── SwiftDateExtension.podspec /.gitignore: -------------------------------------------------------------------------------- 1 | # Xcode 2 | # 3 | build/ 4 | *.pbxuser 5 | !default.pbxuser 6 | *.mode1v3 7 | !default.mode1v3 8 | *.mode2v3 9 | !default.mode2v3 10 | *.perspectivev3 11 | !default.perspectivev3 12 | xcuserdata 13 | *.xccheckout 14 | *.moved-aside 15 | DerivedData 16 | *.hmap 17 | *.ipa 18 | *.xcuserstate 19 | -------------------------------------------------------------------------------- /DateExtension.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 4CF842B319415DE3004DCFB6 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4CF842B219415DE3004DCFB6 /* AppDelegate.swift */; }; 11 | 4CF842B519415DE3004DCFB6 /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 4CF842B419415DE3004DCFB6 /* Images.xcassets */; }; 12 | 4CF842C119415DE3004DCFB6 /* DateExtensionTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4CF842C019415DE3004DCFB6 /* DateExtensionTests.swift */; }; 13 | 4CF842CB19415E18004DCFB6 /* DateExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4CF842CA19415E18004DCFB6 /* DateExtension.swift */; }; 14 | 4CF842CC19415E18004DCFB6 /* DateExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4CF842CA19415E18004DCFB6 /* DateExtension.swift */; }; 15 | /* End PBXBuildFile section */ 16 | 17 | /* Begin PBXContainerItemProxy section */ 18 | 4CF842BB19415DE3004DCFB6 /* PBXContainerItemProxy */ = { 19 | isa = PBXContainerItemProxy; 20 | containerPortal = 4CF842A519415DE3004DCFB6 /* Project object */; 21 | proxyType = 1; 22 | remoteGlobalIDString = 4CF842AC19415DE3004DCFB6; 23 | remoteInfo = DateExtension; 24 | }; 25 | /* End PBXContainerItemProxy section */ 26 | 27 | /* Begin PBXFileReference section */ 28 | 4CF842AD19415DE3004DCFB6 /* DateExtension.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = DateExtension.app; sourceTree = BUILT_PRODUCTS_DIR; }; 29 | 4CF842B119415DE3004DCFB6 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 30 | 4CF842B219415DE3004DCFB6 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; 31 | 4CF842B419415DE3004DCFB6 /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = ""; }; 32 | 4CF842BA19415DE3004DCFB6 /* DateExtensionTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = DateExtensionTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 33 | 4CF842BF19415DE3004DCFB6 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 34 | 4CF842C019415DE3004DCFB6 /* DateExtensionTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DateExtensionTests.swift; sourceTree = ""; }; 35 | 4CF842CA19415E18004DCFB6 /* DateExtension.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DateExtension.swift; sourceTree = ""; }; 36 | /* End PBXFileReference section */ 37 | 38 | /* Begin PBXFrameworksBuildPhase section */ 39 | 4CF842AA19415DE3004DCFB6 /* Frameworks */ = { 40 | isa = PBXFrameworksBuildPhase; 41 | buildActionMask = 2147483647; 42 | files = ( 43 | ); 44 | runOnlyForDeploymentPostprocessing = 0; 45 | }; 46 | 4CF842B719415DE3004DCFB6 /* Frameworks */ = { 47 | isa = PBXFrameworksBuildPhase; 48 | buildActionMask = 2147483647; 49 | files = ( 50 | ); 51 | runOnlyForDeploymentPostprocessing = 0; 52 | }; 53 | /* End PBXFrameworksBuildPhase section */ 54 | 55 | /* Begin PBXGroup section */ 56 | 4CF842A419415DE3004DCFB6 = { 57 | isa = PBXGroup; 58 | children = ( 59 | 4CF842AF19415DE3004DCFB6 /* DateExtension */, 60 | 4CF842BD19415DE3004DCFB6 /* DateExtensionTests */, 61 | 4CF842AE19415DE3004DCFB6 /* Products */, 62 | ); 63 | sourceTree = ""; 64 | }; 65 | 4CF842AE19415DE3004DCFB6 /* Products */ = { 66 | isa = PBXGroup; 67 | children = ( 68 | 4CF842AD19415DE3004DCFB6 /* DateExtension.app */, 69 | 4CF842BA19415DE3004DCFB6 /* DateExtensionTests.xctest */, 70 | ); 71 | name = Products; 72 | sourceTree = ""; 73 | }; 74 | 4CF842AF19415DE3004DCFB6 /* DateExtension */ = { 75 | isa = PBXGroup; 76 | children = ( 77 | 4CF842B219415DE3004DCFB6 /* AppDelegate.swift */, 78 | 4CF842B419415DE3004DCFB6 /* Images.xcassets */, 79 | 4CF842B019415DE3004DCFB6 /* Supporting Files */, 80 | 4CF842CA19415E18004DCFB6 /* DateExtension.swift */, 81 | ); 82 | path = DateExtension; 83 | sourceTree = ""; 84 | }; 85 | 4CF842B019415DE3004DCFB6 /* Supporting Files */ = { 86 | isa = PBXGroup; 87 | children = ( 88 | 4CF842B119415DE3004DCFB6 /* Info.plist */, 89 | ); 90 | name = "Supporting Files"; 91 | sourceTree = ""; 92 | }; 93 | 4CF842BD19415DE3004DCFB6 /* DateExtensionTests */ = { 94 | isa = PBXGroup; 95 | children = ( 96 | 4CF842C019415DE3004DCFB6 /* DateExtensionTests.swift */, 97 | 4CF842BE19415DE3004DCFB6 /* Supporting Files */, 98 | ); 99 | path = DateExtensionTests; 100 | sourceTree = ""; 101 | }; 102 | 4CF842BE19415DE3004DCFB6 /* Supporting Files */ = { 103 | isa = PBXGroup; 104 | children = ( 105 | 4CF842BF19415DE3004DCFB6 /* Info.plist */, 106 | ); 107 | name = "Supporting Files"; 108 | sourceTree = ""; 109 | }; 110 | /* End PBXGroup section */ 111 | 112 | /* Begin PBXNativeTarget section */ 113 | 4CF842AC19415DE3004DCFB6 /* DateExtension */ = { 114 | isa = PBXNativeTarget; 115 | buildConfigurationList = 4CF842C419415DE3004DCFB6 /* Build configuration list for PBXNativeTarget "DateExtension" */; 116 | buildPhases = ( 117 | 4CF842A919415DE3004DCFB6 /* Sources */, 118 | 4CF842AA19415DE3004DCFB6 /* Frameworks */, 119 | 4CF842AB19415DE3004DCFB6 /* Resources */, 120 | ); 121 | buildRules = ( 122 | ); 123 | dependencies = ( 124 | ); 125 | name = DateExtension; 126 | productName = DateExtension; 127 | productReference = 4CF842AD19415DE3004DCFB6 /* DateExtension.app */; 128 | productType = "com.apple.product-type.application"; 129 | }; 130 | 4CF842B919415DE3004DCFB6 /* DateExtensionTests */ = { 131 | isa = PBXNativeTarget; 132 | buildConfigurationList = 4CF842C719415DE3004DCFB6 /* Build configuration list for PBXNativeTarget "DateExtensionTests" */; 133 | buildPhases = ( 134 | 4CF842B619415DE3004DCFB6 /* Sources */, 135 | 4CF842B719415DE3004DCFB6 /* Frameworks */, 136 | 4CF842B819415DE3004DCFB6 /* Resources */, 137 | ); 138 | buildRules = ( 139 | ); 140 | dependencies = ( 141 | 4CF842BC19415DE3004DCFB6 /* PBXTargetDependency */, 142 | ); 143 | name = DateExtensionTests; 144 | productName = DateExtensionTests; 145 | productReference = 4CF842BA19415DE3004DCFB6 /* DateExtensionTests.xctest */; 146 | productType = "com.apple.product-type.bundle.unit-test"; 147 | }; 148 | /* End PBXNativeTarget section */ 149 | 150 | /* Begin PBXProject section */ 151 | 4CF842A519415DE3004DCFB6 /* Project object */ = { 152 | isa = PBXProject; 153 | attributes = { 154 | LastSwiftMigration = 0700; 155 | LastSwiftUpdateCheck = 0700; 156 | LastUpgradeCheck = 0700; 157 | ORGANIZATIONNAME = al7dev; 158 | TargetAttributes = { 159 | 4CF842AC19415DE3004DCFB6 = { 160 | CreatedOnToolsVersion = 6.0; 161 | LastSwiftMigration = 0800; 162 | }; 163 | 4CF842B919415DE3004DCFB6 = { 164 | CreatedOnToolsVersion = 6.0; 165 | LastSwiftMigration = 0800; 166 | TestTargetID = 4CF842AC19415DE3004DCFB6; 167 | }; 168 | }; 169 | }; 170 | buildConfigurationList = 4CF842A819415DE3004DCFB6 /* Build configuration list for PBXProject "DateExtension" */; 171 | compatibilityVersion = "Xcode 3.2"; 172 | developmentRegion = English; 173 | hasScannedForEncodings = 0; 174 | knownRegions = ( 175 | en, 176 | ); 177 | mainGroup = 4CF842A419415DE3004DCFB6; 178 | productRefGroup = 4CF842AE19415DE3004DCFB6 /* Products */; 179 | projectDirPath = ""; 180 | projectRoot = ""; 181 | targets = ( 182 | 4CF842AC19415DE3004DCFB6 /* DateExtension */, 183 | 4CF842B919415DE3004DCFB6 /* DateExtensionTests */, 184 | ); 185 | }; 186 | /* End PBXProject section */ 187 | 188 | /* Begin PBXResourcesBuildPhase section */ 189 | 4CF842AB19415DE3004DCFB6 /* Resources */ = { 190 | isa = PBXResourcesBuildPhase; 191 | buildActionMask = 2147483647; 192 | files = ( 193 | 4CF842B519415DE3004DCFB6 /* Images.xcassets in Resources */, 194 | ); 195 | runOnlyForDeploymentPostprocessing = 0; 196 | }; 197 | 4CF842B819415DE3004DCFB6 /* Resources */ = { 198 | isa = PBXResourcesBuildPhase; 199 | buildActionMask = 2147483647; 200 | files = ( 201 | ); 202 | runOnlyForDeploymentPostprocessing = 0; 203 | }; 204 | /* End PBXResourcesBuildPhase section */ 205 | 206 | /* Begin PBXSourcesBuildPhase section */ 207 | 4CF842A919415DE3004DCFB6 /* Sources */ = { 208 | isa = PBXSourcesBuildPhase; 209 | buildActionMask = 2147483647; 210 | files = ( 211 | 4CF842B319415DE3004DCFB6 /* AppDelegate.swift in Sources */, 212 | 4CF842CB19415E18004DCFB6 /* DateExtension.swift in Sources */, 213 | ); 214 | runOnlyForDeploymentPostprocessing = 0; 215 | }; 216 | 4CF842B619415DE3004DCFB6 /* Sources */ = { 217 | isa = PBXSourcesBuildPhase; 218 | buildActionMask = 2147483647; 219 | files = ( 220 | 4CF842C119415DE3004DCFB6 /* DateExtensionTests.swift in Sources */, 221 | 4CF842CC19415E18004DCFB6 /* DateExtension.swift in Sources */, 222 | ); 223 | runOnlyForDeploymentPostprocessing = 0; 224 | }; 225 | /* End PBXSourcesBuildPhase section */ 226 | 227 | /* Begin PBXTargetDependency section */ 228 | 4CF842BC19415DE3004DCFB6 /* PBXTargetDependency */ = { 229 | isa = PBXTargetDependency; 230 | target = 4CF842AC19415DE3004DCFB6 /* DateExtension */; 231 | targetProxy = 4CF842BB19415DE3004DCFB6 /* PBXContainerItemProxy */; 232 | }; 233 | /* End PBXTargetDependency section */ 234 | 235 | /* Begin XCBuildConfiguration section */ 236 | 4CF842C219415DE3004DCFB6 /* Debug */ = { 237 | isa = XCBuildConfiguration; 238 | buildSettings = { 239 | ALWAYS_SEARCH_USER_PATHS = NO; 240 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 241 | CLANG_CXX_LIBRARY = "libc++"; 242 | CLANG_ENABLE_MODULES = YES; 243 | CLANG_ENABLE_OBJC_ARC = YES; 244 | CLANG_WARN_BOOL_CONVERSION = YES; 245 | CLANG_WARN_CONSTANT_CONVERSION = YES; 246 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 247 | CLANG_WARN_EMPTY_BODY = YES; 248 | CLANG_WARN_ENUM_CONVERSION = YES; 249 | CLANG_WARN_INT_CONVERSION = YES; 250 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 251 | CLANG_WARN_UNREACHABLE_CODE = YES; 252 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 253 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 254 | COPY_PHASE_STRIP = NO; 255 | ENABLE_STRICT_OBJC_MSGSEND = YES; 256 | ENABLE_TESTABILITY = YES; 257 | GCC_C_LANGUAGE_STANDARD = gnu99; 258 | GCC_DYNAMIC_NO_PIC = NO; 259 | GCC_OPTIMIZATION_LEVEL = 0; 260 | GCC_PREPROCESSOR_DEFINITIONS = ( 261 | "DEBUG=1", 262 | "$(inherited)", 263 | ); 264 | GCC_SYMBOLS_PRIVATE_EXTERN = NO; 265 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 266 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 267 | GCC_WARN_UNDECLARED_SELECTOR = YES; 268 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 269 | GCC_WARN_UNUSED_FUNCTION = YES; 270 | GCC_WARN_UNUSED_VARIABLE = YES; 271 | IPHONEOS_DEPLOYMENT_TARGET = 8.0; 272 | METAL_ENABLE_DEBUG_INFO = YES; 273 | ONLY_ACTIVE_ARCH = YES; 274 | SDKROOT = iphoneos; 275 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 276 | SWIFT_VERSION = 3.0; 277 | }; 278 | name = Debug; 279 | }; 280 | 4CF842C319415DE3004DCFB6 /* Release */ = { 281 | isa = XCBuildConfiguration; 282 | buildSettings = { 283 | ALWAYS_SEARCH_USER_PATHS = NO; 284 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 285 | CLANG_CXX_LIBRARY = "libc++"; 286 | CLANG_ENABLE_MODULES = YES; 287 | CLANG_ENABLE_OBJC_ARC = YES; 288 | CLANG_WARN_BOOL_CONVERSION = YES; 289 | CLANG_WARN_CONSTANT_CONVERSION = YES; 290 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 291 | CLANG_WARN_EMPTY_BODY = YES; 292 | CLANG_WARN_ENUM_CONVERSION = YES; 293 | CLANG_WARN_INT_CONVERSION = YES; 294 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 295 | CLANG_WARN_UNREACHABLE_CODE = YES; 296 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 297 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 298 | COPY_PHASE_STRIP = YES; 299 | ENABLE_NS_ASSERTIONS = NO; 300 | ENABLE_STRICT_OBJC_MSGSEND = YES; 301 | GCC_C_LANGUAGE_STANDARD = gnu99; 302 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 303 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 304 | GCC_WARN_UNDECLARED_SELECTOR = YES; 305 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 306 | GCC_WARN_UNUSED_FUNCTION = YES; 307 | GCC_WARN_UNUSED_VARIABLE = YES; 308 | IPHONEOS_DEPLOYMENT_TARGET = 8.0; 309 | METAL_ENABLE_DEBUG_INFO = NO; 310 | SDKROOT = iphoneos; 311 | SWIFT_VERSION = 3.0; 312 | VALIDATE_PRODUCT = YES; 313 | }; 314 | name = Release; 315 | }; 316 | 4CF842C519415DE3004DCFB6 /* Debug */ = { 317 | isa = XCBuildConfiguration; 318 | buildSettings = { 319 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 320 | ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage; 321 | INFOPLIST_FILE = DateExtension/Info.plist; 322 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 323 | PRODUCT_BUNDLE_IDENTIFIER = "com.al7dev.${PRODUCT_NAME:rfc1034identifier}"; 324 | PRODUCT_NAME = "$(TARGET_NAME)"; 325 | SWIFT_VERSION = 3.0; 326 | }; 327 | name = Debug; 328 | }; 329 | 4CF842C619415DE3004DCFB6 /* Release */ = { 330 | isa = XCBuildConfiguration; 331 | buildSettings = { 332 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 333 | ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage; 334 | INFOPLIST_FILE = DateExtension/Info.plist; 335 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 336 | PRODUCT_BUNDLE_IDENTIFIER = "com.al7dev.${PRODUCT_NAME:rfc1034identifier}"; 337 | PRODUCT_NAME = "$(TARGET_NAME)"; 338 | SWIFT_VERSION = 3.0; 339 | }; 340 | name = Release; 341 | }; 342 | 4CF842C819415DE3004DCFB6 /* Debug */ = { 343 | isa = XCBuildConfiguration; 344 | buildSettings = { 345 | BUNDLE_LOADER = "$(BUILT_PRODUCTS_DIR)/DateExtension.app/DateExtension"; 346 | FRAMEWORK_SEARCH_PATHS = ( 347 | "$(SDKROOT)/Developer/Library/Frameworks", 348 | "$(inherited)", 349 | ); 350 | GCC_PREPROCESSOR_DEFINITIONS = ( 351 | "DEBUG=1", 352 | "$(inherited)", 353 | ); 354 | INFOPLIST_FILE = DateExtensionTests/Info.plist; 355 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 356 | METAL_ENABLE_DEBUG_INFO = YES; 357 | PRODUCT_BUNDLE_IDENTIFIER = "com.al7dev.${PRODUCT_NAME:rfc1034identifier}"; 358 | PRODUCT_NAME = "$(TARGET_NAME)"; 359 | SWIFT_VERSION = 3.0; 360 | TEST_HOST = "$(BUNDLE_LOADER)"; 361 | }; 362 | name = Debug; 363 | }; 364 | 4CF842C919415DE3004DCFB6 /* Release */ = { 365 | isa = XCBuildConfiguration; 366 | buildSettings = { 367 | BUNDLE_LOADER = "$(BUILT_PRODUCTS_DIR)/DateExtension.app/DateExtension"; 368 | FRAMEWORK_SEARCH_PATHS = ( 369 | "$(SDKROOT)/Developer/Library/Frameworks", 370 | "$(inherited)", 371 | ); 372 | INFOPLIST_FILE = DateExtensionTests/Info.plist; 373 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 374 | METAL_ENABLE_DEBUG_INFO = NO; 375 | PRODUCT_BUNDLE_IDENTIFIER = "com.al7dev.${PRODUCT_NAME:rfc1034identifier}"; 376 | PRODUCT_NAME = "$(TARGET_NAME)"; 377 | SWIFT_VERSION = 3.0; 378 | TEST_HOST = "$(BUNDLE_LOADER)"; 379 | }; 380 | name = Release; 381 | }; 382 | /* End XCBuildConfiguration section */ 383 | 384 | /* Begin XCConfigurationList section */ 385 | 4CF842A819415DE3004DCFB6 /* Build configuration list for PBXProject "DateExtension" */ = { 386 | isa = XCConfigurationList; 387 | buildConfigurations = ( 388 | 4CF842C219415DE3004DCFB6 /* Debug */, 389 | 4CF842C319415DE3004DCFB6 /* Release */, 390 | ); 391 | defaultConfigurationIsVisible = 0; 392 | defaultConfigurationName = Release; 393 | }; 394 | 4CF842C419415DE3004DCFB6 /* Build configuration list for PBXNativeTarget "DateExtension" */ = { 395 | isa = XCConfigurationList; 396 | buildConfigurations = ( 397 | 4CF842C519415DE3004DCFB6 /* Debug */, 398 | 4CF842C619415DE3004DCFB6 /* Release */, 399 | ); 400 | defaultConfigurationIsVisible = 0; 401 | defaultConfigurationName = Release; 402 | }; 403 | 4CF842C719415DE3004DCFB6 /* Build configuration list for PBXNativeTarget "DateExtensionTests" */ = { 404 | isa = XCConfigurationList; 405 | buildConfigurations = ( 406 | 4CF842C819415DE3004DCFB6 /* Debug */, 407 | 4CF842C919415DE3004DCFB6 /* Release */, 408 | ); 409 | defaultConfigurationIsVisible = 0; 410 | defaultConfigurationName = Release; 411 | }; 412 | /* End XCConfigurationList section */ 413 | }; 414 | rootObject = 4CF842A519415DE3004DCFB6 /* Project object */; 415 | } 416 | -------------------------------------------------------------------------------- /DateExtension.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /DateExtension.xcodeproj/xcuserdata/aleite.xcuserdatad/xcschemes/DateExtension.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 33 | 39 | 40 | 41 | 42 | 43 | 49 | 50 | 51 | 52 | 61 | 62 | 68 | 69 | 70 | 71 | 72 | 73 | 79 | 80 | 86 | 87 | 88 | 89 | 91 | 92 | 95 | 96 | 97 | -------------------------------------------------------------------------------- /DateExtension.xcodeproj/xcuserdata/aleite.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | DateExtension.xcscheme 8 | 9 | orderHint 10 | 0 11 | 12 | 13 | SuppressBuildableAutocreation 14 | 15 | 4CF842AC19415DE3004DCFB6 16 | 17 | primary 18 | 19 | 20 | 4CF842B919415DE3004DCFB6 21 | 22 | primary 23 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /DateExtension/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.swift 3 | // DateExtension 4 | // 5 | // Created by Alex Leite on 6/5/14. 6 | // Copyright (c) 2014 al7dev. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | @UIApplicationMain 12 | class AppDelegate: UIResponder, UIApplicationDelegate { 13 | 14 | var window: UIWindow? 15 | 16 | func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: Any]?) -> Bool { 17 | self.window = UIWindow(frame: UIScreen.main.bounds) 18 | self.window!.rootViewController = UIViewController() 19 | self.window!.backgroundColor = UIColor.white 20 | self.window!.makeKeyAndVisible() 21 | return true 22 | } 23 | 24 | func applicationWillResignActive(_ application: UIApplication) { 25 | 26 | } 27 | 28 | func applicationDidEnterBackground(_ application: UIApplication) { 29 | 30 | } 31 | 32 | func applicationWillEnterForeground(_ application: UIApplication) { 33 | 34 | } 35 | 36 | func applicationDidBecomeActive(_ application: UIApplication) { 37 | 38 | } 39 | 40 | func applicationWillTerminate(_ application: UIApplication) { 41 | 42 | } 43 | 44 | } 45 | 46 | -------------------------------------------------------------------------------- /DateExtension/DateExtension.swift: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Copyright (c) 2015 - Alex Leite (al7dev) 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 13 | all 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 21 | THE SOFTWARE. 22 | 23 | */ 24 | 25 | import Foundation 26 | 27 | public extension Date { 28 | 29 | public func plus(seconds s: UInt) -> Date { 30 | return self.addComponentsToDate(seconds: Int(s), minutes: 0, hours: 0, days: 0, weeks: 0, months: 0, years: 0) 31 | } 32 | 33 | public func minus(seconds s: UInt) -> Date { 34 | return self.addComponentsToDate(seconds: -Int(s), minutes: 0, hours: 0, days: 0, weeks: 0, months: 0, years: 0) 35 | } 36 | 37 | public func plus(minutes m: UInt) -> Date { 38 | return self.addComponentsToDate(seconds: 0, minutes: Int(m), hours: 0, days: 0, weeks: 0, months: 0, years: 0) 39 | } 40 | 41 | public func minus(minutes m: UInt) -> Date { 42 | return self.addComponentsToDate(seconds: 0, minutes: -Int(m), hours: 0, days: 0, weeks: 0, months: 0, years: 0) 43 | } 44 | 45 | public func plus(hours h: UInt) -> Date { 46 | return self.addComponentsToDate(seconds: 0, minutes: 0, hours: Int(h), days: 0, weeks: 0, months: 0, years: 0) 47 | } 48 | 49 | public func minus(hours h: UInt) -> Date { 50 | return self.addComponentsToDate(seconds: 0, minutes: 0, hours: -Int(h), days: 0, weeks: 0, months: 0, years: 0) 51 | } 52 | 53 | public func plus(days d: UInt) -> Date { 54 | return self.addComponentsToDate(seconds: 0, minutes: 0, hours: 0, days: Int(d), weeks: 0, months: 0, years: 0) 55 | } 56 | 57 | public func minus(days d: UInt) -> Date { 58 | return self.addComponentsToDate(seconds: 0, minutes: 0, hours: 0, days: -Int(d), weeks: 0, months: 0, years: 0) 59 | } 60 | 61 | public func plus(weeks w: UInt) -> Date { 62 | return self.addComponentsToDate(seconds: 0, minutes: 0, hours: 0, days: 0, weeks: Int(w), months: 0, years: 0) 63 | } 64 | 65 | public func minus(weeks w: UInt) -> Date { 66 | return self.addComponentsToDate(seconds: 0, minutes: 0, hours: 0, days: 0, weeks: -Int(w), months: 0, years: 0) 67 | } 68 | 69 | public func plus(months m: UInt) -> Date { 70 | return self.addComponentsToDate(seconds: 0, minutes: 0, hours: 0, days: 0, weeks: 0, months: Int(m), years: 0) 71 | } 72 | 73 | public func minus(months m: UInt) -> Date { 74 | return self.addComponentsToDate(seconds: 0, minutes: 0, hours: 0, days: 0, weeks: 0, months: -Int(m), years: 0) 75 | } 76 | 77 | public func plus(years y: UInt) -> Date { 78 | return self.addComponentsToDate(seconds: 0, minutes: 0, hours: 0, days: 0, weeks: 0, months: 0, years: Int(y)) 79 | } 80 | 81 | public func minus(years y: UInt) -> Date { 82 | return self.addComponentsToDate(seconds: 0, minutes: 0, hours: 0, days: 0, weeks: 0, months: 0, years: -Int(y)) 83 | } 84 | 85 | fileprivate func addComponentsToDate(seconds sec: Int, minutes min: Int, hours hrs: Int, days d: Int, weeks wks: Int, months mts: Int, years yrs: Int) -> Date { 86 | var dc = DateComponents() 87 | dc.second = sec 88 | dc.minute = min 89 | dc.hour = hrs 90 | dc.day = d 91 | dc.weekOfYear = wks 92 | dc.month = mts 93 | dc.year = yrs 94 | return Calendar.current.date(byAdding: dc, to: self)! 95 | } 96 | 97 | public func midnightUTCDate() -> Date { 98 | var dc: DateComponents = Calendar.current.dateComponents([.year, .month, .day], from: self) 99 | dc.hour = 0 100 | dc.minute = 0 101 | dc.second = 0 102 | dc.nanosecond = 0 103 | dc.timeZone = TimeZone(secondsFromGMT: 0) 104 | return Calendar.current.date(from: dc)! 105 | } 106 | 107 | public static func secondsBetween(date1 d1:Date, date2 d2:Date) -> Int { 108 | let dc = Calendar.current.dateComponents([.second], from: d1, to: d2) 109 | return dc.second! 110 | } 111 | 112 | public static func minutesBetween(date1 d1: Date, date2 d2: Date) -> Int { 113 | let dc = Calendar.current.dateComponents([.minute], from: d1, to: d2) 114 | return dc.minute! 115 | } 116 | 117 | public static func hoursBetween(date1 d1: Date, date2 d2: Date) -> Int { 118 | let dc = Calendar.current.dateComponents([.hour], from: d1, to: d2) 119 | return dc.hour! 120 | } 121 | 122 | public static func daysBetween(date1 d1: Date, date2 d2: Date) -> Int { 123 | let dc = Calendar.current.dateComponents([.day], from: d1, to: d2) 124 | return dc.day! 125 | } 126 | 127 | public static func weeksBetween(date1 d1: Date, date2 d2: Date) -> Int { 128 | let dc = Calendar.current.dateComponents([.weekOfYear], from: d1, to: d2) 129 | return dc.weekOfYear! 130 | } 131 | 132 | public static func monthsBetween(date1 d1: Date, date2 d2: Date) -> Int { 133 | let dc = Calendar.current.dateComponents([.month], from: d1, to: d2) 134 | return dc.month! 135 | } 136 | 137 | public static func yearsBetween(date1 d1: Date, date2 d2: Date) -> Int { 138 | let dc = Calendar.current.dateComponents([.year], from: d1, to: d2) 139 | return dc.year! 140 | } 141 | 142 | //MARK- Comparison Methods 143 | 144 | public func isGreaterThan(_ date: Date) -> Bool { 145 | return (self.compare(date) == .orderedDescending) 146 | } 147 | 148 | public func isLessThan(_ date: Date) -> Bool { 149 | return (self.compare(date) == .orderedAscending) 150 | } 151 | 152 | //MARK- Computed Properties 153 | 154 | public var day: UInt { 155 | return UInt(Calendar.current.component(.day, from: self)) 156 | } 157 | 158 | public var month: UInt { 159 | return UInt(NSCalendar.current.component(.month, from: self)) 160 | } 161 | 162 | public var year: UInt { 163 | return UInt(NSCalendar.current.component(.year, from: self)) 164 | } 165 | 166 | public var hour: UInt { 167 | return UInt(NSCalendar.current.component(.hour, from: self)) 168 | } 169 | 170 | public var minute: UInt { 171 | return UInt(NSCalendar.current.component(.minute, from: self)) 172 | } 173 | 174 | public var second: UInt { 175 | return UInt(NSCalendar.current.component(.second, from: self)) 176 | } 177 | } 178 | -------------------------------------------------------------------------------- /DateExtension/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" : "40x40", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "iphone", 15 | "size" : "60x60", 16 | "scale" : "2x" 17 | } 18 | ], 19 | "info" : { 20 | "version" : 1, 21 | "author" : "xcode" 22 | } 23 | } -------------------------------------------------------------------------------- /DateExtension/Images.xcassets/LaunchImage.launchimage/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "orientation" : "portrait", 5 | "idiom" : "iphone", 6 | "extent" : "full-screen", 7 | "minimum-system-version" : "7.0", 8 | "scale" : "2x" 9 | }, 10 | { 11 | "orientation" : "portrait", 12 | "idiom" : "iphone", 13 | "subtype" : "retina4", 14 | "extent" : "full-screen", 15 | "minimum-system-version" : "7.0", 16 | "scale" : "2x" 17 | } 18 | ], 19 | "info" : { 20 | "version" : 1, 21 | "author" : "xcode" 22 | } 23 | } -------------------------------------------------------------------------------- /DateExtension/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | ${EXECUTABLE_NAME} 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | ${PRODUCT_NAME} 15 | CFBundlePackageType 16 | APPL 17 | CFBundleShortVersionString 18 | 0.0.2 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1 23 | LSRequiresIPhoneOS 24 | 25 | UIRequiredDeviceCapabilities 26 | 27 | armv7 28 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /DateExtensionTests/DateExtensionTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Created by Alex Leite on 6/5/14. 3 | // Copyright (c) 2014 al7dev. All rights reserved. 4 | // 5 | 6 | import XCTest 7 | 8 | class DateExtensionTests: XCTestCase { 9 | var today: Date? 10 | var fixedDate: Date? 11 | 12 | override func setUp() { 13 | super.setUp() 14 | // Put setup code here. This method is called before the invocation of each test method in the class. 15 | today = Date() 16 | 17 | var dateComponents = DateComponents() 18 | dateComponents.month = 10 19 | dateComponents.day = 10 20 | dateComponents.year = 2010 21 | dateComponents.hour = 10 22 | dateComponents.minute = 10 23 | dateComponents.second = 10 24 | dateComponents.calendar = NSCalendar.current 25 | fixedDate = dateComponents.date 26 | } 27 | 28 | override func tearDown() { 29 | // Put teardown code here. This method is called after the invocation of each test method in the class. 30 | today = nil 31 | fixedDate = nil 32 | 33 | super.tearDown() 34 | } 35 | 36 | func testSecondsBetween() { 37 | let testDate = today!.plus(minutes:1) 38 | let secsBetween = Date.secondsBetween(date1: today!, date2: testDate) 39 | XCTAssert(secsBetween == 60, "There should be 60 seconds between today and test date") 40 | } 41 | 42 | func testMinutesBetween() { 43 | let testDate = today!.plus(hours:2) 44 | let minBetween = Date.minutesBetween(date1: today!, date2: testDate) 45 | XCTAssert(minBetween == 120, "There should be 120 minutes between today and test date") 46 | } 47 | 48 | func testHoursBetween() { 49 | let testDate = today!.plus(days:1) 50 | let hoursBetween = Date.hoursBetween(date1: today!, date2: testDate) 51 | XCTAssert(hoursBetween == 24, "There should be 24 hours between today and test date") 52 | } 53 | 54 | func testDaysBetween() { 55 | let testDate = today!.plus(weeks:1) 56 | let daysBetween = Date.daysBetween(date1: today!, date2: testDate) 57 | XCTAssert(daysBetween == 7, "There should be 7 days between today and test date") 58 | } 59 | 60 | func testWeeksBetween() { 61 | let testDate = today!.plus(days:16) 62 | let weeksBetween = Date.weeksBetween(date1: today!, date2: testDate) 63 | XCTAssert(weeksBetween == 2, "There should be 2 weeks between today and test date") 64 | } 65 | 66 | func testMonthsBetween() { 67 | let testDate = today!.plus(days:65) 68 | let monthsBetween = Date.monthsBetween(date1: today!, date2: testDate) 69 | XCTAssert(monthsBetween == 2, "There should be 2 months between today and test date") 70 | } 71 | 72 | func testMonthsBetween2() { 73 | let testDate = today!.plus(months:2).minus(days:3) 74 | let monthsBetween = Date.monthsBetween(date1: today!, date2: testDate) 75 | XCTAssert(monthsBetween == 1, "There should be 1 month between today and test date") 76 | } 77 | 78 | func testYearsBetween() { 79 | let testDate = today!.plus(months:28) 80 | let yearsBetween = Date.yearsBetween(date1: today!, date2: testDate) 81 | XCTAssert(yearsBetween == 2, "There should be 2 years between today and test date") 82 | } 83 | 84 | func testDirectMonth() { 85 | var month: UInt = 0 86 | if let date = fixedDate { 87 | month = date.month 88 | } 89 | XCTAssert(month == 10, "Month should be 10") 90 | } 91 | 92 | func testDirectDay() { 93 | var day: UInt = 0 94 | if let date = fixedDate { 95 | day = date.day 96 | } 97 | XCTAssert(day == 10, "Day should be 10") 98 | } 99 | 100 | func testDirectYear() { 101 | var year: UInt = 0 102 | if let date = fixedDate { 103 | year = date.year 104 | } 105 | XCTAssert(year == 2010, "Year should be 2010") 106 | } 107 | 108 | func testDirectHour() { 109 | var hour: UInt = 0 110 | if let date = fixedDate { 111 | hour = date.hour 112 | } 113 | XCTAssert(hour == 10, "Month should be 10") 114 | } 115 | 116 | func testDirectMinute() { 117 | var minute: UInt = 0 118 | if let date = fixedDate { 119 | minute = date.minute 120 | } 121 | XCTAssert(minute == 10, "Minute should be 10") 122 | } 123 | 124 | func testDirectSecond() { 125 | var second: UInt = 0 126 | if let date = fixedDate { 127 | second = date.second 128 | } 129 | XCTAssert(second == 10, "Second should be 10") 130 | } 131 | 132 | func testGreaterComparison() { 133 | let now = Date() 134 | let then = now.minus(days:1) 135 | let greater = now.isGreaterThan(then) 136 | XCTAssert(greater == true, "Now should be greater than then") 137 | } 138 | 139 | func testLessComparison() { 140 | let now = Date() 141 | let tomorrow = now.plus(days:1) 142 | let lessThan = now.isLessThan(tomorrow) 143 | XCTAssert(lessThan == true, "Now should be less than tomorrow") 144 | } 145 | } 146 | -------------------------------------------------------------------------------- /DateExtensionTests/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | ${EXECUTABLE_NAME} 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 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 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2015 - Alex Leite (al7dev) 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy 4 | of this software and associated documentation files (the "Software"), to deal 5 | in the Software without restriction, including without limitation the rights 6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | copies of the Software, and to permit persons to whom the Software is 8 | furnished to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in 11 | all copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | THE SOFTWARE. 20 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Swift Date Extension 2 | ===================== 3 | 4 | ### About 5 | 6 | I wrote this little project a while ago, right after Apple announced Swift on WWDC'14. It was my first try of extensions in Swift. I decided to publish and add more goodies to it as time went by. This is an extension to the *Date* class. It includes some convenience methods that make it easier to manipulate and calculate time units to *Date* without having to use *DateComponents* directly. 7 | 8 | Here are a few examples of the things you can do: 9 | 10 | ```swift 11 | //-- Adding time units: 12 | 13 | let date1 = Date().plus(months: 2).minus(days: 5).plus(seconds: 5) 14 | let date2 = Date().plus(years: 1).minus(months: 6) 15 | 16 | //-- Calculating difference between dates: 17 | 18 | let weeksBetween = Date.monthsBetween(date1: someDate, date2: someOtherDate) 19 | let monthsBetween = Date.weeksBetween(date1: someDate, date2: someOtherDate) 20 | 21 | //-- Direct access to calendar units: 22 | 23 | let year = Date().year 24 | let month = Date().month 25 | let seconds = Date().seconds 26 | 27 | //-- Comparing two dates: 28 | 29 | let now = Date() 30 | let then = now.minus(days: 1) 31 | 32 | let comparison1: Bool = now.isGreaterThan(then) //-- true 33 | let comparison2: Bool = now.isLessThan(then) //-- false 34 | 35 | ``` 36 | 37 | I'm trying to keep this up to date. Right now, it's fully compliant to **Swift 3.0**. Feel free to use this sample however you see fit. I hope you find this helpful when venturing through Swift. 38 | 39 | ### How to use 40 | 41 | You can simply include the ``DateExtension.swift`` file to your project. To make your life easier, you can also use CocoaPods. Simply add the following line to your Podfile: 42 | 43 | ``` 44 | pod 'SwiftDateExtension' 45 | ``` 46 | 47 | #### License 48 | 49 | This component is available under MIT license. 50 | -------------------------------------------------------------------------------- /SwiftDateExtension.podspec: -------------------------------------------------------------------------------- 1 | Pod::Spec.new do |s| 2 | 3 | s.name = "SwiftDateExtension" 4 | s.version = "0.0.6" 5 | s.summary = "Date extension in Swift" 6 | s.license = "MIT" 7 | s.homepage = "http://github.com/al7/SwiftDateExtension" 8 | s.author = { "Alex Leite" => "admin@al7dev.com" } 9 | s.platform = :ios, "8.0" 10 | s.source = { :git => "https://github.com/al7/SwiftDateExtension.git", :tag => "0.0.6" } 11 | s.source_files = "DateExtension/DateExtension.swift" 12 | s.requires_arc = true 13 | s.xcconfig = { 14 | 'SWIFT_VERSION' => '3.0' 15 | } 16 | end 17 | --------------------------------------------------------------------------------