├── LICENSE ├── README.md ├── Screenshot ├── cut1.png ├── cut2.png ├── cut3.png ├── cut4.png ├── cut5.png └── screen1.png ├── XHDatePicker.podspec ├── XHDatePicker.xcodeproj ├── project.pbxproj ├── project.xcworkspace │ ├── contents.xcworkspacedata │ ├── xcshareddata │ │ └── IDEWorkspaceChecks.plist │ └── xcuserdata │ │ └── jiangxinhua.xcuserdatad │ │ └── UserInterfaceState.xcuserstate └── xcuserdata │ └── jiangxinhua.xcuserdatad │ ├── xcdebugger │ └── Breakpoints_v2.xcbkptlist │ └── xcschemes │ ├── XHDatePicker.xcscheme │ └── xcschememanagement.plist ├── XHDatePicker ├── NSDate+XHExtension.h ├── NSDate+XHExtension.m ├── XHDatePicker.h ├── XHDatePicker.m └── XHDatePicker.xib ├── XHDatePickerTests ├── Info.plist └── XHDatePickerTests.m ├── XHDatePickerUITests ├── Info.plist └── XHDatePickerUITests.m └── XHDatePicker_demo ├── AppDelegate.h ├── AppDelegate.m ├── Assets.xcassets ├── AppIcon.appiconset │ └── Contents.json ├── Contents.json ├── selected.imageset │ ├── Contents.json │ ├── 选中全天.png │ ├── 选中全天@2x.png │ └── 选中全天@3x.png └── unSelected.imageset │ ├── Contents.json │ ├── 未选中.png │ ├── 未选中@2x.png │ └── 未选中@3x.png ├── Base.lproj └── Main.storyboard ├── Info.plist ├── TableViewController.h ├── TableViewController.m └── main.m /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 XH_J 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 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # XHDatePicker 日期选择器 2 | ![日期选择器](https://github.com/XHJCoder/XHDatePicker/blob/master/Screenshot/screen1.png) 3 | ## Version【版本】 4 | v0.1.3 5 | 6 | ## Installation【安装】 7 | 8 | 在Podfile文件中添加``` pod 'XHDatePicker'``` ,并运行 ```pod install``` 9 | 10 | ## Usage【使用】 11 | - 导入 12 | ``` 13 | #import "XHDatePicker.h" 14 | ``` 15 | 16 | - 生成对象并展示 17 | ``` 18 | /** 19 | @param completeBlock 时间选择好之后的回调,返回选择的时间和时间的String值 20 | */ 21 | + (instancetype)showWithCompleteBlock:(void(^)(NSDate *date, NSString *dateString))completeBlock; 22 | ``` 23 | 24 | - 设置日期选择器样式 25 | ``` 26 | typedef enum { 27 | XHDatePickerModeYearMonthDayHourMinute = 0, // 年月日时分 28 | XHDatePickerModeMonthDayHourMinute, // 月日时分 29 | XHDatePickerModeYearMonthDay, // 年月日 30 | XHDatePickerModeYearMonth, // 年月 31 | XHDatePickerModeMonthDay, // 月日 32 | XHDatePickerModeHourMinute // 时分 33 | } XHDatePickerMode; 34 | 35 | // default is XHDatePickerModeYearMonthDayHourMinute 36 | @property (nonatomic, assign) XHDatePickerMode datePickerMode; 37 | ``` 38 | 39 | - 设置最大最小时间限制 40 | ``` 41 | @property (nonatomic, strong) NSDate *minimumDate; // 限制最大时间(default is nil) 42 | @property (nonatomic, strong) NSDate *maximumDate; // 限制最小时间(default is nil) 43 | ``` 44 | 45 | - 设置当前显示时间 46 | ``` 47 | @property (nonatomic, strong) NSDate *date; // 当前显示时间(default is [NSDate date]) 48 | ``` 49 | 50 | - 设置主题色 51 | ``` 52 | @property (nonatomic, strong) UIColor *themeColor; 53 | ``` 54 | 55 | - 设置时间格式(体现在completeBlock返回的dateString上) 56 | ``` 57 | /** 58 | * 默认与datePickerMode相对应 59 | * 比如:XHDatePickerModeYearMonthDayHourMinute对应的dateFormatter是:@"yyyy-MM-dd HH:mm" 60 | * 你也可以设置格式为 yyyy年MM月dd日HH时mm分 61 | */ 62 | @property (nonatomic, copy) NSString *dateFormatter; 63 | ``` 64 | 65 | ## Example【示例】 66 | ``` 67 | XHDatePicker *datePicker = [XHDatePicker showWithCompleteBlock:^(NSDate *date, NSString *dateString) { 68 | NSLog(@"%@ , %@",date, dateString); 69 | }]; 70 | 71 | datePicker.date = [NSDate date:@"2018-05-13 22:55" WithFormat:@"yyyy-MM-dd HH:mm"]; 72 | datePicker.minimumDate = [NSDate date:@"2015-01-14 12:14" WithFormat:@"yyyy-MM-dd HH:mm"]; 73 | datePicker.maximumDate = [NSDate date:@"2022-11-23 07:55" WithFormat:@"yyyy-MM-dd HH:mm"]; 74 | datePicker.themeColor = [UIColor redColor]; 75 | datePicker.dateFormatter = @"yyyy年MM月dd日 HH:mm"; 76 | datePicker.datePickerMode = XHDatePickerModeYearMonthDayHourMinute; 77 | ``` 78 | 79 | 80 | -------------------------------------------------------------------------------- /Screenshot/cut1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/XHJCoder/XHDatePicker/01c09a9f77bcacf40beb5af44070a192a9d688ed/Screenshot/cut1.png -------------------------------------------------------------------------------- /Screenshot/cut2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/XHJCoder/XHDatePicker/01c09a9f77bcacf40beb5af44070a192a9d688ed/Screenshot/cut2.png -------------------------------------------------------------------------------- /Screenshot/cut3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/XHJCoder/XHDatePicker/01c09a9f77bcacf40beb5af44070a192a9d688ed/Screenshot/cut3.png -------------------------------------------------------------------------------- /Screenshot/cut4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/XHJCoder/XHDatePicker/01c09a9f77bcacf40beb5af44070a192a9d688ed/Screenshot/cut4.png -------------------------------------------------------------------------------- /Screenshot/cut5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/XHJCoder/XHDatePicker/01c09a9f77bcacf40beb5af44070a192a9d688ed/Screenshot/cut5.png -------------------------------------------------------------------------------- /Screenshot/screen1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/XHJCoder/XHDatePicker/01c09a9f77bcacf40beb5af44070a192a9d688ed/Screenshot/screen1.png -------------------------------------------------------------------------------- /XHDatePicker.podspec: -------------------------------------------------------------------------------- 1 | 2 | Pod::Spec.new do |s| 3 | 4 | s.name = "XHDatePicker" 5 | s.version = "0.1.3" 6 | s.summary = "日期选择器 for iOS." 7 | s.homepage = "https://github.com/XHJCoder/XHDatePicker" 8 | s.license = "MIT" 9 | s.author = { "XH_J" => "1149949564@qq.com" } 10 | s.platform = :ios, "8.0" 11 | s.source = { :git => "https://github.com/XHJCoder/XHDatePicker.git", :tag => "#{s.version}" } 12 | s.source_files = "XHDatePicker","XHDatePicker/**/*.{h,m,xib}" 13 | s.framework = "UIKit" 14 | 15 | end 16 | -------------------------------------------------------------------------------- /XHDatePicker.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 2F0A1CB11D631A7F00AFBEC2 /* XHDatePickerTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 2F0A1CB01D631A7F00AFBEC2 /* XHDatePickerTests.m */; }; 11 | 2F0A1CBC1D631A7F00AFBEC2 /* XHDatePickerUITests.m in Sources */ = {isa = PBXBuildFile; fileRef = 2F0A1CBB1D631A7F00AFBEC2 /* XHDatePickerUITests.m */; }; 12 | 2F0B24CF1F53F04B009D1BD8 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 2F0B24C31F53F04B009D1BD8 /* AppDelegate.m */; }; 13 | 2F0B24D01F53F04B009D1BD8 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 2F0B24C41F53F04B009D1BD8 /* Assets.xcassets */; }; 14 | 2F0B24D21F53F04B009D1BD8 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 2F0B24C71F53F04B009D1BD8 /* Main.storyboard */; }; 15 | 2F0B24D31F53F04B009D1BD8 /* Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = 2F0B24C91F53F04B009D1BD8 /* Info.plist */; }; 16 | 2F0B24D41F53F04B009D1BD8 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 2F0B24CA1F53F04B009D1BD8 /* main.m */; }; 17 | 2F0B24F91F54050E009D1BD8 /* NSDate+XHExtension.m in Sources */ = {isa = PBXBuildFile; fileRef = 2F0B24F51F54050E009D1BD8 /* NSDate+XHExtension.m */; }; 18 | 2F0B24FA1F54050E009D1BD8 /* XHDatePicker.m in Sources */ = {isa = PBXBuildFile; fileRef = 2F0B24F71F54050E009D1BD8 /* XHDatePicker.m */; }; 19 | 2F0B24FB1F54050E009D1BD8 /* XHDatePicker.xib in Resources */ = {isa = PBXBuildFile; fileRef = 2F0B24F81F54050E009D1BD8 /* XHDatePicker.xib */; }; 20 | 2F551580207CC33100540676 /* TableViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 2F55157F207CC33100540676 /* TableViewController.m */; }; 21 | /* End PBXBuildFile section */ 22 | 23 | /* Begin PBXContainerItemProxy section */ 24 | 2F0A1CAD1D631A7F00AFBEC2 /* PBXContainerItemProxy */ = { 25 | isa = PBXContainerItemProxy; 26 | containerPortal = 2F0A1C8B1D631A7E00AFBEC2 /* Project object */; 27 | proxyType = 1; 28 | remoteGlobalIDString = 2F0A1C921D631A7E00AFBEC2; 29 | remoteInfo = XHDatePicker; 30 | }; 31 | 2F0A1CB81D631A7F00AFBEC2 /* PBXContainerItemProxy */ = { 32 | isa = PBXContainerItemProxy; 33 | containerPortal = 2F0A1C8B1D631A7E00AFBEC2 /* Project object */; 34 | proxyType = 1; 35 | remoteGlobalIDString = 2F0A1C921D631A7E00AFBEC2; 36 | remoteInfo = XHDatePicker; 37 | }; 38 | /* End PBXContainerItemProxy section */ 39 | 40 | /* Begin PBXFileReference section */ 41 | 2F0A1C931D631A7E00AFBEC2 /* XHDatePicker.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = XHDatePicker.app; sourceTree = BUILT_PRODUCTS_DIR; }; 42 | 2F0A1CAC1D631A7F00AFBEC2 /* XHDatePickerTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = XHDatePickerTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 43 | 2F0A1CB01D631A7F00AFBEC2 /* XHDatePickerTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = XHDatePickerTests.m; sourceTree = ""; }; 44 | 2F0A1CB21D631A7F00AFBEC2 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 45 | 2F0A1CB71D631A7F00AFBEC2 /* XHDatePickerUITests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = XHDatePickerUITests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 46 | 2F0A1CBB1D631A7F00AFBEC2 /* XHDatePickerUITests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = XHDatePickerUITests.m; sourceTree = ""; }; 47 | 2F0A1CBD1D631A7F00AFBEC2 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 48 | 2F0B24C21F53F04B009D1BD8 /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; 49 | 2F0B24C31F53F04B009D1BD8 /* AppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; 50 | 2F0B24C41F53F04B009D1BD8 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 51 | 2F0B24C81F53F04B009D1BD8 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; 52 | 2F0B24C91F53F04B009D1BD8 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 53 | 2F0B24CA1F53F04B009D1BD8 /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; 54 | 2F0B24F41F54050E009D1BD8 /* NSDate+XHExtension.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSDate+XHExtension.h"; sourceTree = ""; }; 55 | 2F0B24F51F54050E009D1BD8 /* NSDate+XHExtension.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSDate+XHExtension.m"; sourceTree = ""; }; 56 | 2F0B24F61F54050E009D1BD8 /* XHDatePicker.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = XHDatePicker.h; sourceTree = ""; }; 57 | 2F0B24F71F54050E009D1BD8 /* XHDatePicker.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = XHDatePicker.m; sourceTree = ""; }; 58 | 2F0B24F81F54050E009D1BD8 /* XHDatePicker.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = XHDatePicker.xib; sourceTree = ""; }; 59 | 2F55157E207CC33100540676 /* TableViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = TableViewController.h; sourceTree = ""; }; 60 | 2F55157F207CC33100540676 /* TableViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = TableViewController.m; sourceTree = ""; }; 61 | /* End PBXFileReference section */ 62 | 63 | /* Begin PBXFrameworksBuildPhase section */ 64 | 2F0A1C901D631A7E00AFBEC2 /* Frameworks */ = { 65 | isa = PBXFrameworksBuildPhase; 66 | buildActionMask = 2147483647; 67 | files = ( 68 | ); 69 | runOnlyForDeploymentPostprocessing = 0; 70 | }; 71 | 2F0A1CA91D631A7F00AFBEC2 /* Frameworks */ = { 72 | isa = PBXFrameworksBuildPhase; 73 | buildActionMask = 2147483647; 74 | files = ( 75 | ); 76 | runOnlyForDeploymentPostprocessing = 0; 77 | }; 78 | 2F0A1CB41D631A7F00AFBEC2 /* Frameworks */ = { 79 | isa = PBXFrameworksBuildPhase; 80 | buildActionMask = 2147483647; 81 | files = ( 82 | ); 83 | runOnlyForDeploymentPostprocessing = 0; 84 | }; 85 | /* End PBXFrameworksBuildPhase section */ 86 | 87 | /* Begin PBXGroup section */ 88 | 2F0A1C8A1D631A7E00AFBEC2 = { 89 | isa = PBXGroup; 90 | children = ( 91 | 2F0B24F31F54050E009D1BD8 /* XHDatePicker */, 92 | 2F0B24C11F53F04B009D1BD8 /* XHDatePicker_demo */, 93 | 2F0A1CAF1D631A7F00AFBEC2 /* XHDatePickerTests */, 94 | 2F0A1CBA1D631A7F00AFBEC2 /* XHDatePickerUITests */, 95 | 2F0A1C941D631A7E00AFBEC2 /* Products */, 96 | ); 97 | sourceTree = ""; 98 | }; 99 | 2F0A1C941D631A7E00AFBEC2 /* Products */ = { 100 | isa = PBXGroup; 101 | children = ( 102 | 2F0A1C931D631A7E00AFBEC2 /* XHDatePicker.app */, 103 | 2F0A1CAC1D631A7F00AFBEC2 /* XHDatePickerTests.xctest */, 104 | 2F0A1CB71D631A7F00AFBEC2 /* XHDatePickerUITests.xctest */, 105 | ); 106 | name = Products; 107 | sourceTree = ""; 108 | }; 109 | 2F0A1CAF1D631A7F00AFBEC2 /* XHDatePickerTests */ = { 110 | isa = PBXGroup; 111 | children = ( 112 | 2F0A1CB01D631A7F00AFBEC2 /* XHDatePickerTests.m */, 113 | 2F0A1CB21D631A7F00AFBEC2 /* Info.plist */, 114 | ); 115 | path = XHDatePickerTests; 116 | sourceTree = ""; 117 | }; 118 | 2F0A1CBA1D631A7F00AFBEC2 /* XHDatePickerUITests */ = { 119 | isa = PBXGroup; 120 | children = ( 121 | 2F0A1CBB1D631A7F00AFBEC2 /* XHDatePickerUITests.m */, 122 | 2F0A1CBD1D631A7F00AFBEC2 /* Info.plist */, 123 | ); 124 | path = XHDatePickerUITests; 125 | sourceTree = ""; 126 | }; 127 | 2F0B24C11F53F04B009D1BD8 /* XHDatePicker_demo */ = { 128 | isa = PBXGroup; 129 | children = ( 130 | 2F0B24C21F53F04B009D1BD8 /* AppDelegate.h */, 131 | 2F0B24C31F53F04B009D1BD8 /* AppDelegate.m */, 132 | 2F55157E207CC33100540676 /* TableViewController.h */, 133 | 2F55157F207CC33100540676 /* TableViewController.m */, 134 | 2F0B24C41F53F04B009D1BD8 /* Assets.xcassets */, 135 | 2F0B24C71F53F04B009D1BD8 /* Main.storyboard */, 136 | 2F0B24C91F53F04B009D1BD8 /* Info.plist */, 137 | 2F0B24CA1F53F04B009D1BD8 /* main.m */, 138 | ); 139 | path = XHDatePicker_demo; 140 | sourceTree = ""; 141 | }; 142 | 2F0B24F31F54050E009D1BD8 /* XHDatePicker */ = { 143 | isa = PBXGroup; 144 | children = ( 145 | 2F0B24F41F54050E009D1BD8 /* NSDate+XHExtension.h */, 146 | 2F0B24F51F54050E009D1BD8 /* NSDate+XHExtension.m */, 147 | 2F0B24F61F54050E009D1BD8 /* XHDatePicker.h */, 148 | 2F0B24F71F54050E009D1BD8 /* XHDatePicker.m */, 149 | 2F0B24F81F54050E009D1BD8 /* XHDatePicker.xib */, 150 | ); 151 | path = XHDatePicker; 152 | sourceTree = ""; 153 | }; 154 | /* End PBXGroup section */ 155 | 156 | /* Begin PBXNativeTarget section */ 157 | 2F0A1C921D631A7E00AFBEC2 /* XHDatePicker */ = { 158 | isa = PBXNativeTarget; 159 | buildConfigurationList = 2F0A1CC01D631A7F00AFBEC2 /* Build configuration list for PBXNativeTarget "XHDatePicker" */; 160 | buildPhases = ( 161 | 2F0A1C8F1D631A7E00AFBEC2 /* Sources */, 162 | 2F0A1C901D631A7E00AFBEC2 /* Frameworks */, 163 | 2F0A1C911D631A7E00AFBEC2 /* Resources */, 164 | ); 165 | buildRules = ( 166 | ); 167 | dependencies = ( 168 | ); 169 | name = XHDatePicker; 170 | productName = XHDatePicker; 171 | productReference = 2F0A1C931D631A7E00AFBEC2 /* XHDatePicker.app */; 172 | productType = "com.apple.product-type.application"; 173 | }; 174 | 2F0A1CAB1D631A7F00AFBEC2 /* XHDatePickerTests */ = { 175 | isa = PBXNativeTarget; 176 | buildConfigurationList = 2F0A1CC31D631A7F00AFBEC2 /* Build configuration list for PBXNativeTarget "XHDatePickerTests" */; 177 | buildPhases = ( 178 | 2F0A1CA81D631A7F00AFBEC2 /* Sources */, 179 | 2F0A1CA91D631A7F00AFBEC2 /* Frameworks */, 180 | 2F0A1CAA1D631A7F00AFBEC2 /* Resources */, 181 | ); 182 | buildRules = ( 183 | ); 184 | dependencies = ( 185 | 2F0A1CAE1D631A7F00AFBEC2 /* PBXTargetDependency */, 186 | ); 187 | name = XHDatePickerTests; 188 | productName = XHDatePickerTests; 189 | productReference = 2F0A1CAC1D631A7F00AFBEC2 /* XHDatePickerTests.xctest */; 190 | productType = "com.apple.product-type.bundle.unit-test"; 191 | }; 192 | 2F0A1CB61D631A7F00AFBEC2 /* XHDatePickerUITests */ = { 193 | isa = PBXNativeTarget; 194 | buildConfigurationList = 2F0A1CC61D631A7F00AFBEC2 /* Build configuration list for PBXNativeTarget "XHDatePickerUITests" */; 195 | buildPhases = ( 196 | 2F0A1CB31D631A7F00AFBEC2 /* Sources */, 197 | 2F0A1CB41D631A7F00AFBEC2 /* Frameworks */, 198 | 2F0A1CB51D631A7F00AFBEC2 /* Resources */, 199 | ); 200 | buildRules = ( 201 | ); 202 | dependencies = ( 203 | 2F0A1CB91D631A7F00AFBEC2 /* PBXTargetDependency */, 204 | ); 205 | name = XHDatePickerUITests; 206 | productName = XHDatePickerUITests; 207 | productReference = 2F0A1CB71D631A7F00AFBEC2 /* XHDatePickerUITests.xctest */; 208 | productType = "com.apple.product-type.bundle.ui-testing"; 209 | }; 210 | /* End PBXNativeTarget section */ 211 | 212 | /* Begin PBXProject section */ 213 | 2F0A1C8B1D631A7E00AFBEC2 /* Project object */ = { 214 | isa = PBXProject; 215 | attributes = { 216 | LastUpgradeCheck = 0730; 217 | ORGANIZATIONNAME = "江欣华"; 218 | TargetAttributes = { 219 | 2F0A1C921D631A7E00AFBEC2 = { 220 | CreatedOnToolsVersion = 7.3.1; 221 | DevelopmentTeam = 2444ZSL97S; 222 | }; 223 | 2F0A1CAB1D631A7F00AFBEC2 = { 224 | CreatedOnToolsVersion = 7.3.1; 225 | TestTargetID = 2F0A1C921D631A7E00AFBEC2; 226 | }; 227 | 2F0A1CB61D631A7F00AFBEC2 = { 228 | CreatedOnToolsVersion = 7.3.1; 229 | TestTargetID = 2F0A1C921D631A7E00AFBEC2; 230 | }; 231 | }; 232 | }; 233 | buildConfigurationList = 2F0A1C8E1D631A7E00AFBEC2 /* Build configuration list for PBXProject "XHDatePicker" */; 234 | compatibilityVersion = "Xcode 3.2"; 235 | developmentRegion = English; 236 | hasScannedForEncodings = 0; 237 | knownRegions = ( 238 | en, 239 | Base, 240 | ); 241 | mainGroup = 2F0A1C8A1D631A7E00AFBEC2; 242 | productRefGroup = 2F0A1C941D631A7E00AFBEC2 /* Products */; 243 | projectDirPath = ""; 244 | projectRoot = ""; 245 | targets = ( 246 | 2F0A1C921D631A7E00AFBEC2 /* XHDatePicker */, 247 | 2F0A1CAB1D631A7F00AFBEC2 /* XHDatePickerTests */, 248 | 2F0A1CB61D631A7F00AFBEC2 /* XHDatePickerUITests */, 249 | ); 250 | }; 251 | /* End PBXProject section */ 252 | 253 | /* Begin PBXResourcesBuildPhase section */ 254 | 2F0A1C911D631A7E00AFBEC2 /* Resources */ = { 255 | isa = PBXResourcesBuildPhase; 256 | buildActionMask = 2147483647; 257 | files = ( 258 | 2F0B24FB1F54050E009D1BD8 /* XHDatePicker.xib in Resources */, 259 | 2F0B24D31F53F04B009D1BD8 /* Info.plist in Resources */, 260 | 2F0B24D21F53F04B009D1BD8 /* Main.storyboard in Resources */, 261 | 2F0B24D01F53F04B009D1BD8 /* Assets.xcassets in Resources */, 262 | ); 263 | runOnlyForDeploymentPostprocessing = 0; 264 | }; 265 | 2F0A1CAA1D631A7F00AFBEC2 /* Resources */ = { 266 | isa = PBXResourcesBuildPhase; 267 | buildActionMask = 2147483647; 268 | files = ( 269 | ); 270 | runOnlyForDeploymentPostprocessing = 0; 271 | }; 272 | 2F0A1CB51D631A7F00AFBEC2 /* Resources */ = { 273 | isa = PBXResourcesBuildPhase; 274 | buildActionMask = 2147483647; 275 | files = ( 276 | ); 277 | runOnlyForDeploymentPostprocessing = 0; 278 | }; 279 | /* End PBXResourcesBuildPhase section */ 280 | 281 | /* Begin PBXSourcesBuildPhase section */ 282 | 2F0A1C8F1D631A7E00AFBEC2 /* Sources */ = { 283 | isa = PBXSourcesBuildPhase; 284 | buildActionMask = 2147483647; 285 | files = ( 286 | 2F0B24D41F53F04B009D1BD8 /* main.m in Sources */, 287 | 2F551580207CC33100540676 /* TableViewController.m in Sources */, 288 | 2F0B24CF1F53F04B009D1BD8 /* AppDelegate.m in Sources */, 289 | 2F0B24F91F54050E009D1BD8 /* NSDate+XHExtension.m in Sources */, 290 | 2F0B24FA1F54050E009D1BD8 /* XHDatePicker.m in Sources */, 291 | ); 292 | runOnlyForDeploymentPostprocessing = 0; 293 | }; 294 | 2F0A1CA81D631A7F00AFBEC2 /* Sources */ = { 295 | isa = PBXSourcesBuildPhase; 296 | buildActionMask = 2147483647; 297 | files = ( 298 | 2F0A1CB11D631A7F00AFBEC2 /* XHDatePickerTests.m in Sources */, 299 | ); 300 | runOnlyForDeploymentPostprocessing = 0; 301 | }; 302 | 2F0A1CB31D631A7F00AFBEC2 /* Sources */ = { 303 | isa = PBXSourcesBuildPhase; 304 | buildActionMask = 2147483647; 305 | files = ( 306 | 2F0A1CBC1D631A7F00AFBEC2 /* XHDatePickerUITests.m in Sources */, 307 | ); 308 | runOnlyForDeploymentPostprocessing = 0; 309 | }; 310 | /* End PBXSourcesBuildPhase section */ 311 | 312 | /* Begin PBXTargetDependency section */ 313 | 2F0A1CAE1D631A7F00AFBEC2 /* PBXTargetDependency */ = { 314 | isa = PBXTargetDependency; 315 | target = 2F0A1C921D631A7E00AFBEC2 /* XHDatePicker */; 316 | targetProxy = 2F0A1CAD1D631A7F00AFBEC2 /* PBXContainerItemProxy */; 317 | }; 318 | 2F0A1CB91D631A7F00AFBEC2 /* PBXTargetDependency */ = { 319 | isa = PBXTargetDependency; 320 | target = 2F0A1C921D631A7E00AFBEC2 /* XHDatePicker */; 321 | targetProxy = 2F0A1CB81D631A7F00AFBEC2 /* PBXContainerItemProxy */; 322 | }; 323 | /* End PBXTargetDependency section */ 324 | 325 | /* Begin PBXVariantGroup section */ 326 | 2F0B24C71F53F04B009D1BD8 /* Main.storyboard */ = { 327 | isa = PBXVariantGroup; 328 | children = ( 329 | 2F0B24C81F53F04B009D1BD8 /* Base */, 330 | ); 331 | name = Main.storyboard; 332 | sourceTree = ""; 333 | }; 334 | /* End PBXVariantGroup section */ 335 | 336 | /* Begin XCBuildConfiguration section */ 337 | 2F0A1CBE1D631A7F00AFBEC2 /* Debug */ = { 338 | isa = XCBuildConfiguration; 339 | buildSettings = { 340 | ALWAYS_SEARCH_USER_PATHS = NO; 341 | CLANG_ANALYZER_NONNULL = YES; 342 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 343 | CLANG_CXX_LIBRARY = "libc++"; 344 | CLANG_ENABLE_MODULES = YES; 345 | CLANG_ENABLE_OBJC_ARC = YES; 346 | CLANG_WARN_BOOL_CONVERSION = YES; 347 | CLANG_WARN_CONSTANT_CONVERSION = YES; 348 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 349 | CLANG_WARN_EMPTY_BODY = YES; 350 | CLANG_WARN_ENUM_CONVERSION = YES; 351 | CLANG_WARN_INT_CONVERSION = YES; 352 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 353 | CLANG_WARN_UNREACHABLE_CODE = YES; 354 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 355 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 356 | COPY_PHASE_STRIP = NO; 357 | DEBUG_INFORMATION_FORMAT = dwarf; 358 | ENABLE_STRICT_OBJC_MSGSEND = YES; 359 | ENABLE_TESTABILITY = YES; 360 | GCC_C_LANGUAGE_STANDARD = gnu99; 361 | GCC_DYNAMIC_NO_PIC = NO; 362 | GCC_NO_COMMON_BLOCKS = YES; 363 | GCC_OPTIMIZATION_LEVEL = 0; 364 | GCC_PREPROCESSOR_DEFINITIONS = ( 365 | "DEBUG=1", 366 | "$(inherited)", 367 | ); 368 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 369 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 370 | GCC_WARN_UNDECLARED_SELECTOR = YES; 371 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 372 | GCC_WARN_UNUSED_FUNCTION = YES; 373 | GCC_WARN_UNUSED_VARIABLE = YES; 374 | IPHONEOS_DEPLOYMENT_TARGET = 9.3; 375 | MTL_ENABLE_DEBUG_INFO = YES; 376 | ONLY_ACTIVE_ARCH = YES; 377 | SDKROOT = iphoneos; 378 | TARGETED_DEVICE_FAMILY = "1,2"; 379 | }; 380 | name = Debug; 381 | }; 382 | 2F0A1CBF1D631A7F00AFBEC2 /* Release */ = { 383 | isa = XCBuildConfiguration; 384 | buildSettings = { 385 | ALWAYS_SEARCH_USER_PATHS = NO; 386 | CLANG_ANALYZER_NONNULL = YES; 387 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 388 | CLANG_CXX_LIBRARY = "libc++"; 389 | CLANG_ENABLE_MODULES = YES; 390 | CLANG_ENABLE_OBJC_ARC = YES; 391 | CLANG_WARN_BOOL_CONVERSION = YES; 392 | CLANG_WARN_CONSTANT_CONVERSION = YES; 393 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 394 | CLANG_WARN_EMPTY_BODY = YES; 395 | CLANG_WARN_ENUM_CONVERSION = YES; 396 | CLANG_WARN_INT_CONVERSION = YES; 397 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 398 | CLANG_WARN_UNREACHABLE_CODE = YES; 399 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 400 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 401 | COPY_PHASE_STRIP = NO; 402 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 403 | ENABLE_NS_ASSERTIONS = NO; 404 | ENABLE_STRICT_OBJC_MSGSEND = YES; 405 | GCC_C_LANGUAGE_STANDARD = gnu99; 406 | GCC_NO_COMMON_BLOCKS = YES; 407 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 408 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 409 | GCC_WARN_UNDECLARED_SELECTOR = YES; 410 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 411 | GCC_WARN_UNUSED_FUNCTION = YES; 412 | GCC_WARN_UNUSED_VARIABLE = YES; 413 | IPHONEOS_DEPLOYMENT_TARGET = 9.3; 414 | MTL_ENABLE_DEBUG_INFO = NO; 415 | SDKROOT = iphoneos; 416 | TARGETED_DEVICE_FAMILY = "1,2"; 417 | VALIDATE_PRODUCT = YES; 418 | }; 419 | name = Release; 420 | }; 421 | 2F0A1CC11D631A7F00AFBEC2 /* Debug */ = { 422 | isa = XCBuildConfiguration; 423 | buildSettings = { 424 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 425 | DEVELOPMENT_TEAM = 2444ZSL97S; 426 | INFOPLIST_FILE = XHDatePicker_demo/Info.plist; 427 | IPHONEOS_DEPLOYMENT_TARGET = 8.0; 428 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 429 | PRODUCT_BUNDLE_IDENTIFIER = com.xhj.XHDatePicker; 430 | PRODUCT_NAME = "$(TARGET_NAME)"; 431 | }; 432 | name = Debug; 433 | }; 434 | 2F0A1CC21D631A7F00AFBEC2 /* Release */ = { 435 | isa = XCBuildConfiguration; 436 | buildSettings = { 437 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 438 | DEVELOPMENT_TEAM = 2444ZSL97S; 439 | INFOPLIST_FILE = XHDatePicker_demo/Info.plist; 440 | IPHONEOS_DEPLOYMENT_TARGET = 8.0; 441 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 442 | PRODUCT_BUNDLE_IDENTIFIER = com.xhj.XHDatePicker; 443 | PRODUCT_NAME = "$(TARGET_NAME)"; 444 | }; 445 | name = Release; 446 | }; 447 | 2F0A1CC41D631A7F00AFBEC2 /* Debug */ = { 448 | isa = XCBuildConfiguration; 449 | buildSettings = { 450 | BUNDLE_LOADER = "$(TEST_HOST)"; 451 | INFOPLIST_FILE = XHDatePickerTests/Info.plist; 452 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 453 | PRODUCT_BUNDLE_IDENTIFIER = com.weker.XHDatePickerTests; 454 | PRODUCT_NAME = "$(TARGET_NAME)"; 455 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/XHDatePicker.app/XHDatePicker"; 456 | }; 457 | name = Debug; 458 | }; 459 | 2F0A1CC51D631A7F00AFBEC2 /* Release */ = { 460 | isa = XCBuildConfiguration; 461 | buildSettings = { 462 | BUNDLE_LOADER = "$(TEST_HOST)"; 463 | INFOPLIST_FILE = XHDatePickerTests/Info.plist; 464 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 465 | PRODUCT_BUNDLE_IDENTIFIER = com.weker.XHDatePickerTests; 466 | PRODUCT_NAME = "$(TARGET_NAME)"; 467 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/XHDatePicker.app/XHDatePicker"; 468 | }; 469 | name = Release; 470 | }; 471 | 2F0A1CC71D631A7F00AFBEC2 /* Debug */ = { 472 | isa = XCBuildConfiguration; 473 | buildSettings = { 474 | INFOPLIST_FILE = XHDatePickerUITests/Info.plist; 475 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 476 | PRODUCT_BUNDLE_IDENTIFIER = com.weker.XHDatePickerUITests; 477 | PRODUCT_NAME = "$(TARGET_NAME)"; 478 | TEST_TARGET_NAME = XHDatePicker; 479 | }; 480 | name = Debug; 481 | }; 482 | 2F0A1CC81D631A7F00AFBEC2 /* Release */ = { 483 | isa = XCBuildConfiguration; 484 | buildSettings = { 485 | INFOPLIST_FILE = XHDatePickerUITests/Info.plist; 486 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 487 | PRODUCT_BUNDLE_IDENTIFIER = com.weker.XHDatePickerUITests; 488 | PRODUCT_NAME = "$(TARGET_NAME)"; 489 | TEST_TARGET_NAME = XHDatePicker; 490 | }; 491 | name = Release; 492 | }; 493 | /* End XCBuildConfiguration section */ 494 | 495 | /* Begin XCConfigurationList section */ 496 | 2F0A1C8E1D631A7E00AFBEC2 /* Build configuration list for PBXProject "XHDatePicker" */ = { 497 | isa = XCConfigurationList; 498 | buildConfigurations = ( 499 | 2F0A1CBE1D631A7F00AFBEC2 /* Debug */, 500 | 2F0A1CBF1D631A7F00AFBEC2 /* Release */, 501 | ); 502 | defaultConfigurationIsVisible = 0; 503 | defaultConfigurationName = Release; 504 | }; 505 | 2F0A1CC01D631A7F00AFBEC2 /* Build configuration list for PBXNativeTarget "XHDatePicker" */ = { 506 | isa = XCConfigurationList; 507 | buildConfigurations = ( 508 | 2F0A1CC11D631A7F00AFBEC2 /* Debug */, 509 | 2F0A1CC21D631A7F00AFBEC2 /* Release */, 510 | ); 511 | defaultConfigurationIsVisible = 0; 512 | defaultConfigurationName = Release; 513 | }; 514 | 2F0A1CC31D631A7F00AFBEC2 /* Build configuration list for PBXNativeTarget "XHDatePickerTests" */ = { 515 | isa = XCConfigurationList; 516 | buildConfigurations = ( 517 | 2F0A1CC41D631A7F00AFBEC2 /* Debug */, 518 | 2F0A1CC51D631A7F00AFBEC2 /* Release */, 519 | ); 520 | defaultConfigurationIsVisible = 0; 521 | defaultConfigurationName = Release; 522 | }; 523 | 2F0A1CC61D631A7F00AFBEC2 /* Build configuration list for PBXNativeTarget "XHDatePickerUITests" */ = { 524 | isa = XCConfigurationList; 525 | buildConfigurations = ( 526 | 2F0A1CC71D631A7F00AFBEC2 /* Debug */, 527 | 2F0A1CC81D631A7F00AFBEC2 /* Release */, 528 | ); 529 | defaultConfigurationIsVisible = 0; 530 | defaultConfigurationName = Release; 531 | }; 532 | /* End XCConfigurationList section */ 533 | }; 534 | rootObject = 2F0A1C8B1D631A7E00AFBEC2 /* Project object */; 535 | } 536 | -------------------------------------------------------------------------------- /XHDatePicker.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /XHDatePicker.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /XHDatePicker.xcodeproj/project.xcworkspace/xcuserdata/jiangxinhua.xcuserdatad/UserInterfaceState.xcuserstate: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/XHJCoder/XHDatePicker/01c09a9f77bcacf40beb5af44070a192a9d688ed/XHDatePicker.xcodeproj/project.xcworkspace/xcuserdata/jiangxinhua.xcuserdatad/UserInterfaceState.xcuserstate -------------------------------------------------------------------------------- /XHDatePicker.xcodeproj/xcuserdata/jiangxinhua.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 8 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /XHDatePicker.xcodeproj/xcuserdata/jiangxinhua.xcuserdatad/xcschemes/XHDatePicker.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 33 | 39 | 40 | 41 | 43 | 49 | 50 | 51 | 52 | 53 | 59 | 60 | 61 | 62 | 63 | 64 | 74 | 76 | 82 | 83 | 84 | 85 | 86 | 87 | 93 | 95 | 101 | 102 | 103 | 104 | 106 | 107 | 110 | 111 | 112 | -------------------------------------------------------------------------------- /XHDatePicker.xcodeproj/xcuserdata/jiangxinhua.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | XHDatePicker.xcscheme 8 | 9 | orderHint 10 | 0 11 | 12 | 13 | SuppressBuildableAutocreation 14 | 15 | 2F0A1C921D631A7E00AFBEC2 16 | 17 | primary 18 | 19 | 20 | 2F0A1CAB1D631A7F00AFBEC2 21 | 22 | primary 23 | 24 | 25 | 2F0A1CB61D631A7F00AFBEC2 26 | 27 | primary 28 | 29 | 30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /XHDatePicker/NSDate+XHExtension.h: -------------------------------------------------------------------------------- 1 | // 2 | // NSDate+XHExtension.h 3 | // SmartLock 4 | // 5 | // Created by XH_J on 2016/10/25. 6 | // Copyright © 2016年 XHJCoder. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | #define D_MINUTE 60 12 | #define D_HOUR 3600 13 | #define D_DAY 86400 14 | #define D_WEEK 604800 15 | #define D_YEAR 31556926 16 | 17 | @interface NSDate (XHExtension) 18 | 19 | + (NSCalendar *) currentCalendar; // avoid bottlenecks 20 | 21 | // Relative dates from the current date 22 | + (NSDate *) dateTomorrow; 23 | + (NSDate *) dateYesterday; 24 | + (NSDate *) dateWithDaysFromNow: (NSInteger) days; 25 | + (NSDate *) dateWithDaysBeforeNow: (NSInteger) days; 26 | + (NSDate *) dateWithHoursFromNow: (NSInteger) dHours; 27 | + (NSDate *) dateWithHoursBeforeNow: (NSInteger) dHours; 28 | + (NSDate *) dateWithMinutesFromNow: (NSInteger) dMinutes; 29 | + (NSDate *) dateWithMinutesBeforeNow: (NSInteger) dMinutes; 30 | + (NSDate *)date:(NSString *)datestr WithFormat:(NSString *)format; 31 | 32 | // Short string utilities 33 | - (NSString *) stringWithDateStyle: (NSDateFormatterStyle) dateStyle timeStyle: (NSDateFormatterStyle) timeStyle; 34 | - (NSString *) stringWithFormat: (NSString *) format; 35 | @property (nonatomic, readonly) NSString *shortString; 36 | @property (nonatomic, readonly) NSString *shortDateString; 37 | @property (nonatomic, readonly) NSString *shortTimeString; 38 | @property (nonatomic, readonly) NSString *mediumString; 39 | @property (nonatomic, readonly) NSString *mediumDateString; 40 | @property (nonatomic, readonly) NSString *mediumTimeString; 41 | @property (nonatomic, readonly) NSString *longString; 42 | @property (nonatomic, readonly) NSString *longDateString; 43 | @property (nonatomic, readonly) NSString *longTimeString; 44 | 45 | // Comparing dates 46 | - (BOOL) isEqualToDateIgnoringTime: (NSDate *) aDate; 47 | 48 | - (BOOL) isToday; 49 | - (BOOL) isTomorrow; 50 | - (BOOL) isYesterday; 51 | 52 | - (BOOL) isSameWeekAsDate: (NSDate *) aDate; 53 | - (BOOL) isThisWeek; 54 | - (BOOL) isNextWeek; 55 | - (BOOL) isLastWeek; 56 | 57 | - (BOOL) isSameMonthAsDate: (NSDate *) aDate; 58 | - (BOOL) isThisMonth; 59 | - (BOOL) isNextMonth; 60 | - (BOOL) isLastMonth; 61 | 62 | - (BOOL) isSameYearAsDate: (NSDate *) aDate; 63 | - (BOOL) isThisYear; 64 | - (BOOL) isNextYear; 65 | - (BOOL) isLastYear; 66 | 67 | - (BOOL) isEarlierThanDate: (NSDate *) aDate; 68 | - (BOOL) isLaterThanDate: (NSDate *) aDate; 69 | 70 | - (BOOL) isInFuture; 71 | - (BOOL) isInPast; 72 | 73 | // Date roles 74 | - (BOOL) isTypicallyWorkday; 75 | - (BOOL) isTypicallyWeekend; 76 | 77 | // Adjusting dates 78 | - (NSDate *) dateByAddingYears: (NSInteger) dYears; 79 | - (NSDate *) dateBySubtractingYears: (NSInteger) dYears; 80 | - (NSDate *) dateByAddingMonths: (NSInteger) dMonths; 81 | - (NSDate *) dateBySubtractingMonths: (NSInteger) dMonths; 82 | - (NSDate *) dateByAddingDays: (NSInteger) dDays; 83 | - (NSDate *) dateBySubtractingDays: (NSInteger) dDays; 84 | - (NSDate *) dateByAddingHours: (NSInteger) dHours; 85 | - (NSDate *) dateBySubtractingHours: (NSInteger) dHours; 86 | - (NSDate *) dateByAddingMinutes: (NSInteger) dMinutes; 87 | - (NSDate *) dateBySubtractingMinutes: (NSInteger) dMinutes; 88 | 89 | // Date extremes 90 | - (NSDate *) dateAtStartOfDay; 91 | - (NSDate *) dateAtEndOfDay; 92 | 93 | // Retrieving intervals 94 | - (NSInteger) minutesAfterDate: (NSDate *) aDate; 95 | - (NSInteger) minutesBeforeDate: (NSDate *) aDate; 96 | - (NSInteger) hoursAfterDate: (NSDate *) aDate; 97 | - (NSInteger) hoursBeforeDate: (NSDate *) aDate; 98 | - (NSInteger) daysAfterDate: (NSDate *) aDate; 99 | - (NSInteger) daysBeforeDate: (NSDate *) aDate; 100 | - (NSInteger)distanceInDaysToDate:(NSDate *)anotherDate; 101 | 102 | // Decomposing dates 103 | @property (readonly) NSInteger nearestHour; 104 | @property (readonly) NSInteger hour; 105 | @property (readonly) NSInteger minute; 106 | @property (readonly) NSInteger seconds; 107 | @property (readonly) NSInteger day; 108 | @property (readonly) NSInteger month; 109 | @property (readonly) NSInteger week; 110 | @property (readonly) NSInteger weekday; 111 | @property (readonly) NSInteger nthWeekday; // e.g. 2nd Tuesday of the month == 2 112 | @property (readonly) NSInteger year; 113 | 114 | - (NSDate *)dateWithFormatter:(NSString *)formatter; 115 | 116 | @end 117 | -------------------------------------------------------------------------------- /XHDatePicker/NSDate+XHExtension.m: -------------------------------------------------------------------------------- 1 | // 2 | // NSDate+XHExtension.m 3 | // SmartLock 4 | // 5 | // Created by XH_J on 2016/10/25. 6 | // Copyright © 2016年 XHJCoder. All rights reserved. 7 | // 8 | 9 | #import "NSDate+XHExtension.h" 10 | 11 | static const unsigned componentFlags = (NSCalendarUnitYear| NSCalendarUnitMonth | NSCalendarUnitDay | NSCalendarUnitWeekOfMonth | NSCalendarUnitHour | NSCalendarUnitMinute | NSCalendarUnitSecond | NSCalendarUnitWeekday | NSCalendarUnitWeekdayOrdinal); 12 | 13 | @implementation NSDate (XHExtension) 14 | // Courtesy of Lukasz Margielewski 15 | // Updated via Holger Haenisch 16 | + (NSCalendar *) currentCalendar 17 | { 18 | static NSCalendar *sharedCalendar = nil; 19 | if (!sharedCalendar) 20 | sharedCalendar = [NSCalendar autoupdatingCurrentCalendar]; 21 | return sharedCalendar; 22 | } 23 | 24 | #pragma mark - Relative Dates 25 | 26 | + (NSDate *) dateWithDaysFromNow: (NSInteger) days 27 | { 28 | // Thanks, Jim Morrison 29 | return [[NSDate date] dateByAddingDays:days]; 30 | } 31 | 32 | + (NSDate *) dateWithDaysBeforeNow: (NSInteger) days 33 | { 34 | // Thanks, Jim Morrison 35 | return [[NSDate date] dateBySubtractingDays:days]; 36 | } 37 | 38 | + (NSDate *) dateTomorrow 39 | { 40 | return [NSDate dateWithDaysFromNow:1]; 41 | } 42 | 43 | + (NSDate *) dateYesterday 44 | { 45 | return [NSDate dateWithDaysBeforeNow:1]; 46 | } 47 | 48 | + (NSDate *) dateWithHoursFromNow: (NSInteger) dHours 49 | { 50 | NSTimeInterval aTimeInterval = [[NSDate date] timeIntervalSinceReferenceDate] + D_HOUR * dHours; 51 | NSDate *newDate = [NSDate dateWithTimeIntervalSinceReferenceDate:aTimeInterval]; 52 | return newDate; 53 | } 54 | 55 | + (NSDate *) dateWithHoursBeforeNow: (NSInteger) dHours 56 | { 57 | NSTimeInterval aTimeInterval = [[NSDate date] timeIntervalSinceReferenceDate] - D_HOUR * dHours; 58 | NSDate *newDate = [NSDate dateWithTimeIntervalSinceReferenceDate:aTimeInterval]; 59 | return newDate; 60 | } 61 | 62 | + (NSDate *) dateWithMinutesFromNow: (NSInteger) dMinutes 63 | { 64 | NSTimeInterval aTimeInterval = [[NSDate date] timeIntervalSinceReferenceDate] + D_MINUTE * dMinutes; 65 | NSDate *newDate = [NSDate dateWithTimeIntervalSinceReferenceDate:aTimeInterval]; 66 | return newDate; 67 | } 68 | 69 | + (NSDate *) dateWithMinutesBeforeNow: (NSInteger) dMinutes 70 | { 71 | NSTimeInterval aTimeInterval = [[NSDate date] timeIntervalSinceReferenceDate] - D_MINUTE * dMinutes; 72 | NSDate *newDate = [NSDate dateWithTimeIntervalSinceReferenceDate:aTimeInterval]; 73 | return newDate; 74 | } 75 | 76 | #pragma mark - String Properties 77 | - (NSString *) stringWithFormat: (NSString *) format 78 | { 79 | NSDateFormatter *formatter = [NSDateFormatter new]; 80 | // formatter.locale = [NSLocale currentLocale]; // Necessary? 81 | formatter.dateFormat = format; 82 | return [formatter stringFromDate:self]; 83 | } 84 | 85 | - (NSString *) stringWithDateStyle: (NSDateFormatterStyle) dateStyle timeStyle: (NSDateFormatterStyle) timeStyle 86 | { 87 | NSDateFormatter *formatter = [NSDateFormatter new]; 88 | formatter.dateStyle = dateStyle; 89 | formatter.timeStyle = timeStyle; 90 | // formatter.locale = [NSLocale currentLocale]; // Necessary? 91 | return [formatter stringFromDate:self]; 92 | } 93 | 94 | - (NSString *) shortString 95 | { 96 | return [self stringWithDateStyle:NSDateFormatterShortStyle timeStyle:NSDateFormatterShortStyle]; 97 | } 98 | 99 | - (NSString *) shortTimeString 100 | { 101 | return [self stringWithDateStyle:NSDateFormatterNoStyle timeStyle:NSDateFormatterShortStyle]; 102 | } 103 | 104 | - (NSString *) shortDateString 105 | { 106 | return [self stringWithDateStyle:NSDateFormatterShortStyle timeStyle:NSDateFormatterNoStyle]; 107 | } 108 | 109 | - (NSString *) mediumString 110 | { 111 | return [self stringWithDateStyle:NSDateFormatterMediumStyle timeStyle:NSDateFormatterMediumStyle ]; 112 | } 113 | 114 | - (NSString *) mediumTimeString 115 | { 116 | return [self stringWithDateStyle:NSDateFormatterNoStyle timeStyle:NSDateFormatterMediumStyle ]; 117 | } 118 | 119 | - (NSString *) mediumDateString 120 | { 121 | return [self stringWithDateStyle:NSDateFormatterMediumStyle timeStyle:NSDateFormatterNoStyle]; 122 | } 123 | 124 | - (NSString *) longString 125 | { 126 | return [self stringWithDateStyle:NSDateFormatterLongStyle timeStyle:NSDateFormatterLongStyle ]; 127 | } 128 | 129 | - (NSString *) longTimeString 130 | { 131 | return [self stringWithDateStyle:NSDateFormatterNoStyle timeStyle:NSDateFormatterLongStyle ]; 132 | } 133 | 134 | - (NSString *) longDateString 135 | { 136 | return [self stringWithDateStyle:NSDateFormatterLongStyle timeStyle:NSDateFormatterNoStyle]; 137 | } 138 | 139 | #pragma mark - Comparing Dates 140 | 141 | - (BOOL) isEqualToDateIgnoringTime: (NSDate *) aDate 142 | { 143 | NSDateComponents *components1 = [[NSDate currentCalendar] components:componentFlags fromDate:self]; 144 | NSDateComponents *components2 = [[NSDate currentCalendar] components:componentFlags fromDate:aDate]; 145 | return ((components1.year == components2.year) && 146 | (components1.month == components2.month) && 147 | (components1.day == components2.day)); 148 | } 149 | 150 | - (BOOL) isToday 151 | { 152 | return [self isEqualToDateIgnoringTime:[NSDate date]]; 153 | } 154 | 155 | - (BOOL) isTomorrow 156 | { 157 | return [self isEqualToDateIgnoringTime:[NSDate dateTomorrow]]; 158 | } 159 | 160 | - (BOOL) isYesterday 161 | { 162 | return [self isEqualToDateIgnoringTime:[NSDate dateYesterday]]; 163 | } 164 | 165 | // This hard codes the assumption that a week is 7 days 166 | - (BOOL) isSameWeekAsDate: (NSDate *) aDate 167 | { 168 | NSDateComponents *components1 = [[NSDate currentCalendar] components:componentFlags fromDate:self]; 169 | NSDateComponents *components2 = [[NSDate currentCalendar] components:componentFlags fromDate:aDate]; 170 | 171 | // Must be same week. 12/31 and 1/1 will both be week "1" if they are in the same week 172 | if (components1.weekOfMonth != components2.weekOfMonth) return NO; 173 | 174 | // Must have a time interval under 1 week. Thanks @aclark 175 | return (fabs([self timeIntervalSinceDate:aDate]) < D_WEEK); 176 | } 177 | 178 | - (BOOL) isThisWeek 179 | { 180 | return [self isSameWeekAsDate:[NSDate date]]; 181 | } 182 | 183 | - (BOOL) isNextWeek 184 | { 185 | NSTimeInterval aTimeInterval = [[NSDate date] timeIntervalSinceReferenceDate] + D_WEEK; 186 | NSDate *newDate = [NSDate dateWithTimeIntervalSinceReferenceDate:aTimeInterval]; 187 | return [self isSameWeekAsDate:newDate]; 188 | } 189 | 190 | - (BOOL) isLastWeek 191 | { 192 | NSTimeInterval aTimeInterval = [[NSDate date] timeIntervalSinceReferenceDate] - D_WEEK; 193 | NSDate *newDate = [NSDate dateWithTimeIntervalSinceReferenceDate:aTimeInterval]; 194 | return [self isSameWeekAsDate:newDate]; 195 | } 196 | 197 | // Thanks, mspasov 198 | - (BOOL) isSameMonthAsDate: (NSDate *) aDate 199 | { 200 | NSDateComponents *components1 = [[NSDate currentCalendar] components:NSCalendarUnitYear | NSCalendarUnitMonth fromDate:self]; 201 | NSDateComponents *components2 = [[NSDate currentCalendar] components:NSCalendarUnitYear | NSCalendarUnitMonth fromDate:aDate]; 202 | return ((components1.month == components2.month) && 203 | (components1.year == components2.year)); 204 | } 205 | 206 | - (BOOL) isThisMonth 207 | { 208 | return [self isSameMonthAsDate:[NSDate date]]; 209 | } 210 | 211 | // Thanks Marcin Krzyzanowski, also for adding/subtracting years and months 212 | - (BOOL) isLastMonth 213 | { 214 | return [self isSameMonthAsDate:[[NSDate date] dateBySubtractingMonths:1]]; 215 | } 216 | 217 | - (BOOL) isNextMonth 218 | { 219 | return [self isSameMonthAsDate:[[NSDate date] dateByAddingMonths:1]]; 220 | } 221 | 222 | - (BOOL) isSameYearAsDate: (NSDate *) aDate 223 | { 224 | NSDateComponents *components1 = [[NSDate currentCalendar] components:NSCalendarUnitYear fromDate:self]; 225 | NSDateComponents *components2 = [[NSDate currentCalendar] components:NSCalendarUnitYear fromDate:aDate]; 226 | return (components1.year == components2.year); 227 | } 228 | 229 | - (BOOL) isThisYear 230 | { 231 | // Thanks, baspellis 232 | return [self isSameYearAsDate:[NSDate date]]; 233 | } 234 | 235 | - (BOOL) isNextYear 236 | { 237 | NSDateComponents *components1 = [[NSDate currentCalendar] components:NSCalendarUnitYear fromDate:self]; 238 | NSDateComponents *components2 = [[NSDate currentCalendar] components:NSCalendarUnitYear fromDate:[NSDate date]]; 239 | 240 | return (components1.year == (components2.year + 1)); 241 | } 242 | 243 | - (BOOL) isLastYear 244 | { 245 | NSDateComponents *components1 = [[NSDate currentCalendar] components:NSCalendarUnitYear fromDate:self]; 246 | NSDateComponents *components2 = [[NSDate currentCalendar] components:NSCalendarUnitYear fromDate:[NSDate date]]; 247 | 248 | return (components1.year == (components2.year - 1)); 249 | } 250 | 251 | - (BOOL) isEarlierThanDate: (NSDate *) aDate 252 | { 253 | return ([self compare:aDate] == NSOrderedAscending); 254 | } 255 | 256 | - (BOOL) isLaterThanDate: (NSDate *) aDate 257 | { 258 | return ([self compare:aDate] == NSOrderedDescending); 259 | } 260 | 261 | // Thanks, markrickert 262 | - (BOOL) isInFuture 263 | { 264 | return ([self isLaterThanDate:[NSDate date]]); 265 | } 266 | 267 | // Thanks, markrickert 268 | - (BOOL) isInPast 269 | { 270 | return ([self isEarlierThanDate:[NSDate date]]); 271 | } 272 | 273 | 274 | #pragma mark - Roles 275 | - (BOOL) isTypicallyWeekend 276 | { 277 | NSDateComponents *components = [[NSDate currentCalendar] components:NSCalendarUnitWeekday fromDate:self]; 278 | if ((components.weekday == 1) || 279 | (components.weekday == 7)) 280 | return YES; 281 | return NO; 282 | } 283 | 284 | - (BOOL) isTypicallyWorkday 285 | { 286 | return ![self isTypicallyWeekend]; 287 | } 288 | 289 | #pragma mark - Adjusting Dates 290 | 291 | // Thaks, rsjohnson 292 | - (NSDate *) dateByAddingYears: (NSInteger) dYears 293 | { 294 | NSDateComponents *dateComponents = [[NSDateComponents alloc] init]; 295 | [dateComponents setYear:dYears]; 296 | NSDate *newDate = [[NSCalendar currentCalendar] dateByAddingComponents:dateComponents toDate:self options:0]; 297 | return newDate; 298 | } 299 | 300 | - (NSDate *) dateBySubtractingYears: (NSInteger) dYears 301 | { 302 | return [self dateByAddingYears:-dYears]; 303 | } 304 | 305 | - (NSDate *) dateByAddingMonths: (NSInteger) dMonths 306 | { 307 | NSDateComponents *dateComponents = [[NSDateComponents alloc] init]; 308 | [dateComponents setMonth:dMonths]; 309 | NSDate *newDate = [[NSCalendar currentCalendar] dateByAddingComponents:dateComponents toDate:self options:0]; 310 | return newDate; 311 | } 312 | 313 | - (NSDate *) dateBySubtractingMonths: (NSInteger) dMonths 314 | { 315 | return [self dateByAddingMonths:-dMonths]; 316 | } 317 | 318 | // Courtesy of dedan who mentions issues with Daylight Savings 319 | - (NSDate *) dateByAddingDays: (NSInteger) dDays 320 | { 321 | NSDateComponents *dateComponents = [[NSDateComponents alloc] init]; 322 | [dateComponents setDay:dDays]; 323 | NSDate *newDate = [[NSCalendar currentCalendar] dateByAddingComponents:dateComponents toDate:self options:0]; 324 | return newDate; 325 | } 326 | 327 | - (NSDate *) dateBySubtractingDays: (NSInteger) dDays 328 | { 329 | return [self dateByAddingDays: (dDays * -1)]; 330 | } 331 | 332 | - (NSDate *) dateByAddingHours: (NSInteger) dHours 333 | { 334 | NSTimeInterval aTimeInterval = [self timeIntervalSinceReferenceDate] + D_HOUR * dHours; 335 | NSDate *newDate = [NSDate dateWithTimeIntervalSinceReferenceDate:aTimeInterval]; 336 | return newDate; 337 | } 338 | 339 | - (NSDate *) dateBySubtractingHours: (NSInteger) dHours 340 | { 341 | return [self dateByAddingHours: (dHours * -1)]; 342 | } 343 | 344 | - (NSDate *) dateByAddingMinutes: (NSInteger) dMinutes 345 | { 346 | NSTimeInterval aTimeInterval = [self timeIntervalSinceReferenceDate] + D_MINUTE * dMinutes; 347 | NSDate *newDate = [NSDate dateWithTimeIntervalSinceReferenceDate:aTimeInterval]; 348 | return newDate; 349 | } 350 | 351 | - (NSDate *) dateBySubtractingMinutes: (NSInteger) dMinutes 352 | { 353 | return [self dateByAddingMinutes: (dMinutes * -1)]; 354 | } 355 | 356 | - (NSDateComponents *) componentsWithOffsetFromDate: (NSDate *) aDate 357 | { 358 | NSDateComponents *dTime = [[NSDate currentCalendar] components:componentFlags fromDate:aDate toDate:self options:0]; 359 | return dTime; 360 | } 361 | 362 | #pragma mark - Extremes 363 | 364 | - (NSDate *) dateAtStartOfDay 365 | { 366 | NSDateComponents *components = [[NSDate currentCalendar] components:componentFlags fromDate:self]; 367 | components.hour = 0; 368 | components.minute = 0; 369 | components.second = 0; 370 | return [[NSDate currentCalendar] dateFromComponents:components]; 371 | } 372 | 373 | // Thanks gsempe & mteece 374 | - (NSDate *) dateAtEndOfDay 375 | { 376 | NSDateComponents *components = [[NSDate currentCalendar] components:componentFlags fromDate:self]; 377 | components.hour = 23; // Thanks Aleksey Kononov 378 | components.minute = 59; 379 | components.second = 59; 380 | return [[NSDate currentCalendar] dateFromComponents:components]; 381 | } 382 | 383 | #pragma mark - Retrieving Intervals 384 | 385 | - (NSInteger) minutesAfterDate: (NSDate *) aDate 386 | { 387 | NSTimeInterval ti = [self timeIntervalSinceDate:aDate]; 388 | return (NSInteger) (ti / D_MINUTE); 389 | } 390 | 391 | - (NSInteger) minutesBeforeDate: (NSDate *) aDate 392 | { 393 | NSTimeInterval ti = [aDate timeIntervalSinceDate:self]; 394 | return (NSInteger) (ti / D_MINUTE); 395 | } 396 | 397 | - (NSInteger) hoursAfterDate: (NSDate *) aDate 398 | { 399 | NSTimeInterval ti = [self timeIntervalSinceDate:aDate]; 400 | return (NSInteger) (ti / D_HOUR); 401 | } 402 | 403 | - (NSInteger) hoursBeforeDate: (NSDate *) aDate 404 | { 405 | NSTimeInterval ti = [aDate timeIntervalSinceDate:self]; 406 | return (NSInteger) (ti / D_HOUR); 407 | } 408 | 409 | - (NSInteger) daysAfterDate: (NSDate *) aDate 410 | { 411 | NSTimeInterval ti = [self timeIntervalSinceDate:aDate]; 412 | return (NSInteger) (ti / D_DAY); 413 | } 414 | 415 | - (NSInteger) daysBeforeDate: (NSDate *) aDate 416 | { 417 | NSTimeInterval ti = [aDate timeIntervalSinceDate:self]; 418 | return (NSInteger) (ti / D_DAY); 419 | } 420 | 421 | // Thanks, dmitrydims 422 | // I have not yet thoroughly tested this 423 | - (NSInteger)distanceInDaysToDate:(NSDate *)anotherDate 424 | { 425 | NSCalendar *gregorianCalendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSCalendarIdentifierGregorian]; 426 | NSDateComponents *components = [gregorianCalendar components:NSCalendarUnitDay fromDate:self toDate:anotherDate options:0]; 427 | return components.day; 428 | } 429 | 430 | #pragma mark - Decomposing Dates 431 | 432 | - (NSInteger) nearestHour 433 | { 434 | NSTimeInterval aTimeInterval = [[NSDate date] timeIntervalSinceReferenceDate] + D_MINUTE * 30; 435 | NSDate *newDate = [NSDate dateWithTimeIntervalSinceReferenceDate:aTimeInterval]; 436 | NSDateComponents *components = [[NSDate currentCalendar] components:NSCalendarUnitHour fromDate:newDate]; 437 | return components.hour; 438 | } 439 | 440 | - (NSInteger) hour 441 | { 442 | NSDateComponents *components = [[NSDate currentCalendar] components:componentFlags fromDate:self]; 443 | return components.hour; 444 | } 445 | 446 | - (NSInteger) minute 447 | { 448 | NSDateComponents *components = [[NSDate currentCalendar] components:componentFlags fromDate:self]; 449 | return components.minute; 450 | } 451 | 452 | - (NSInteger) seconds 453 | { 454 | NSDateComponents *components = [[NSDate currentCalendar] components:componentFlags fromDate:self]; 455 | return components.second; 456 | } 457 | 458 | - (NSInteger) day 459 | { 460 | NSDateComponents *components = [[NSDate currentCalendar] components:componentFlags fromDate:self]; 461 | return components.day; 462 | } 463 | 464 | - (NSInteger) month 465 | { 466 | NSDateComponents *components = [[NSDate currentCalendar] components:componentFlags fromDate:self]; 467 | return components.month; 468 | } 469 | 470 | - (NSInteger) week 471 | { 472 | NSDateComponents *components = [[NSDate currentCalendar] components:componentFlags fromDate:self]; 473 | return components.weekOfMonth; 474 | } 475 | 476 | - (NSInteger) weekday 477 | { 478 | NSDateComponents *components = [[NSDate currentCalendar] components:componentFlags fromDate:self]; 479 | return components.weekday; 480 | } 481 | 482 | - (NSInteger) nthWeekday // e.g. 2nd Tuesday of the month is 2 483 | { 484 | NSDateComponents *components = [[NSDate currentCalendar] components:componentFlags fromDate:self]; 485 | return components.weekdayOrdinal; 486 | } 487 | 488 | - (NSInteger) year 489 | { 490 | NSDateComponents *components = [[NSDate currentCalendar] components:componentFlags fromDate:self]; 491 | return components.year; 492 | } 493 | 494 | + (NSDate *)date:(NSString *)datestr WithFormat:(NSString *)format 495 | { 496 | NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init]; 497 | [dateFormatter setLocale:[NSLocale currentLocale]]; 498 | [dateFormatter setTimeZone:[NSTimeZone localTimeZone]]; 499 | [dateFormatter setDateFormat:format]; 500 | NSDate *date = [dateFormatter dateFromString:datestr]; 501 | #if ! __has_feature(objc_arc) 502 | [dateFormatter release]; 503 | #endif 504 | return date; 505 | } 506 | 507 | -(NSDate *)dateWithFormatter:(NSString *)formatter { 508 | NSDateFormatter *fmt = [[NSDateFormatter alloc] init]; 509 | fmt.dateFormat = formatter; 510 | NSString *selfStr = [fmt stringFromDate:self]; 511 | return [fmt dateFromString:selfStr]; 512 | } 513 | 514 | @end 515 | -------------------------------------------------------------------------------- /XHDatePicker/XHDatePicker.h: -------------------------------------------------------------------------------- 1 | // 2 | // XHDatePicker.h 3 | // XHDatePicker 4 | // 5 | // Created by XH_J on 2016/10/25. 6 | // Copyright © 2016年 XHJCoder. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | typedef NS_ENUM(NSInteger, XHDatePickerMode) { 12 | XHDatePickerModeYearMonthDayHourMinute = 0, // 年月日时分 13 | XHDatePickerModeMonthDayHourMinute, // 月日时分 14 | XHDatePickerModeYearMonthDay, // 年月日 15 | XHDatePickerModeYearMonth, // 年月 16 | XHDatePickerModeMonthDay, // 月日 17 | XHDatePickerModeHourMinute // 时分 18 | }; 19 | 20 | @interface XHDatePicker : UIView 21 | 22 | // default is XHDatePickerModeYearMonthDayHourMinute 23 | @property (nonatomic, assign) XHDatePickerMode datePickerMode; 24 | 25 | /** 26 | * 默认与datePickerMode相对应 27 | * 比如:XHDatePickerModeYearMonthDayHourMinute对应的dateFormatter是:@"yyyy-MM-dd HH:mm" 28 | * 你也可以设置格式为 yyyy年MM月dd日HH时mm分 29 | */ 30 | @property (nonatomic, copy) NSString *dateFormatter; 31 | 32 | @property (nonatomic, strong) UIColor *themeColor; 33 | 34 | @property (nonatomic, strong) NSDate *minimumDate; // 限制最大时间(default is nil) 35 | @property (nonatomic, strong) NSDate *maximumDate; // 限制最小时间(default is nil) 36 | @property (nonatomic, strong) NSDate *date; // 当前显示时间(default is [NSDate date]) 37 | 38 | + (instancetype)showWithCompleteBlock:(void(^)(NSDate *date, NSString *dateString))completeBlock; 39 | 40 | @end 41 | -------------------------------------------------------------------------------- /XHDatePicker/XHDatePicker.m: -------------------------------------------------------------------------------- 1 | // 2 | // XHDatePicker.m 3 | // XHDatePicker 4 | // 5 | // Created by XH_J on 2016/10/25. 6 | // Copyright © 2016年 XHJCoder. All rights reserved. 7 | // 8 | 9 | #import "XHDatePicker.h" 10 | #import "NSDate+XHExtension.h" 11 | 12 | typedef NS_ENUM(NSInteger, XHDateType) { 13 | XHDateTypeYear, 14 | XHDateTypeMonth, 15 | XHDateTypeDay, 16 | XHDateTypeHour, 17 | XHDateTypeMinute 18 | }; 19 | 20 | @interface XHDatePicker () { 21 | 22 | NSArray *_rowsDataArray; 23 | NSArray *_dateTypeArray; 24 | NSArray *_textDataArray; 25 | BOOL _isRepeatMonth; 26 | 27 | } 28 | 29 | @property (weak, nonatomic) IBOutlet UIView *buttomView; 30 | @property (weak, nonatomic) IBOutlet UILabel *showYearView; 31 | @property (weak, nonatomic) IBOutlet UIButton *doneBtn; 32 | @property (weak, nonatomic) IBOutlet NSLayoutConstraint *bottomConstraint; 33 | 34 | @property (nonatomic, strong) UIPickerView *datePicker; 35 | @property (nonatomic, strong) void(^doneBlock)(NSDate *date, NSString *dateString); 36 | @property (nonatomic, copy) NSString *yearText; 37 | @property (nonatomic, strong) NSDate *currentDate; 38 | 39 | 40 | @end 41 | 42 | @implementation XHDatePicker 43 | 44 | + (instancetype)showWithCompleteBlock:(void (^)(NSDate *, NSString *))completeBlock { 45 | 46 | XHDatePicker *datePickerView = [[[NSBundle bundleForClass:[self class]] loadNibNamed:NSStringFromClass([self class]) owner:self options:nil] lastObject]; 47 | [datePickerView setupUI]; 48 | 49 | datePickerView.datePickerMode = XHDatePickerModeYearMonthDayHourMinute; 50 | datePickerView.date = [NSDate date]; 51 | 52 | if (completeBlock) { 53 | datePickerView.doneBlock = ^(NSDate *date, NSString *dateString) { 54 | completeBlock(date,dateString); 55 | }; 56 | } 57 | return datePickerView; 58 | } 59 | 60 | - (void)setupUI { 61 | 62 | self.buttomView.layer.cornerRadius = 10; 63 | self.buttomView.layer.masksToBounds = YES; 64 | self.frame = [UIScreen mainScreen].bounds; 65 | 66 | //点击背景是否隐藏 67 | UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc]initWithTarget:self action:@selector(dismiss)]; 68 | tap.delegate = self; 69 | [self addGestureRecognizer:tap]; 70 | 71 | self.bottomConstraint.constant = -self.frame.size.height; 72 | self.backgroundColor = [UIColor colorWithRed:(0 / 255.0) green:(0 / 255.0) blue:(0 / 255.0) alpha:0]; 73 | [self layoutIfNeeded]; 74 | 75 | [[UIApplication sharedApplication].keyWindow bringSubviewToFront:self]; 76 | 77 | [self.showYearView addSubview:self.datePicker]; 78 | 79 | [self show]; 80 | 81 | } 82 | 83 | - (void)addLabelWithName:(NSArray *)nameArr { 84 | for (id subView in self.showYearView.subviews) { 85 | if ([subView isKindOfClass:[UILabel class]]) { 86 | [subView removeFromSuperview]; 87 | } 88 | } 89 | CGSize datePickerSize = self.datePicker.frame.size; 90 | for (int i=0; idays) { 288 | isUpdateDays = YES; 289 | } 290 | tmpDate = [_currentDate dateByAddingYears:rowData - _currentDate.year]; 291 | break; 292 | case XHDateTypeMonth: 293 | days = [self getDaysfromYear:_currentDate.year andMonth:rowData]; 294 | if (_currentDate.day>days) { 295 | isUpdateDays = YES; 296 | } 297 | tmpDate = [_currentDate dateByAddingMonths:rowData - _currentDate.month]; 298 | break; 299 | case XHDateTypeDay: 300 | days = [self getDaysfromYear:_currentDate.year andMonth:_currentDate.month]; 301 | if (rowData>days) { 302 | rowData = days; 303 | isUpdateDays = YES; 304 | } 305 | tmpDate = [_currentDate dateByAddingDays:rowData - _currentDate.day]; 306 | break; 307 | case XHDateTypeHour: 308 | tmpDate = [_currentDate dateByAddingHours:rowData - _currentDate.hour]; 309 | break; 310 | case XHDateTypeMinute: 311 | tmpDate = [_currentDate dateByAddingMinutes:rowData - _currentDate.minute]; 312 | break; 313 | } 314 | if (isUpdateDays) { 315 | [self.datePicker selectRow:days-1 inComponent:[_dateTypeArray indexOfObject:@(XHDateTypeDay)] animated:YES]; 316 | } 317 | 318 | self.currentDate = tmpDate; 319 | } 320 | 321 | // 通过年月求每月天数 322 | - (NSInteger)getDaysfromYear:(NSInteger)year andMonth:(NSInteger)month { 323 | BOOL isrunNian = year%4==0 ? (year%100==0? (year%400==0?YES:NO):YES):NO; 324 | switch (month) { 325 | case 1:case 3:case 5:case 7:case 8:case 10:case 12: 326 | return 31; 327 | case 4:case 6:case 9:case 11: 328 | return 30; 329 | case 2: 330 | return isrunNian ? 29 : 28; 331 | } 332 | return 0; 333 | } 334 | 335 | #pragma mark - Setter 336 | - (void)setDatePickerMode:(XHDatePickerMode)datePickerMode { 337 | _datePickerMode = datePickerMode; 338 | switch (datePickerMode) { 339 | case XHDatePickerModeYearMonthDayHourMinute: 340 | _rowsDataArray = @[@(10000), @(12), @(31), @(24), @(60)]; 341 | _dateTypeArray = @[@(XHDateTypeYear),@(XHDateTypeMonth),@(XHDateTypeDay),@(XHDateTypeHour),@(XHDateTypeMinute)]; 342 | _textDataArray = @[@"年",@"月",@"日",@"时",@"分"]; 343 | _isRepeatMonth = NO; 344 | break; 345 | case XHDatePickerModeMonthDayHourMinute: 346 | _rowsDataArray = @[@(12*10000), @(31), @(24), @(60)]; 347 | _dateTypeArray = @[@(XHDateTypeMonth),@(XHDateTypeDay),@(XHDateTypeHour),@(XHDateTypeMinute)]; 348 | _textDataArray = @[@"月",@"日",@"时",@"分"]; 349 | _isRepeatMonth = YES; 350 | break; 351 | case XHDatePickerModeYearMonthDay: 352 | _rowsDataArray = @[@(10000), @(12), @(31)]; 353 | _dateTypeArray = @[@(XHDateTypeYear),@(XHDateTypeMonth),@(XHDateTypeDay)]; 354 | _textDataArray = @[@"年",@"月",@"日"]; 355 | _isRepeatMonth = NO; 356 | break; 357 | case XHDatePickerModeYearMonth: 358 | _rowsDataArray = @[@(10000), @(12)]; 359 | _dateTypeArray = @[@(XHDateTypeYear),@(XHDateTypeMonth)]; 360 | _textDataArray = @[@"年",@"月"]; 361 | _isRepeatMonth = NO; 362 | break; 363 | case XHDatePickerModeMonthDay: 364 | _rowsDataArray = @[@(12*10000), @(31)]; 365 | _dateTypeArray = @[@(XHDateTypeMonth),@(XHDateTypeDay)]; 366 | _textDataArray = @[@"月",@"日"]; 367 | _isRepeatMonth = YES; 368 | break; 369 | case XHDatePickerModeHourMinute: 370 | _rowsDataArray = @[@(24), @(60)]; 371 | _dateTypeArray = @[@(XHDateTypeHour),@(XHDateTypeMinute)]; 372 | _textDataArray = @[@"时",@"分"]; 373 | _isRepeatMonth = NO; 374 | break; 375 | } 376 | [self.datePicker reloadAllComponents]; 377 | self.yearText = [NSString stringWithFormat:@"%d",(int)_currentDate.year]; 378 | [self scrollToCurrentDateWithAnimated:NO]; 379 | } 380 | 381 | - (void)setMinimumDate:(NSDate *)minimumDate { 382 | _minimumDate = minimumDate; 383 | [self currentDateInRangeWithAnimated:NO]; 384 | } 385 | 386 | - (void)setMaximumDate:(NSDate *)maximumDate { 387 | _maximumDate = maximumDate; 388 | [self currentDateInRangeWithAnimated:NO]; 389 | } 390 | 391 | - (void)setCurrentDate:(NSDate *)currentDate { 392 | _currentDate = currentDate; 393 | [self currentDateInRangeWithAnimated:YES]; 394 | } 395 | 396 | - (void)setDate:(NSDate *)date { 397 | _date = date; 398 | _currentDate = date; 399 | if ([self currentDateInRangeWithAnimated:NO]) { 400 | [self scrollToCurrentDateWithAnimated:NO]; 401 | } 402 | 403 | } 404 | 405 | - (void)setThemeColor:(UIColor *)themeColor { 406 | _themeColor = themeColor; 407 | self.doneBtn.backgroundColor = themeColor; 408 | [self.datePicker reloadAllComponents]; 409 | } 410 | 411 | - (void)setYearText:(NSString *)yearText { 412 | _yearText = yearText; 413 | switch (_datePickerMode) { 414 | case XHDatePickerModeYearMonthDayHourMinute: 415 | case XHDatePickerModeYearMonthDay: 416 | case XHDatePickerModeYearMonth: 417 | case XHDatePickerModeHourMinute: 418 | self.showYearView.text = @""; 419 | break; 420 | case XHDatePickerModeMonthDayHourMinute: 421 | case XHDatePickerModeMonthDay: 422 | self.showYearView.text = yearText; 423 | break; 424 | } 425 | } 426 | 427 | #pragma mark - Getter 428 | - (UIPickerView *)datePicker { 429 | if (!_datePicker) { 430 | [self.showYearView layoutIfNeeded]; 431 | _datePicker = [[UIPickerView alloc] initWithFrame:self.showYearView.bounds]; 432 | _datePicker.showsSelectionIndicator = YES; 433 | _datePicker.delegate = self; 434 | _datePicker.dataSource = self; 435 | } 436 | return _datePicker; 437 | } 438 | 439 | @end 440 | -------------------------------------------------------------------------------- /XHDatePicker/XHDatePicker.xib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 34 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | -------------------------------------------------------------------------------- /XHDatePickerTests/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 | -------------------------------------------------------------------------------- /XHDatePickerTests/XHDatePickerTests.m: -------------------------------------------------------------------------------- 1 | // 2 | // XHDatePickerTests.m 3 | // XHDatePickerTests 4 | // 5 | // Created by XH_J on 2016/10/25. 6 | // Copyright © 2016年 XHJCoder. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface XHDatePickerTests : XCTestCase 12 | 13 | @end 14 | 15 | @implementation XHDatePickerTests 16 | 17 | - (void)setUp { 18 | [super setUp]; 19 | // Put setup code here. This method is called before the invocation of each test method in the class. 20 | } 21 | 22 | - (void)tearDown { 23 | // Put teardown code here. This method is called after the invocation of each test method in the class. 24 | [super tearDown]; 25 | } 26 | 27 | - (void)testExample { 28 | // This is an example of a functional test case. 29 | // Use XCTAssert and related functions to verify your tests produce the correct results. 30 | } 31 | 32 | - (void)testPerformanceExample { 33 | // This is an example of a performance test case. 34 | [self measureBlock:^{ 35 | // Put the code you want to measure the time of here. 36 | }]; 37 | } 38 | 39 | @end 40 | -------------------------------------------------------------------------------- /XHDatePickerUITests/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 | -------------------------------------------------------------------------------- /XHDatePickerUITests/XHDatePickerUITests.m: -------------------------------------------------------------------------------- 1 | // 2 | // XHDatePickerUITests.m 3 | // XHDatePickerUITests 4 | // 5 | // Created by XH_J on 2016/10/25. 6 | // Copyright © 2016年 XHJCoder. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface XHDatePickerUITests : XCTestCase 12 | 13 | @end 14 | 15 | @implementation XHDatePickerUITests 16 | 17 | - (void)setUp { 18 | [super setUp]; 19 | 20 | // Put setup code here. This method is called before the invocation of each test method in the class. 21 | 22 | // In UI tests it is usually best to stop immediately when a failure occurs. 23 | self.continueAfterFailure = NO; 24 | // UI tests must launch the application that they test. Doing this in setup will make sure it happens for each test method. 25 | [[[XCUIApplication alloc] init] launch]; 26 | 27 | // In UI tests it’s important to set the initial state - such as interface orientation - required for your tests before they run. The setUp method is a good place to do this. 28 | } 29 | 30 | - (void)tearDown { 31 | // Put teardown code here. This method is called after the invocation of each test method in the class. 32 | [super tearDown]; 33 | } 34 | 35 | - (void)testExample { 36 | // Use recording to get started writing UI tests. 37 | // Use XCTAssert and related functions to verify your tests produce the correct results. 38 | } 39 | 40 | @end 41 | -------------------------------------------------------------------------------- /XHDatePicker_demo/AppDelegate.h: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.h 3 | // XHDatePicker 4 | // 5 | // Created by XH_J on 2016/10/25. 6 | // Copyright © 2016年 XHJCoder. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface AppDelegate : UIResponder 12 | 13 | @property (strong, nonatomic) UIWindow *window; 14 | 15 | 16 | @end 17 | 18 | -------------------------------------------------------------------------------- /XHDatePicker_demo/AppDelegate.m: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.m 3 | // XHDatePicker 4 | // 5 | // Created by XH_J on 2016/10/25. 6 | // Copyright © 2016年 XHJCoder. All rights reserved. 7 | // 8 | 9 | #import "AppDelegate.h" 10 | 11 | @interface AppDelegate () 12 | 13 | @end 14 | 15 | @implementation AppDelegate 16 | 17 | 18 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { 19 | // Override point for customization after application launch. 20 | return YES; 21 | } 22 | 23 | - (void)applicationWillResignActive:(UIApplication *)application { 24 | // 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. 25 | // 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. 26 | } 27 | 28 | - (void)applicationDidEnterBackground:(UIApplication *)application { 29 | // 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. 30 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. 31 | } 32 | 33 | - (void)applicationWillEnterForeground:(UIApplication *)application { 34 | // 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. 35 | } 36 | 37 | - (void)applicationDidBecomeActive:(UIApplication *)application { 38 | // 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. 39 | } 40 | 41 | - (void)applicationWillTerminate:(UIApplication *)application { 42 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. 43 | } 44 | 45 | @end 46 | -------------------------------------------------------------------------------- /XHDatePicker_demo/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "iphone", 5 | "size" : "20x20", 6 | "scale" : "2x" 7 | }, 8 | { 9 | "idiom" : "iphone", 10 | "size" : "20x20", 11 | "scale" : "3x" 12 | }, 13 | { 14 | "idiom" : "iphone", 15 | "size" : "29x29", 16 | "scale" : "2x" 17 | }, 18 | { 19 | "idiom" : "iphone", 20 | "size" : "29x29", 21 | "scale" : "3x" 22 | }, 23 | { 24 | "idiom" : "iphone", 25 | "size" : "40x40", 26 | "scale" : "2x" 27 | }, 28 | { 29 | "idiom" : "iphone", 30 | "size" : "40x40", 31 | "scale" : "3x" 32 | }, 33 | { 34 | "idiom" : "iphone", 35 | "size" : "60x60", 36 | "scale" : "2x" 37 | }, 38 | { 39 | "idiom" : "iphone", 40 | "size" : "60x60", 41 | "scale" : "3x" 42 | }, 43 | { 44 | "idiom" : "ipad", 45 | "size" : "20x20", 46 | "scale" : "1x" 47 | }, 48 | { 49 | "idiom" : "ipad", 50 | "size" : "20x20", 51 | "scale" : "2x" 52 | }, 53 | { 54 | "idiom" : "ipad", 55 | "size" : "29x29", 56 | "scale" : "1x" 57 | }, 58 | { 59 | "idiom" : "ipad", 60 | "size" : "29x29", 61 | "scale" : "2x" 62 | }, 63 | { 64 | "idiom" : "ipad", 65 | "size" : "40x40", 66 | "scale" : "1x" 67 | }, 68 | { 69 | "idiom" : "ipad", 70 | "size" : "40x40", 71 | "scale" : "2x" 72 | }, 73 | { 74 | "idiom" : "ipad", 75 | "size" : "76x76", 76 | "scale" : "1x" 77 | }, 78 | { 79 | "idiom" : "ipad", 80 | "size" : "76x76", 81 | "scale" : "2x" 82 | }, 83 | { 84 | "idiom" : "ipad", 85 | "size" : "83.5x83.5", 86 | "scale" : "2x" 87 | }, 88 | { 89 | "idiom" : "ios-marketing", 90 | "size" : "1024x1024", 91 | "scale" : "1x" 92 | } 93 | ], 94 | "info" : { 95 | "version" : 1, 96 | "author" : "xcode" 97 | } 98 | } -------------------------------------------------------------------------------- /XHDatePicker_demo/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /XHDatePicker_demo/Assets.xcassets/selected.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "选中全天.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "选中全天@2x.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "filename" : "选中全天@3x.png", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "version" : 1, 21 | "author" : "xcode" 22 | } 23 | } -------------------------------------------------------------------------------- /XHDatePicker_demo/Assets.xcassets/selected.imageset/选中全天.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/XHJCoder/XHDatePicker/01c09a9f77bcacf40beb5af44070a192a9d688ed/XHDatePicker_demo/Assets.xcassets/selected.imageset/选中全天.png -------------------------------------------------------------------------------- /XHDatePicker_demo/Assets.xcassets/selected.imageset/选中全天@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/XHJCoder/XHDatePicker/01c09a9f77bcacf40beb5af44070a192a9d688ed/XHDatePicker_demo/Assets.xcassets/selected.imageset/选中全天@2x.png -------------------------------------------------------------------------------- /XHDatePicker_demo/Assets.xcassets/selected.imageset/选中全天@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/XHJCoder/XHDatePicker/01c09a9f77bcacf40beb5af44070a192a9d688ed/XHDatePicker_demo/Assets.xcassets/selected.imageset/选中全天@3x.png -------------------------------------------------------------------------------- /XHDatePicker_demo/Assets.xcassets/unSelected.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "未选中.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "未选中@2x.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "filename" : "未选中@3x.png", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "version" : 1, 21 | "author" : "xcode" 22 | } 23 | } -------------------------------------------------------------------------------- /XHDatePicker_demo/Assets.xcassets/unSelected.imageset/未选中.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/XHJCoder/XHDatePicker/01c09a9f77bcacf40beb5af44070a192a9d688ed/XHDatePicker_demo/Assets.xcassets/unSelected.imageset/未选中.png -------------------------------------------------------------------------------- /XHDatePicker_demo/Assets.xcassets/unSelected.imageset/未选中@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/XHJCoder/XHDatePicker/01c09a9f77bcacf40beb5af44070a192a9d688ed/XHDatePicker_demo/Assets.xcassets/unSelected.imageset/未选中@2x.png -------------------------------------------------------------------------------- /XHDatePicker_demo/Assets.xcassets/unSelected.imageset/未选中@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/XHJCoder/XHDatePicker/01c09a9f77bcacf40beb5af44070a192a9d688ed/XHDatePicker_demo/Assets.xcassets/unSelected.imageset/未选中@3x.png -------------------------------------------------------------------------------- /XHDatePicker_demo/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 | 27 | 28 | 29 | 30 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | -------------------------------------------------------------------------------- /XHDatePicker_demo/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | zh_CN 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 | 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 | 37 | UISupportedInterfaceOrientations~ipad 38 | 39 | UIInterfaceOrientationPortrait 40 | UIInterfaceOrientationPortraitUpsideDown 41 | UIInterfaceOrientationLandscapeLeft 42 | UIInterfaceOrientationLandscapeRight 43 | 44 | 45 | 46 | -------------------------------------------------------------------------------- /XHDatePicker_demo/TableViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // TableViewController.h 3 | // XHDatePicker 4 | // 5 | // Created by XHJCoder on 2018/4/10. 6 | // Copyright © 2018年 江欣华. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface TableViewController : UITableViewController 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /XHDatePicker_demo/TableViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // TableViewController.m 3 | // XHDatePicker 4 | // 5 | // Created by XHJCoder on 2018/4/10. 6 | // Copyright © 2018年 江欣华. All rights reserved. 7 | // 8 | 9 | #import "TableViewController.h" 10 | #import "XHDatePicker.h" 11 | #import "NSDate+XHExtension.h" 12 | 13 | @interface TableViewController () 14 | 15 | @end 16 | 17 | @implementation TableViewController 18 | 19 | - (void)viewDidLoad { 20 | [super viewDidLoad]; 21 | } 22 | 23 | 24 | #pragma mark - Table view data source 25 | - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { 26 | 27 | XHDatePicker *datePicker = [XHDatePicker showWithCompleteBlock:^(NSDate *date, NSString *dateString) { 28 | NSLog(@"%@ , %@",date, dateString); 29 | }]; 30 | 31 | datePicker.date = [NSDate date:@"2018-05-13 22:55" WithFormat:@"yyyy-MM-dd HH:mm"]; 32 | datePicker.minimumDate = [NSDate date:@"2015-01-14 12:14" WithFormat:@"yyyy-MM-dd HH:mm"]; 33 | datePicker.maximumDate = [NSDate date:@"2022-11-23 07:55" WithFormat:@"yyyy-MM-dd HH:mm"]; 34 | datePicker.themeColor = [UIColor redColor]; 35 | datePicker.dateFormatter = @"yyyy年MM月dd日 HH:mm"; 36 | datePicker.datePickerMode = (int)indexPath.row; 37 | 38 | // datePicker.themeColor = [UIColor colorWithRed:(arc4random_uniform(256) / 255.0) green:(arc4random_uniform(256) / 255.0) blue:(arc4random_uniform(256) / 255.0) alpha:1]; 39 | } 40 | 41 | @end 42 | -------------------------------------------------------------------------------- /XHDatePicker_demo/main.m: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // XHDatePicker 4 | // 5 | // Created by XH_J on 2016/10/25. 6 | // Copyright © 2016年 XHJCoder. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "AppDelegate.h" 11 | 12 | int main(int argc, char * argv[]) { 13 | @autoreleasepool { 14 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); 15 | } 16 | } 17 | --------------------------------------------------------------------------------