Newer
Older
Productization_H5_IOS / template / Common / Tool / Date+Ex.swift
@zhangfeng zhangfeng on 8 Aug 2023 8 KB commit first


import Foundation
/// 时间与字符串的转换
extension Date {
    /// Date转换为时间字符串
    ///
    /// - Parameter format: dateFormat 默认 yyyy-MM-dd HH:mm:ss
    /// - Returns: dateFormat格式时间字符串
    public func dateToString(_ format: String = "yyyy-MM-dd HH:mm:ss") -> String {
        let dateFormatter = DateFormatter()
        dateFormatter.dateFormat = format
        return dateFormatter.string(from: self)
    }
}

extension String {
    /// 时间字符串转 Date
    ///
    /// - Parameter format: dateFormat 默认
    /// - Returns: Date
    public func stringToDate(_ format: String = "yyyy-MM-dd HH:mm:ss") -> Date? {
        if self.isEmpty {
            return nil
        }
        let dateFormatter = DateFormatter()
        dateFormatter.dateFormat = format
        return dateFormatter.date(from: self)
    }
}

extension Date {
    /// 当前时间所在月的总天数
    ///
    /// - Returns: 当前时间所在月的总天数
    public func numberOfDaysInCurrentMonth() -> Int {
        let range = self.currentCalendar.range(of: Calendar.Component.day, in: Calendar.Component.month, for: self)
        if range == nil, (range?.isEmpty)! {
            return 0
        } else {
            return (range?.count)!
        }
    }

    /// 获取本月第一天时间
    ///
    /// - Returns: 本月第一天时间
    public func firstDayOfCurrentMonth() -> Date? {
        var startDate: Date = Date()
        var interval: TimeInterval = 0
        let ok = self.currentCalendar.dateInterval(of: Calendar.Component.month, start: &startDate, interval: &interval, for: self)
        if ok == true {
            return startDate
        } else {
            return nil
        }
    }

    /// 获取本月最后一天最后一秒
    ///
    /// - Returns: 本月最后一天最后一秒
    public func endDayLastSecondOfCurrentMonth() -> Date? {
        return self.endDayOfCurrentMonthIsFistSecond(firstSecond: true)
    }

    /// 获取本月最后一天第一秒
    ///
    /// - Returns: 本月最后一天第一秒
    public func endDayFistSecondOfCurrentMonth() -> Date? {
        return self.endDayOfCurrentMonthIsFistSecond(firstSecond: false)
    }

    /// 获取当前时间的年
    ///
    /// - Returns: 当前时间的年
    public func year() -> Int {
        let components = self.currentCalendar.dateComponents([.year], from: self)
        return components.year!
    }

    /// 获取当前时间的月
    ///
    /// - Returns: 当前时间的月
    public func month() -> Int {
        let components = self.currentCalendar.dateComponents([.month], from: self)
        return components.month!
    }

    /// 获取当前时间的天
    ///
    /// - Returns: 当前时间的天
    public func day() -> Int {
        let components = self.currentCalendar.dateComponents([.day], from: self)
        return components.day!
    }

    /// 获取当前时间的小时
    public func hour() -> Int {
        let components = self.currentCalendar.dateComponents([.hour], from: self)
        return components.hour!
    }

    /// 获取当前时间的分钟
    public func minute() -> Int {
        let components = self.currentCalendar.dateComponents([.minute], from: self)
        return components.minute!
    }

    /// 获取当前时间的秒
    public func second() -> Int {
        let components = self.currentCalendar.dateComponents([.second], from: self)
        return components.second!
    }

    /// 获取当前时间所在月的第一天
    ///
    /// - Returns: 所在月的第一天
    public func firstWeekdayInThisMonth() -> Int {
        var calendar = self.currentCalendar
        calendar.firstWeekday = 1
        var comp = calendar.dateComponents([.year, .month, .day], from: self)
        comp.day = 1
        let date = calendar.date(from: comp)
        let firstWeekday = calendar.ordinality(of: .day, in: .month, for: date!)
        return firstWeekday! - 1
    }

    /// 当前时间所在月的总天数
    ///
    /// - Returns: 当前时间所在月的总天数
    public func totaldaysInMonth() -> Int {
        let range = self.currentCalendar.range(of: .day, in: .month, for: self)
        return (range?.count)!
    }

    /// 当前时间上月这一天
    ///
    /// - Returns: 当前时间上月这一天
    public func lastMonth() -> Date? {
        var dateComponents = DateComponents()
        dateComponents.month = -1
        return self.currentCalendar.date(byAdding: dateComponents, to: self)
    }

    /// 当前时间下月这一天
    ///
    /// - Returns: 当前时间下月这一天
    public func nextMonth() -> Date? {
        var dateComponents = DateComponents()
        dateComponents.month = +1
        return self.currentCalendar.date(byAdding: dateComponents, to: self)
    }
    
    /// 获取间隔天数的时间
    /// - Parameter interval: 间隔天数。 例 +1 -1
    /// - Returns: 时间
    public func intervalDay(_ count: Int) -> Date? {
        var dateComponents = DateComponents()
        dateComponents.day = count
        return self.currentCalendar.date(byAdding: dateComponents, to: self)
    }
    
    /// 当前日期的星期   //1.Sunday. 2.Monday. 3.Tuesday. 4.Wednesday. 5.Thursday. 6.Friday. 7.Saturday.
    ///
    /// - Returns: 1.Sunday. 2.Monday. 3.Tuesday. 4.Wednesday. 5.Thursday. 6.Friday. 7.Saturday.
    public func numOfweek() -> Int {
        var calendar = self.currentCalendar
        calendar.locale = Locale(identifier: "zh_CN")
        let comps = calendar.dateComponents([.year, .month, .day, .weekday, .hour, .minute, .second], from: self)
        return comps.weekday != nil ? comps.weekday! : 0
    }

    /// 当前日期周几  //周日,周一,周二,周三,周四,周五,周六
    ///
    /// - Returns: 周日,周一,周二,周三,周四,周五,周六
    public func numOfWeekShortFormat() -> String {
        let dateFormat = DateFormatter()
        dateFormat.dateFormat = "EEE"
        let zh_Locale = Locale(identifier: "zh-Hans")
        dateFormat.locale = zh_Locale
        return dateFormat.string(from: self)
    }

    /// 当前日期星期几  //星期日,星期一,星期二,星期三,星期四,星期五,星期六
    ///
    /// - Returns: 星期日,星期一,星期二,星期三,星期四,星期五,星期六
    public func numOfWeekLongFormat() -> String {
        let dateFormat = DateFormatter()
        dateFormat.dateFormat = "EEEE"
        let zh_Locale = Locale(identifier: "zh-Hans")
        dateFormat.locale = zh_Locale
        return dateFormat.string(from: self)
    }

    /// NSDate转换为当地时区时间
    ///
    /// - Returns: 当地时区时间
    public func localDate() -> Date {
        let zone = TimeZone.current
        let interval = zone.secondsFromGMT(for: self)
        return self.addingTimeInterval(TimeInterval(interval))
    }

    /// 获取偏移日期 year = 1表示1年后的时间 year = -1为1年前的日期,month day 类推
    func getOffsetDate(year: Int = 0, month: Int = 0, day: Int = 0) -> Date {
        let curDate = self
        let calendar = Calendar(identifier: .gregorian)
        var lastMonthComps = DateComponents()
        lastMonthComps.year = year
        lastMonthComps.month = month
        lastMonthComps.day = day
        let newDate = calendar.date(byAdding: lastMonthComps, to: curDate)
        return newDate ?? curDate
    }
}

extension Date {
    /// 本月最后一天最后一秒 或 第一秒
    ///
    /// - Parameter firstSecond: 是否是第一秒
    /// - Returns: 最后一天最后一秒 或 第一秒
    private func endDayOfCurrentMonthIsFistSecond(firstSecond: Bool) -> Date? {
        var dateComponents = DateComponents()
        dateComponents.month = 1
        if firstSecond {
            dateComponents.day = -1
        } else {
            dateComponents.second = -1
        }
        let date = self.currentCalendar.date(byAdding: dateComponents, to: self.firstDayOfCurrentMonth()!, wrappingComponents: false)
        return date
    }

    /// 获取当前日历管理器
    private var currentCalendar: Calendar {
        if #available(iOS 9, *) {
            return Calendar(identifier: Calendar.Identifier.gregorian)
        } else {
            return Calendar.current
        }
    }
}

extension Date {
    /// 获取各个时段的问候语
    static func getGreetings() -> String {
        let now = Date()
        let comps = now.currentCalendar.dateComponents([Calendar.Component.hour], from: now)
        let hour = comps.hour ?? 0
        switch hour {
        case 0 ..< 5:
            return "凌晨好~"
        case 5 ..< 9:
            return "早上好~"
        case 9 ..< 12:
            return "上午好~"
        case 12 ..< 14:
            return "中午好~"
        case 14 ..< 18:
            return "下午好~"
        case 18 ..< 24:
            return "晚上好~"
        default:
            break
        }
        return "你好~"
    }
}