iOS - Swift NSCalendar 日历

简介: 前言 public class NSCalendar : NSObject, NSCopying, NSSecureCodingNSCalendar 对世界上现存的常用的历法进行了封装,既提供了不同历法的时间信息,又支持日历的计算。

前言

    public class NSCalendar : NSObject, NSCopying, NSSecureCoding
  • NSCalendar 对世界上现存的常用的历法进行了封装,既提供了不同历法的时间信息,又支持日历的计算。

    • NSCalendar -- 日历类,它提供了大部分的日期计算接口,并且允许您在 NSDate 和 NSDateComponents 之间转换
    • NSTimeZone -- 时区信息
    • NSLocale -- 本地化信息
    • NSDate -- 表示一个绝对的时间点
    • NSDateComponents -- 一个封装了具体年月日、时秒分、周、季度等的类
    • NSDateFormatter -- 用来在日期和字符串之间转换
  • firstWeekday

    • 大家在使用 dateComponents.weekday 获取某天对应的星期时,会发现,星期日对应的值为 1,星期一对应的值为 2,星期二对应的值为 3,依次递推,星期六对应的值为 7,这与我们平时理解的方式不一样。然后,我们就开始找是不是可以设置这种对应关系。终于,我们在 NSCalendar 中发现了 firstWeekday 这个变量,从字面意思上看貌似就是我们寻找的那个东西。可是,设置过 firstWeekday 后,我们又发现完全没有作用,真是郁闷啊!其实,大家不必郁闷,因为郁闷也没用,iOS 中规定的就是周日为 1,周一为 2,周二为 3,周三为 4,周四为 5,周五为 6,周六为 7,无法通过某个设置改变这个事实的,只能在使用的时候注意一下这个规则了。那 firstWeekday 是干什么用的呢?大家设置一下 firstWeekday,再获取一下 dateComponents.weekOfYear 或 dateComponents.weekOfMonth,看看返回的数据是否发生了变化。firstWeekday 的作用确实是修改当前历法中周的起始位置,但是不能修改周日对应的数值,只能修改一年或一个月中周的数量,以及周的次序。

1、日历的创建

    // 根据提供的日历标示符初始化。
    /*
        identifier 的范围可以是:
                                                                                 
            NSCalendarIdentifierGregorian         公历
            NSCalendarIdentifierBuddhist          佛教日历
            NSCalendarIdentifierChinese           中国农历
            NSCalendarIdentifierHebrew            希伯来日历
            NSCalendarIdentifierIslamic           伊斯兰日历
            NSCalendarIdentifierIslamicCivil      伊斯兰教日历
            NSCalendarIdentifierJapanese          日本日历
            NSCalendarIdentifierRepublicOfChina   中华民国日历(台湾)
            NSCalendarIdentifierPersian           波斯历
            NSCalendarIdentifierIndian            印度日历
            NSCalendarIdentifierISO8601           ISO8601
    */
    let cal1:NSCalendar? = NSCalendar(calendarIdentifier: NSCalendarIdentifierGregorian)
    
    // 返回当前客户端的逻辑日历
    /*
        取得的值会一直保持在 cache 中,第一次用此方法实例化对象后,即使修改了系统日历设定,这个对象也不会改变
    */
    let cal2:NSCalendar = NSCalendar.currentCalendar()
    
    // 返回当前客户端的逻辑日历
    /*
        当每次修改系统日历设定,其实例化的对象也会随之改变。
    */
    let cal3:NSCalendar = NSCalendar.autoupdatingCurrentCalendar()

2、日历的设置

    let calendar:NSCalendar = NSCalendar.currentCalendar()
    
    // 设置区域
    calendar.locale = NSLocale(localeIdentifier: "zh_CN")
    
    // 设置时区
    /*
        设置时区,设置为 GMT+8,即北京时间(+8)
    */
    calendar.timeZone = NSTimeZone(abbreviation: "EST")!
    calendar.timeZone = NSTimeZone(forSecondsFromGMT: +28800)
    
    // 设定每周的第一天从星期几开始
    /*
        1 代表星期日开始,2 代表星期一开始,以此类推。默认值是 1
    */
    calendar.firstWeekday = 2
    
    // 设置每年及每月第一周必须包含的最少天数
    /*
        设定第一周最少包括 3 天,则 value 传入 3
    */
    calendar.minimumDaysInFirstWeek = 3

3、日历设置信息的获取

    let calendar:NSCalendar = NSCalendar.currentCalendar()
        
    // 获取日历标示符
    /*
        有效的日历标示符包括:
             
            gregorian
            buddhist
            chinese
            hebrew
            islamic
            islamic-civil
            japanese
            roc
            persian
            indian
            iso8601
    */
    let calendarIdentifier = calendar.calendarIdentifier

    // 获取地区信息
    let localeIdentifier1 = calendar.locale?.localeIdentifier
    let localeIdentifier2: AnyObject? = calendar.locale?.objectForKey(NSLocaleIdentifier)
        
    // 获取时区信息
    let timeZone = calendar.timeZone
        
    // 获取每周的第一天从星期几开始
    let firstWeekday = calendar.firstWeekday
        
    // 获取第一周必须包含的最少天数
    let minimumDaysInFirstWeek = calendar.minimumDaysInFirstWeek

4、日历信息的获取

    let calendar:NSCalendar = NSCalendar.currentCalendar()
  • 1)获取一个小的单位在一个大的单位里面的序数

        let count = calendar.ordinalityOfUnit(NSCalendarUnit.Weekday, inUnit: NSCalendarUnit.WeekOfMonth, forDate: NSDate())
        public func ordinalityOfUnit(smaller: NSCalendarUnit, inUnit larger: NSCalendarUnit, forDate date: NSDate) -> Int
    
        NSCalendarUnit包含的值有:
    
            Era               -- 纪元单位。对于 NSGregorianCalendar (公历)来说,只有公元前(BC)和公元(AD);而对于其它历法可能有很多,
                                 例如日本和历是以每一代君王统治来做计算。
            Year              -- 年单位。值很大,相当于经历了多少年,未来多少年。
            Month             -- 月单位。范围为1-12
            Day               -- 天单位。范围为1-31
            Hour              -- 小时单位。范围为0-24
            Minute            -- 分钟单位。范围为0-60
            Second            -- 秒单位。范围为0-60
            Weekday           -- 星期单位,每周的7天。范围为1-7
            WeekdayOrdinal    -- 没完全搞清楚
    
            Quarter           -- 几刻钟,也就是15分钟。范围为1-4
            WeekOfMonth       -- 月包含的周数。最多为6个周
            WeekOfYear        -- 年包含的周数。最多为53个周
            YearForWeekOfYear -- 没完全搞清楚
            Nanosecond        -- 微妙
            Calendar          --
            TimeZone          -- 没完全搞清楚
    
        <1>、当小单位为 NSCalendarUnitWeekday,大单位为 NSCalendarUnitWeekOfMonth / NSCalendarUnitWeekOfYear 时
             (即某个日期在这一周是第几天),根据 firstWeekday 属性不同,返回的结果也不同。具体说明如下:
    
            当 firstWeekday 被指定为星期天(即 = 1)时,它返回的值与星期几对应的数值保持一致。比如:
                fromDate 传入的参数是星期日,则函数返回 1
                fromDate 传入的参数是星期一,则函数返回 2
            当 firstWeekday 被指定为其它值时(即 <> 1)时,假设firstWeekday 被指定为星期一(即 = 2),那么:
                fromDate 传入的参数是星期一,则函数返回 1
                fromDate 传入的参数是星期二,则函数返回 2
                fromDate 传入的参数是星期日,则函数返回 7
    
        <2>、当小单位为 参数为 NSCalendarUnitWeekOfMonth / NSCalendarUnitWeekOfYear,大单位为 NSCalendarUnitYear 时
             (即某个日期在这一年中是第几周),minimumDaysInFirstWeek 属性影响它的返回值。具体说明如下:
    
                2005年1月
                日   一    二   三   四    五   六
                --------------------------------
                                              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   31
    
                2005年1月第一周包括1号。
                a. 如果将 minimumDaysInFirstWeek 设定 = 1
                则 fromDate 传入1月1号,方法均返回1  ==> 满足 minimumDaysInFirstWeek 指定的天数(最少1天),所以方法将其归为
                                                      2005年的第1周
                则 fromDate 传入1月2-8号,方法均返回2
                则 fromDate 传入1月9-15号,方法均返回3
                ......
    
                b. 如果将 minimumDaysInFirstWeek 设定为 > 1,比如2
                则 fromDate 传入1月1号,方法均返回53  ==> 不足2天,所以方法将其归为2004年的第53周
                则 fromDate 传入1月2-8号,方法均返回1
                则 fromDate 传入1月9-15号,方法均返回2
                ......
    
                2008年1月
                日   一    二   三   四    五   六
                ---------------------------------
                          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   31
    
                2005年1月第一周包括1-5号共5天。
                a. 如果将 minimumDaysInFirstWeek 设定为 <= 5时
                则 fromDate 传入1月1-5号,方法均返回1  ==> 满足 minimumDaysInFirstWeek 指定的天数,所以方法将其归为
                                                        2008年的第1周
                则 fromDate 传入1月6-12号,方法均返回2
                则 fromDate 传入1月13-19号,方法均返回3
                ......
    
                b. 如果将 minimumDaysInFirstWeek 设定为 > 5,比如6
                则 fromDate 传入1月1-5号,方法均返回53  ==> 当周不足6天,所以方法将其归为2007年的第53周
                则 fromDate 传入1月2-8号,方法均返回1
                则 fromDate 传入1月9-15号,方法均返回2
                ......
    
        <3>、当小单位为 参数为 NSCalendarUnitWeekOfMonth / NSCalendarUnitWeekOfYear,大单位为 NSCalendarUnitMonth 时
             (即某个日期在这一个月中是第几周),minimumDaysInFirstWeek 属性影响它的返回值。具体说明如下:
    
                2008年4月
                日   一    二   三   四    五   六
                ---------------------------------
                          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
    
                2008年4月第一周包括1、2、3、4、5号。
                a. 如果将 minimumDaysInFirstWeek 设定为小于或等于5的数
                则 fromDate 传入4月1-5号,方法均返回1
                则 fromDate 传入4月6-12号,方法均返回2
                则 fromDate 传入4月13-19号,方法均返回3
                ....
    
                b. 如果将 minimumDaysInFirstWeek 设定为大于5的数
                则 fromDate 传入1-5号,方法均返回0
                则 fromDate 传入6-12号,方法均返回1
                则 fromDate 传入13-19号,方法均返回2
                ....
  • 2)获取一个小的单位在一个大的单位里面的取值范围

        let range = calendar.rangeOfUnit(NSCalendarUnit.Day, inUnit: NSCalendarUnit.Month, forDate: NSDate())
        public func rangeOfUnit(smaller: NSCalendarUnit, inUnit larger: NSCalendarUnit, forDate date: NSDate) -> NSRange
    
        调用这个方法要明确一点,取得的是"范围"而不是"包含",下面是一些例子:
    
        <1>、小单位是 NSCalendarUnitDay,大单位是 NSCalendarUnitYear,并不是要取这一年包含多少天,而是要取"天"(Day)这个单位
             在这一年(Year)的取值范围。其实不管你提供的日期是多少,返回的值都是"1--31"。
    
        <2>、小单位是 NSCalendarUnitDay,大单位是 NSCalendarUnitMonth。要取得参数时间点所对应的月份下,"天"(Day)的取值范围。
             根据参数时间的月份不同,值也不同。例如2月是1--28、3月是1--31、4月是1--30。
    
        <3>、小单位是 NSCalendarUnitWeekOfMonth / NSCalendarUnitWeekOfYear,大单位是 NSCalendarUnitMonth。要取得参数时间点
             所对应的月份下,"周"(Week)的取值范围。需要注意的是结果会受到 minimumDaysInFirstWeek 属性的影响。在默认 
             minimumDaysInFirstWeek 情况下,取得的范围值一般是"1--5",从日历上可以看出来这个月包含5排,即5个周。
    
        <4>、小单位是 NSCalendarUnitDay,大单位是 NSCalendarUnitWeekOfMonth / NSCalendarUnitWeekOfYear。要取得周所包含
             的"天"(Day)的取值范围。下面是一个示例日历图:
    
                2013年4月
                日   一    二   三   四    五   六
                ---------------------------------
                     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
    
                在上图的日期条件下,假如提供的参数是4月1日--4月6日,那么对应的 week 就是1(第一个周),可以看到第一个周包含有6天,
            从1号开始,那么最终得到的范围值为1--6。
    
            假如提供的参数是4月18日,那么对应的 week 是3(第三个周),第三个周包含有7天,从14号开始,那么最终得到的范围值是14--7。
    
            假如提供的参数是4月30日,那么对应的 week 是5(第五个周),第五个周只包含3天,从28号开始,那么最终得到的范围值是28--3。
  • 3)获取所在日历单位的开始时间及秒数

        var startDate:NSDate? = nil
        var intervalCount:NSTimeInterval = 0
    
        let bl:Bool = calendar.rangeOfUnit(NSCalendarUnit.Month, 
                                 startDate: &startDate, 
                                  interval: &intervalCount, 
                                   forDate: NSDate())
目录
相关文章
|
3月前
|
Swift iOS开发
iOS Swift使用Alamofire请求本地服务器报错-1002
iOS Swift使用Alamofire请求本地服务器报错-1002
102 1
|
4月前
|
Unix 调度 Swift
苹果iOS新手开发之Swift 中获取时间戳有哪些方式?
在Swift中获取时间戳有四种常见方式:1) 使用`Date`对象获取秒级或毫秒级时间戳;2) 通过`CFAbsoluteTimeGetCurrent`获取Core Foundation的秒数,需转换为Unix时间戳;3) 使用`DispatchTime.now()`获取纳秒级精度的调度时间点;4) `ProcessInfo`提供设备启动后的秒数,不表示绝对时间。不同方法适用于不同的精度和场景需求。
156 3
|
7天前
|
安全 Swift iOS开发
Swift 与 UIKit 在 iOS 应用界面开发中的关键技术和实践方法
本文深入探讨了 Swift 与 UIKit 在 iOS 应用界面开发中的关键技术和实践方法。Swift 以其简洁、高效和类型安全的特点,结合 UIKit 丰富的组件和功能,为开发者提供了强大的工具。文章从 Swift 的语法优势、类型安全、编程模型以及与 UIKit 的集成,到 UIKit 的主要组件和功能,再到构建界面的实践技巧和实际案例分析,全面介绍了如何利用这些技术创建高质量的用户界面。
16 2
|
14天前
|
安全 数据处理 Swift
深入探索iOS开发中的Swift语言特性
本文旨在为开发者提供对Swift语言在iOS平台开发的深度理解,涵盖从基础语法到高级特性的全面分析。通过具体案例和代码示例,揭示Swift如何简化编程过程、提高代码效率,并促进iOS应用的创新。文章不仅适合初学者作为入门指南,也适合有经验的开发者深化对Swift语言的认识。
35 9
|
23天前
|
Swift iOS开发 UED
如何使用Swift和UIKit在iOS应用中实现自定义按钮动画
本文通过一个具体案例,介绍如何使用Swift和UIKit在iOS应用中实现自定义按钮动画。当用户点击按钮时,按钮将从圆形变为椭圆形,颜色从蓝色渐变到绿色;释放按钮时,动画以相反方式恢复。通过UIView的动画方法和弹簧动画效果,实现平滑自然的过渡。
41 1
|
27天前
|
安全 API Swift
探索iOS开发中的Swift语言之美
【10月更文挑战第23天】在数字时代的浪潮中,iOS开发如同一艘航船,而Swift语言则是推动这艘船前进的风帆。本文将带你领略Swift的独特魅力,从语法到设计哲学,再到实际应用案例,我们将一步步深入这个现代编程语言的世界。你将发现,Swift不仅仅是一种编程语言,它是苹果生态系统中的一个创新工具,它让iOS开发变得更加高效、安全和有趣。让我们一起启航,探索Swift的奥秘,感受编程的乐趣。
|
1月前
|
Swift iOS开发 UED
如何使用Swift和UIKit在iOS应用中实现自定义按钮动画
【10月更文挑战第18天】本文通过一个具体案例,介绍如何使用Swift和UIKit在iOS应用中实现自定义按钮动画。当用户按下按钮时,按钮将从圆形变为椭圆形并从蓝色渐变为绿色;释放按钮时,动画恢复原状。通过UIView的动画方法和弹簧动画效果,实现平滑自然的动画过渡。
50 5
|
1月前
|
安全 Swift iOS开发
探索iOS开发中的Swift语言之美
在数字时代的浪潮中,移动应用已成为日常生活的延伸。本文将深入探讨iOS平台上的Swift编程语言,揭示其背后的设计哲学、语法特性以及如何利用Swift进行高效开发。我们将通过实际代码示例,展示Swift语言的强大功能和优雅简洁的编程风格,引导读者理解并运用Swift解决实际问题。
|
2月前
|
安全 Swift iOS开发
探索iOS开发之旅:Swift语言的魅力与挑战
【9月更文挑战第21天】在这篇文章中,我们将一起潜入iOS开发的海洋,探索Swift这门现代编程语言的独特之处。从简洁的语法到强大的功能,Swift旨在让开发者能够以更高效、更安全的方式构建应用程序。通过实际代码示例,我们会深入了解Swift如何简化复杂任务,并讨论它面临的挑战和未来的发展方向。无论你是初学者还是有经验的开发者,这篇文章都将为你提供新的视角和知识。
46 4
|
2月前
|
安全 编译器 Swift
探索iOS开发之旅:Swift编程语言的魅力与挑战
【9月更文挑战第5天】在iOS应用开发的广阔天地中,Swift作为苹果官方推荐的编程语言,以其简洁、高效和安全的特点,成为了开发者的新宠。本文将带领你领略Swift语言的独特魅力,同时探讨在实际开发过程中可能遇到的挑战,以及如何克服这些挑战,成为一名优秀的iOS开发者。