swift当月的第一天和最后一天

use*_*025 59 nsdate nscalendar ios swift

我试图迅速获得本月的第一天和最后一天.

到目前为止,我有以下内容:

let dateFormatter = NSDateFormatter()
let date = NSDate()
dateFormatter.dateFormat = "yyyy-MM-dd"
let calendar = NSCalendar.currentCalendar()
let components = calendar.components([.Year, .Month, .Day, .Hour, .Minute, .Second], fromDate: date)

let month = components.month
let year = components.year

let startOfMonth = ("\(year)-\(month)-01")
Run Code Online (Sandbox Code Playgroud)

但我不知道如何获得最后的约会.有缺点的内置方法吗?显然它必须考虑到闰年等.

bra*_*ipt 115

Swift 3和4 drop-in扩展

这实际上得到了很多更容易斯威夫特3+:

  1. 你可以毫无保护地做到这一点(如果你愿意的话可以,但因为DateComponents现在是非可选类型,所以不再需要).
  2. 使用iOS 8 startOfDayForDate(现在startOfDay),您不需要手动将时间设置为12pm,除非您在跨时区进行一些非常疯狂的日历计算.

值得一提的是,其他一些答案声称你可以通过使用来快捷方式Calendar.current.date(byAdding: .month, value: 0, to: Date())!,但是如果失败了,那就是它实际上并没有将当天归零,或者说明了时区的差异.

干得好:

extension Date {
    func startOfMonth() -> Date {
        return Calendar.current.date(from: Calendar.current.dateComponents([.year, .month], from: Calendar.current.startOfDay(for: self)))!
    }

    func endOfMonth() -> Date {
        return Calendar.current.date(byAdding: DateComponents(month: 1, day: -1), to: self.startOfMonth())!
    }
}

print(Date().startOfMonth())     // "2018-02-01 08:00:00 +0000\n"
print(Date().endOfMonth())       // "2018-02-28 08:00:00 +0000\n"
Run Code Online (Sandbox Code Playgroud)

  • 月的开始对我不起作用.它给我前一天的22:00(所以是上个月的最后一天).如果我也使用day组件,那么它可以工作:`Calendar.current.date(from:Calendar.current.dateComponents([.year,.month,.day],from:Calendar.current.startOfDay(for:self)) )!` (6认同)
  • 针对Swift 3进行了更新 (2认同)
  • 顺便说一句,它给了我添加`DateComponents(月:1,日:-1)`的意愿,因为你依赖于无证的行为,它在'day`之前做了`month`.例如,如果今天是5月15日,那么月初是5月1日,如果它在月前减去,那么你将在5月30日而不是5月31日.在两个单独的操作中执行月+1和第-1天似乎更安全.或者使用`calendar.range(of:in:for :)). (2认同)

Mar*_*n R 73

你只需要一个月的第一天

let components = calendar.components([.Year, .Month], fromDate: date)
let startOfMonth = calendar.dateFromComponents(components)!
print(dateFormatter.stringFromDate(startOfMonth)) // 2015-11-01
Run Code Online (Sandbox Code Playgroud)

要获取该月的最后一天,请添加一个月并减去一天:

let comps2 = NSDateComponents()
comps2.month = 1
comps2.day = -1
let endOfMonth = calendar.dateByAddingComponents(comps2, toDate: startOfMonth, options: [])!
print(dateFormatter.stringFromDate(endOfMonth)) // 2015-11-30
Run Code Online (Sandbox Code Playgroud)

或者,使用rangeOfUnit提供月份开始和长度的方法:

var startOfMonth : NSDate?
var lengthOfMonth : NSTimeInterval = 0
calendar.rangeOfUnit(.Month, startDate: &startOfMonth, interval: &lengthOfMonth, forDate: date)
Run Code Online (Sandbox Code Playgroud)

对于月份最后一天的日期,请添加月份减去一秒的长度:

let endOfMonth = startOfMonth!.dateByAddingTimeInterval(lengthOfMonth - 1)
Run Code Online (Sandbox Code Playgroud)

  • @Maks:对于检查“是本月的日期”,我将计算本月的开始和下个月的开始,而不减去任何内容。然后与“if date >= startDate && date < endDate”进行比较 (2认同)

Lui*_*ien 27

随着斯威夫特3和iOS 10,我发现这样做的最简单的方法是CalendardateInterval(of:for:):

guard let interval = calendar.dateInterval(of: .month, for: Date()) else { return }
Run Code Online (Sandbox Code Playgroud)

然后interval.start,您可以使用并interval.end获取所需的日期.

  • 现在每个人都应该使用iOS10+,这个答案是迄今为止最好的 (2认同)

Bha*_*iya 21

斯威夫特3

许多日期示例:

过去6个月, 过去3个月, 昨天,过去7天,过去30天,上个月, 当前月份开始和结束,上个月开始和结束日期

let startDate = dateFormatter.string(from: Date().getThisMonthStart()!)
let endDate = dateFormatter.string(from: Date().getThisMonthEnd()!)

extension Date {

func getLast6Month() -> Date? {
    return Calendar.current.date(byAdding: .month, value: -6, to: self)
}

func getLast3Month() -> Date? {
    return Calendar.current.date(byAdding: .month, value: -3, to: self)
}

func getYesterday() -> Date? {
    return Calendar.current.date(byAdding: .day, value: -1, to: self)
}

func getLast7Day() -> Date? {
    return Calendar.current.date(byAdding: .day, value: -7, to: self)
}
func getLast30Day() -> Date? {
    return Calendar.current.date(byAdding: .day, value: -30, to: self)
}

func getPreviousMonth() -> Date? {
    return Calendar.current.date(byAdding: .month, value: -1, to: self)
}

// This Month Start
func getThisMonthStart() -> Date? {
    let components = Calendar.current.dateComponents([.year, .month], from: self)
    return Calendar.current.date(from: components)!
}

func getThisMonthEnd() -> Date? {
    let components:NSDateComponents = Calendar.current.dateComponents([.year, .month], from: self) as NSDateComponents
    components.month += 1
    components.day = 1
    components.day -= 1
    return Calendar.current.date(from: components as DateComponents)!
}

//Last Month Start
func getLastMonthStart() -> Date? {
    let components:NSDateComponents = Calendar.current.dateComponents([.year, .month], from: self) as NSDateComponents
    components.month -= 1
    return Calendar.current.date(from: components as DateComponents)!
}

//Last Month End
func getLastMonthEnd() -> Date? {
    let components:NSDateComponents = Calendar.current.dateComponents([.year, .month], from: self) as NSDateComponents
    components.day = 1
    components.day -= 1
    return Calendar.current.date(from: components as DateComponents)!
}

}
Run Code Online (Sandbox Code Playgroud)


Zul*_*ain 7

这是最简单的解决方案:

extension Date {

func startOfMonth() -> Date {
    let interval = Calendar.current.dateInterval(of: .month, for: self)
    return (interval?.start.toLocalTime())! // Without toLocalTime it give last months last date
}

func endOfMonth() -> Date {
    let interval = Calendar.current.dateInterval(of: .month, for: self)
    return interval!.end
}

// Convert UTC (or GMT) to local time
func toLocalTime() -> Date {
    let timezone    = TimeZone.current
    let seconds     = TimeInterval(timezone.secondsFromGMT(for: self))
    return Date(timeInterval: seconds, since: self)
}}
Run Code Online (Sandbox Code Playgroud)

然后用您的日期实例调用它们:

print(Date().startOfMonth())
print(Date().endOfMonth())
Run Code Online (Sandbox Code Playgroud)


Fat*_*tie 5

2017年...

首先,获得您需要的月份:

    let cal = Calendar.current
    let d = Calendar.current.date(byAdding: .month, value: 0, to: Date())!

    // for "last month" just use -1, for "next month" just use 1, etc
Run Code Online (Sandbox Code Playgroud)

要获得每月第一天的星期几:

    let c = cal.dateComponents([.year, .month], from: d)
    let FDOM = cal.date(from: c)!
    let dowFDOM = cal.component(.weekday, from: FDOM)

    print("the day-of-week on the 1st is ... \(dowFDOM)")
    // so, that's 1=Sunday, 2=Monday, etc.
Run Code Online (Sandbox Code Playgroud)

要获得当月的天数:

    let r = cal.range(of: .day, in: .month, for: d)!
    let kDays = r.count

    print("the number of days is ... \(kDays)")
Run Code Online (Sandbox Code Playgroud)


Mig*_*ego 5

斯威夫特4

如果您只需要顺序的一天:

func lastDay(ofMonth m: Int, year y: Int) -> Int {
    let cal = Calendar.current
    var comps = DateComponents(calendar: cal, year: y, month: m)
    comps.setValue(m + 1, for: .month)
    comps.setValue(0, for: .day)
    let date = cal.date(from: comps)!
    return cal.component(.day, from: date)
}

lastDay(ofMonth: 2, year: 2018)  // 28
lastDay(ofMonth: 2, year: 2020)  // 29
Run Code Online (Sandbox Code Playgroud)


小智 5

这是我发现的最简单的方法(Swift 5+):

extension Date {

    func getStart(of component: Calendar.Component, calendar: Calendar = Calendar.current) -> Date? {
        return calendar.dateInterval(of: component, for: self)?.start
    }

    func getEnd(of component: Calendar.Component, calendar: Calendar = Calendar.current) -> Date? {
        return calendar.dateInterval(of: component, for: self)?.end
    }
}
Run Code Online (Sandbox Code Playgroud)