YMCalendarUtils.m 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473
  1. //
  2. // YMCalendarUtils.m
  3. // MSYOUPAI
  4. //
  5. // Created by YoMi on 2024/3/3.
  6. // Copyright © 2024 MS. All rights reserved.
  7. //
  8. #import "YMCalendarUtils.h"
  9. @interface YMCalendarUtils ()
  10. @property (nonatomic, strong) NSCalendar *calendar;
  11. @property (nonatomic, strong) NSCalendar *currentCalendar;
  12. @property (nonatomic, strong) NSCalendar *chineseCalendar;
  13. @property (nonatomic, strong) NSCalendar *gregorianCalendar;
  14. @end
  15. @implementation YMCalendarUtils
  16. #pragma mark -- 单例
  17. static YMCalendarUtils *_instance;
  18. + (instancetype)allocWithZone:(struct _NSZone *)zone {
  19. // 也可以使用一次性代码
  20. static dispatch_once_t onceToken;
  21. dispatch_once(&onceToken, ^{
  22. if (_instance == nil) {
  23. _instance = [super allocWithZone:zone];
  24. }
  25. });
  26. return _instance;
  27. }
  28. + (instancetype)shareCalender {
  29. return [[self alloc]init];
  30. }
  31. - (id)copyWithZone:(NSZone *)zone {
  32. return _instance;
  33. }
  34. - (id)mutableCopyWithZone:(NSZone *)zone {
  35. return _instance;
  36. }
  37. - (NSCalendar *)gregorianCalendar {
  38. if (!_gregorianCalendar) {
  39. _gregorianCalendar = [[NSCalendar alloc]initWithCalendarIdentifier:NSCalendarIdentifierGregorian];
  40. }
  41. return _gregorianCalendar;
  42. }
  43. - (NSCalendar *)currentCalendar {
  44. if (!_currentCalendar) {
  45. _currentCalendar = [NSCalendar currentCalendar];
  46. }
  47. return _currentCalendar;
  48. }
  49. - (NSCalendar *)chineseCalendar{
  50. if (!_chineseCalendar) {
  51. _chineseCalendar = [[NSCalendar alloc]initWithCalendarIdentifier:NSCalendarIdentifierChinese];
  52. }
  53. return _chineseCalendar;
  54. }
  55. #pragma mark --与农历相关
  56. - (NSString *)calendarIdentifierChineseWithDate:(NSDate *)date {
  57. NSString *chineseDateStr = @"";
  58. NSCalendarUnit unit = NSCalendarUnitDay | NSCalendarUnitMonth | NSCalendarUnitYear;
  59. NSDateComponents *com = [self.chineseCalendar components:unit fromDate:date];
  60. NSInteger day = com.day;
  61. NSInteger month = com.month;
  62. NSInteger year = com.year;
  63. chineseDateStr = [NSString stringWithFormat:@"%ld-%ld-%ld",(long)year,(long)month,(long)day];
  64. return chineseDateStr;
  65. }
  66. #pragma mark -- 与NSCalendar相关
  67. // 获取当前月份的天数
  68. - (NSInteger)getCurrentMonthForDays {
  69. NSInteger dayNumber = 0;
  70. NSRange range = [self.currentCalendar rangeOfUnit:NSCalendarUnitDay inUnit:NSCalendarUnitMonth forDate:[NSDate date]];
  71. dayNumber = range.length;
  72. return dayNumber;
  73. }
  74. // 获取目标月份的天数
  75. - (NSInteger)getNextNMonthForDays:(NSDate *)date{
  76. NSCalendar * calendar = [NSCalendar currentCalendar];
  77. // 调用rangeOfUnit方法:(返回一样是一个结构体)两个参数一个大单位,一个小单位(.length就是天数,.location就是月)
  78. NSInteger monthNum = [calendar rangeOfUnit:NSCalendarUnitDay inUnit:NSCalendarUnitMonth forDate:date].length;
  79. return monthNum;
  80. }
  81. - (NSInteger)getSumOfDaysForYear:(NSString *)year month:(NSString *)month {
  82. NSDateFormatter * formatter = [[NSDateFormatter alloc] init];
  83. [formatter setDateFormat:@"yyyy-MM"]; // 年-月
  84. NSString * dateStr = [NSString stringWithFormat:@"%@-%@",year,month];
  85. NSDate * date = [formatter dateFromString:dateStr];
  86. //
  87. NSCalendar * calendar = self.gregorianCalendar;
  88. NSRange range = [calendar rangeOfUnit:NSCalendarUnitDay
  89. inUnit: NSCalendarUnitMonth
  90. forDate:date];
  91. return range.length;
  92. }
  93. // 获取某个月的1号的 date 对象
  94. - (NSDate *)getAMonthframDate:(NSDate*)date {
  95. NSCalendar * calendar = [NSCalendar currentCalendar];
  96. // 指定日历单位,如日期和月份。(这里指定了年月日,还有其他字段添加单位.特别齐全 :世纪,年月日时分秒等等等)
  97. NSCalendarUnit dayInfoUnits = NSCalendarUnitEra | NSCalendarUnitYear | NSCalendarUnitMonth | NSCalendarUnitDay;
  98. // NSDateComponents封装了日期的组件,年月日时分秒等(个人感觉像是平时用的model模型)
  99. NSDateComponents *components = [calendar components: dayInfoUnits fromDate:date];
  100. // 指定1号
  101. components.day = 1;
  102. // 转成需要的date对象return
  103. NSDate * nextMonthDate =[calendar dateFromComponents:components];
  104. return nextMonthDate;
  105. }
  106. // 获取某个月的1号是星期几
  107. - (NSString *)getFirstDayWeekForMonth:(NSDate *)date {
  108. NSInteger weekDay = 0;
  109. NSArray *weekStr = @[@"星期日",@"星期一",@"星期二",@"星期三",@"星期四",@"星期五",@"星期六"];
  110. //获取公历日历
  111. NSCalendar *calendar = [[NSCalendar alloc]initWithCalendarIdentifier:NSCalendarIdentifierGregorian];
  112. NSCalendarUnit unit = NSCalendarUnitYear | NSCalendarUnitMonth | NSCalendarUnitDay | NSCalendarUnitHour | NSCalendarUnitMinute | NSCalendarUnitWeekday;
  113. NSDateComponents *components = [calendar components:unit fromDate:date];
  114. weekDay = components.weekday;
  115. weekDay--;
  116. return weekStr[weekDay];
  117. }
  118. // 获取某个月的某天是星期几
  119. - (NSUInteger )getFirstDayWeekIntergerForMonth:(NSDate *)date{
  120. NSUInteger weekDay = 0;
  121. // NSArray *weekStr = @[@"星期日",@"星期一",@"星期二",@"星期三",@"星期四",@"星期五",@"星期六"];
  122. //获取公历日历
  123. NSCalendar *calendar = self.gregorianCalendar;
  124. NSCalendarUnit unit = NSCalendarUnitYear | NSCalendarUnitMonth | NSCalendarUnitDay | NSCalendarUnitHour | NSCalendarUnitMinute | NSCalendarUnitWeekday;
  125. NSDateComponents *components = [calendar components:unit fromDate:date];
  126. weekDay = components.weekday;
  127. weekDay--;
  128. return weekDay;
  129. }
  130. #pragma mark -- 与时间NSDate相关
  131. - (NSString *)getCurrentTimeWithHourMinSecond:(BOOL)flag{
  132. NSDateFormatter * formatter = [[NSDateFormatter alloc]init];
  133. // 格式化系统时间字符串</code>
  134. if (flag) {
  135. [formatter setDateFormat:@"yyyy-MM-dd HH:mm:ss"];
  136. } else {
  137. [formatter setDateFormat:@"yyyy-MM-dd"];
  138. }
  139. NSString * time = [formatter stringFromDate:[NSDate date]];
  140. return time;
  141. }
  142. - (int)getYear{
  143. NSCalendar *calendar = self.currentCalendar;
  144. NSUInteger unitFlags = NSCalendarUnitYear | NSCalendarUnitMonth | NSCalendarUnitDay | NSCalendarUnitHour | NSCalendarUnitMinute | NSCalendarUnitSecond;
  145. NSDateComponents *dateComponent = [calendar components:unitFlags fromDate:[NSDate date]];
  146. return (int)dateComponent.year;
  147. }
  148. - (int)getMonth{
  149. NSCalendar *calendar = self.currentCalendar;
  150. NSUInteger unitFlags = NSCalendarUnitYear | NSCalendarUnitMonth | NSCalendarUnitDay | NSCalendarUnitHour | NSCalendarUnitMinute | NSCalendarUnitSecond;
  151. NSDateComponents *dateComponent = [calendar components:unitFlags fromDate:[NSDate date]];
  152. return (int)dateComponent.month;
  153. }
  154. - (int)getDay{
  155. NSCalendar *calendar = self.currentCalendar;
  156. NSUInteger unitFlags = NSCalendarUnitYear | NSCalendarUnitMonth | NSCalendarUnitDay | NSCalendarUnitHour | NSCalendarUnitMinute | NSCalendarUnitSecond;
  157. NSDateComponents *dateComponent = [calendar components:unitFlags fromDate:[NSDate date]];
  158. return (int)dateComponent.day;
  159. }
  160. - (int)getHour{
  161. NSCalendar *calendar = self.currentCalendar;
  162. NSUInteger unitFlags = NSCalendarUnitYear | NSCalendarUnitMonth | NSCalendarUnitDay | NSCalendarUnitHour | NSCalendarUnitMinute | NSCalendarUnitSecond;
  163. NSDateComponents *dateComponent = [calendar components:unitFlags fromDate:[NSDate date]];
  164. return (int)dateComponent.hour;
  165. }
  166. - (int)getMinute{
  167. NSCalendar *calendar = self.currentCalendar;
  168. NSUInteger unitFlags = NSCalendarUnitYear | NSCalendarUnitMonth | NSCalendarUnitDay | NSCalendarUnitHour | NSCalendarUnitMinute | NSCalendarUnitSecond;
  169. NSDateComponents *dateComponent = [calendar components:unitFlags fromDate:[NSDate date]];
  170. return (int)dateComponent.minute;
  171. }
  172. - (int)getSecond{
  173. NSCalendar *calendar = self.currentCalendar;
  174. NSUInteger unitFlags = NSCalendarUnitYear | NSCalendarUnitMonth | NSCalendarUnitDay | NSCalendarUnitHour | NSCalendarUnitMinute | NSCalendarUnitSecond;
  175. NSDateComponents *dateComponent = [calendar components:unitFlags fromDate:[NSDate date]];
  176. return (int)dateComponent.second;
  177. }
  178. - (NSInteger)getYearWithDate:(NSDate *)date{
  179. NSCalendar *calendar = self.gregorianCalendar;
  180. NSCalendarUnit unit = NSCalendarUnitYear | NSCalendarUnitMonth | NSCalendarUnitDay | NSCalendarUnitHour | NSCalendarUnitMinute | NSCalendarUnitWeekday;
  181. NSDateComponents *components = [calendar components:unit fromDate:date];
  182. return components.year;
  183. }
  184. - (NSInteger)getMonthWithDate:(NSDate *)date{
  185. NSCalendar *calendar = self.gregorianCalendar;
  186. NSCalendarUnit unit = NSCalendarUnitYear | NSCalendarUnitMonth | NSCalendarUnitDay | NSCalendarUnitHour | NSCalendarUnitMinute | NSCalendarUnitWeekday;
  187. NSDateComponents *components = [calendar components:unit fromDate:date];
  188. return components.month;
  189. }
  190. - (NSInteger)getDayWithDate:(NSDate *)date{
  191. NSCalendar *calendar = self.gregorianCalendar;
  192. NSCalendarUnit unit = NSCalendarUnitYear | NSCalendarUnitMonth | NSCalendarUnitDay | NSCalendarUnitHour | NSCalendarUnitMinute | NSCalendarUnitWeekday;
  193. NSDateComponents *components = [calendar components:unit fromDate:date];
  194. return components.day;
  195. }
  196. - (NSInteger)getHourWithDate:(NSDate *)date{
  197. NSCalendar *calendar = self.gregorianCalendar;
  198. NSCalendarUnit unit = NSCalendarUnitYear | NSCalendarUnitMonth | NSCalendarUnitDay | NSCalendarUnitHour | NSCalendarUnitMinute | NSCalendarUnitWeekday;
  199. NSDateComponents *components = [calendar components:unit fromDate:date];
  200. return components.hour;
  201. }
  202. - (NSInteger)getMinuteWithDate:(NSDate *)date{
  203. NSCalendar *calendar = self.gregorianCalendar;
  204. NSCalendarUnit unit = NSCalendarUnitYear | NSCalendarUnitMonth | NSCalendarUnitDay | NSCalendarUnitHour | NSCalendarUnitMinute | NSCalendarUnitWeekday;
  205. NSDateComponents *components = [calendar components:unit fromDate:date];
  206. return components.minute;
  207. }
  208. - (NSInteger)getSecondWithDate:(NSDate *)date{
  209. NSCalendar *calendar = self.gregorianCalendar;
  210. NSCalendarUnit unit = NSCalendarUnitYear | NSCalendarUnitMonth | NSCalendarUnitDay | NSCalendarUnitHour | NSCalendarUnitMinute | NSCalendarUnitWeekday;
  211. NSDateComponents *components = [calendar components:unit fromDate:date];
  212. return components.second;
  213. }
  214. - (NSTimeInterval )timeIntervalWithDateStr:(NSString *)dateStr dateStrFormatterStr:(NSString *)formatterStr {
  215. NSDate *date = [self dateWithDateStr:dateStr dateStrFormatterStr:formatterStr];
  216. NSTimeInterval timeInterval = [date timeIntervalSince1970];
  217. return timeInterval;
  218. }
  219. // 字符串时间 --> NSDate
  220. - (NSDate *)dateWithDateStr:(NSString *)dateStr dateStrFormatterStr:(NSString *)formatterStr {
  221. NSDateFormatter *formatter = [[NSDateFormatter alloc]init];
  222. [formatter setDateFormat:formatterStr];
  223. NSDate *date = [formatter dateFromString:dateStr];
  224. return date;
  225. }
  226. // NSDate --> 字符串时间
  227. - (NSString *)dateStrWithDate:(NSDate *)date dateStrFormatterStr:(NSString *)formatterStr {
  228. NSDateFormatter *formatter = [[NSDateFormatter alloc]init];
  229. [formatter setDateFormat:formatterStr];
  230. NSString *dateStr = [formatter stringFromDate:date];
  231. return dateStr;
  232. }
  233. // 当前时间与指定时间的间隔
  234. - (NSString *)getStandardTimeInterval:(NSTimeInterval)interval{
  235. //当前时间与1970时间戳(秒为单位)
  236. NSTimeInterval time = [[NSDate date] timeIntervalSince1970];
  237. // 当前时间戳-传入的时间戳=差值(比如朋友圈动态发表时间为10分钟前(当前时间-发表时间))
  238. NSTimeInterval timeInterval = time-interval;
  239. //计算出天、小时、分钟
  240. int day = timeInterval/(60*60*24);
  241. int hour = ((long)timeInterval%(60*60*24))/(60*60);
  242. int minite = ((long)timeInterval%(60*60*24))%(60*60)/60;
  243. NSMutableString * timeStr = [[NSMutableString alloc]init];
  244. // 逻辑判断
  245. if (day!=0) {
  246. [timeStr appendString:[NSString stringWithFormat:@"%d天",day]];
  247. }else{
  248. if (hour!=0) {
  249. [timeStr appendString:[NSString stringWithFormat:@"%d小时",hour]];
  250. }else{
  251. if (minite<1) {
  252. [timeStr appendString:@"刚刚"];
  253. }else{
  254. [timeStr appendString:[NSString stringWithFormat:@"%d分钟",minite]];
  255. }
  256. }
  257. }
  258. return timeStr;
  259. }
  260. // 当前时间与指定时间的间隔(返回分钟)
  261. - (NSInteger )getDifferenceMinWithTimeInterval:(NSTimeInterval)interval{
  262. //当前时间与1970时间戳(秒为单位)
  263. NSTimeInterval time = [[NSDate date] timeIntervalSince1970];
  264. // 当前时间戳-传入的时间戳=差值(比如朋友圈动态发表时间为10分钟前(当前时间-发表时间))
  265. NSTimeInterval timeInterval = time - interval;
  266. // if (time > interval) {
  267. // timeInterval = fabs(time - interval);
  268. //
  269. // } else {
  270. // timeInterval = fabs(interval - time);
  271. //
  272. // }
  273. //计算分
  274. NSInteger minite = (long)timeInterval/60;
  275. return minite;
  276. }
  277. - (NSInteger)numberOfDaysWithFromDate:(NSDate *)fromDate toDate:(NSDate *)toDate{
  278. NSCalendar *calendar = self.gregorianCalendar;
  279. NSDateComponents *comp = [calendar components:NSCalendarUnitDay fromDate:fromDate toDate:toDate options:NSCalendarWrapComponents];
  280. return comp.day;
  281. }
  282. /**
  283. 计算当前日期的前一天或者后一天
  284. @param later 是否计算后一天
  285. @param currentDateStr 当期的日期
  286. @return 返回计算后的字符串
  287. */
  288. - (NSString *)calculateMonthDay:(BOOL)later withCurrentDateStr:(NSString *)currentDateStr {
  289. NSInteger second = 0;
  290. if (later) {//后一天
  291. second = 24*60*60;
  292. } else {
  293. second = - 24* 60 * 60;
  294. }
  295. NSCalendar *calendar = self.currentCalendar;
  296. NSDateFormatter *inputFormatter = [[NSDateFormatter alloc] init];
  297. [inputFormatter setLocale:[[NSLocale alloc] initWithLocaleIdentifier:@"en_US"]];
  298. [inputFormatter setDateFormat:@"yyyy-MM-dd"];
  299. NSDate *inputDate = [inputFormatter dateFromString:currentDateStr];
  300. NSDate *nextDate = [NSDate dateWithTimeInterval:second sinceDate:inputDate];
  301. NSDateComponents *comps = [calendar components:NSCalendarUnitYear|NSCalendarUnitMonth|NSCalendarUnitWeekday|NSCalendarUnitDay fromDate:nextDate];
  302. NSString *month = comps.month > 9 ? [NSString stringWithFormat:@"%ld",(long)comps.month]:[NSString stringWithFormat:@"0%ld",(long)comps.month];
  303. NSString *day = comps.day > 9 ?[NSString stringWithFormat:@"%ld",(long)comps.day]:[NSString stringWithFormat:@"0%ld",(long)comps.day];
  304. NSString *currentDate = [NSString stringWithFormat:@"%ld-%@-%@",(long)comps.year,month,day];
  305. return currentDate;
  306. }
  307. /**
  308. 计算前一天或者后一天
  309. @param later 是否是后一天
  310. @param currentDateStr 要计算的日期
  311. @return 返回的日期字典key:year、month、day
  312. */
  313. - (NSDictionary *)calculateDate:(BOOL)later withCurrentDateStr:(NSString *)currentDateStr {
  314. NSInteger second = 0;
  315. if (later) {//后一天
  316. second = 24*60*60;
  317. } else {
  318. second = -24*60*60;
  319. }
  320. NSCalendar *calendar = self.currentCalendar;
  321. NSDateFormatter *inputFormatter = [[NSDateFormatter alloc] init];
  322. [inputFormatter setLocale:[[NSLocale alloc] initWithLocaleIdentifier:@"en_US"]];
  323. [inputFormatter setDateFormat:@"yyyy-MM-dd"];
  324. NSDate *inputDate = [inputFormatter dateFromString:currentDateStr];
  325. NSDate *nextDate = [NSDate dateWithTimeInterval:second sinceDate:inputDate];
  326. NSDateComponents *comps = [calendar components:NSCalendarUnitYear|NSCalendarUnitMonth|NSCalendarUnitWeekday|NSCalendarUnitDay fromDate:nextDate];
  327. NSString *month = comps.month > 9 ? [NSString stringWithFormat:@"%ld",(long)comps.month]:[NSString stringWithFormat:@"0%ld",(long)comps.month];
  328. NSString *day = comps.day > 9 ?[NSString stringWithFormat:@"%ld",(long)comps.day]:[NSString stringWithFormat:@"0%ld",(long)comps.day];
  329. NSDictionary *resultDic = @{@"year":@(comps.year),@"month":month,@"day":day};
  330. return resultDic;
  331. }
  332. - (BOOL)isTodayWithDate:(NSDate *)date{
  333. NSCalendar *calendar = [NSCalendar currentCalendar];
  334. int unit = NSCalendarUnitDay | NSCalendarUnitMonth | NSCalendarUnitYear;
  335. // 1.获得当前时间的年月日
  336. NSDateComponents *nowCmps = [calendar components:unit fromDate:[NSDate date]];
  337. // 2.获得self的年月日
  338. NSDateComponents *selfCmps = [calendar components:unit fromDate:date];
  339. return
  340. (selfCmps.year == nowCmps.year) &&
  341. (selfCmps.month == nowCmps.month) &&
  342. (selfCmps.day == nowCmps.day);
  343. }
  344. /**
  345. 获取 当前时间的时间戳
  346. @return 返回的时间戳
  347. */
  348. - (NSTimeInterval )currentTimeInterval {
  349. return [self timeIntervalWithDateStr:[self getCurrentTimeWithHourMinSecond:YES] dateStrFormatterStr:@"yyyy-MM-dd HH:mm:ss"];
  350. }
  351. @end