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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/33605816/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-31 08:12:27  来源:igfitidea点击:

first and last day of the current month in swift

iosswiftnsdatenscalendar

提问by user2363025

I'm trying to get the first and last day of the month in swift.

我试图快速获得本月的第一天和最后一天。

So far I have the following:

到目前为止,我有以下几点:

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")

But I'm not sure how to get the last date. Is there a built in method I'm missing? Obviously it has to take into account leap years etc.

但我不确定如何获得最后日期。是否有我缺少的内置方法?显然,它必须考虑闰年等。

回答by brandonscript

Swift 3 and 4 drop-in extensions

Swift 3 和 4 插入式扩展

This actually gets a loteasier with Swift 3+:

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

  1. You can do it without guard (you could if you wanted to, but because DateComponentsis a non-optional type now, it's no longer necessary).
  2. Using iOS 8's startOfDayForDate(now startOfDay), you don't need to manually set the time to 12pm unless you're doing some really crazy calendar calculations across time zones.
  1. 您可以在没有保护的情况下执行此操作(如果您愿意,可以这样做,但由于DateComponents现在是非可选类型,因此不再需要)。
  2. 使用 iOS 8 startOfDayForDate(现在startOfDay),您无需手动将时间设置为下午 12 点,除非您正在跨时区进行一些非常疯狂的日历计算。

It's worth mentioning that some of the other answers claim you can shortcut this by using Calendar.current.date(byAdding: .month, value: 0, to: Date())!, but where this fails, is that it doesn't actually zero out the day, or account for differences in timezones.

值得一提的是,其他一些答案声称您可以通过使用来缩短此操作Calendar.current.date(byAdding: .month, value: 0, to: Date())!,但是失败的地方在于它实际上并没有将一天归零,也没有考虑到时区的差异。

Here you go:

干得好:

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"

回答by Martin R

You get the first day of the month simply with

您只需使用以下命令即可获得本月的第一天

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

To get the last day of the month, add one month and subtract one day:

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

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

Alternatively, use the rangeOfUnitmethod which gives you the start and the length of the month:

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

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

For a date on the last day of month, add the length of the month minus one second:

对于一个月的最后一天的日期,加上一个月的长度减去一秒:

let endOfMonth = startOfMonth!.dateByAddingTimeInterval(lengthOfMonth - 1)

Updated for Swift5:

为 Swift5 更新:

extension Date {
    var startOfDay: Date {
        return Calendar.current.startOfDay(for: self)
    }

    var startOfMonth: Date {

        let calendar = Calendar(identifier: .gregorian)
        let components = calendar.dateComponents([.year, .month], from: self)

        return  calendar.date(from: components)!
    }

    var endOfDay: Date {
        var components = DateComponents()
        components.day = 1
        components.second = -1
        return Calendar.current.date(byAdding: components, to: startOfDay)!
    }

    var endOfMonth: Date {
        var components = DateComponents()
        components.month = 1
        components.second = -1
        return Calendar(identifier: .gregorian).date(byAdding: components, to: startOfMonth)!
    }

    func isMonday() -> Bool {
        let calendar = Calendar(identifier: .gregorian)
        let components = calendar.dateComponents([.weekday], from: self)
        return components.weekday == 2
    }
}

回答by LuisCien

With Swift 3 & iOS 10 the easiest way I found to do this is Calendar's dateInterval(of:for:):

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

guard let interval = calendar.dateInterval(of: .month, for: Date()) else { return }

You can then use interval.startand interval.endto get the dates you need.

然后您可以使用interval.startinterval.end来获取您需要的日期。

回答by Bhadresh Kathiriya

Swift 3

斯威夫特 3

Many date example for :

许多日期示例:

Last 6 month, last 3 month, yesterday, last 7 day, last 30 day, previous month,current month start & end, last month start & end date

过去 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)!
}

}

回答by Miguel Gallego

Swift 4

斯威夫特 4

If you only need the ordinal day:

如果您只需要序数日:

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

回答by Fattie

2017...

2017...

First, get the month you need:

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

    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

To get the day-of-the-week for the first day of the month:

要获取该月第一天的星期几:

    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.

To get the number of days in the month:

要获取一个月中的天数:

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

    print("the number of days is ... \(kDays)")

回答by Alfredo Luco G

In swift 3, if you put 0 to day component you can get the last day of the month. There's an example code:

在 swift 3 中,如果您将 0 放在 day 组件中,您可以获得该月的最后一天。有一个示例代码:

 public func isMoreDays(date: Date, asc: Bool)->Bool{
    //components
    var dayComponents = self.getDateComponents(date: date)
    //asc is true if ascendant or false if descendant
    dayComponents.day = asc ?  0 : 1
    //plus 1 to month 'cos if you set up day to 0 you are going to the previous month
    dayComponents.month = asc ? dayComponents.month! + 1 : dayComponents.month

    //instantiate calendar and get the date
    let calendar : Calendar = NSCalendar.current
    let day = calendar.date(from: dayComponents)

    //date comparison
    if(day?.compare(date) == .orderedSame){
        return false
    }
    return true
}

回答by Zulqarnain

Here is easiest solution:

这是最简单的解决方案:

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)
}}

and then call these with your date instance:

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

print(Date().startOfMonth())
print(Date().endOfMonth())

回答by Imanou Petit

With Swift 3, you can choose one of the two following patters in order to retrieve the first and last days of a month.

使用 Swift 3,您可以选择以下两种模式之一来检索一个月的第一天和最后一天。



#1. Using CalendardateComponents(_:from:), date(from:)and date(byAdding:to:wrappingComponents:)methods

#1. 使用CalendardateComponents(_:from:),date(from:)date(byAdding:to:wrappingComponents:)方法

With this pattern, you first get the date of the first day of a month then add a month and remove a day from it in order to get the date of the last day of the month. The Playground code below shows how to set it:

使用此模式,您首先获取一个月的第一天的日期,然后添加一个月并从中删除一天以获得该月的最后一天的日期。下面的 Playground 代码显示了如何设置它:

import Foundation

// Set calendar and date 
let calendar = Calendar.current
let date = calendar.date(byAdding: DateComponents(day: -10), to: Date())!

// Get first day of month
let firstDayComponents = calendar.dateComponents([.year, .month], from: date)
let firstDay = calendar.date(from: firstDayComponents)!

// Get last day of month
let lastDayComponents = DateComponents(month: 1, day: -1)
let lastDay = calendar.date(byAdding: lastDayComponents, to: firstDay)!

// Set date formatter
let dateFormatter = DateFormatter()
dateFormatter.locale = Locale(identifier: "en_UK")
dateFormatter.dateStyle = .long
dateFormatter.timeStyle = .long

// Print results
print(dateFormatter.string(from: date)) // Prints: 22 March 2017 at 18:07:15 CET
print(dateFormatter.string(from: firstDay)) // Prints: 1 March 2017 at 00:00:00 CET
print(dateFormatter.string(from: lastDay)) // Prints: 31 March 2017 at 00:00:00 CEST


#2. Using Calendarrange(of:in:for:), dateComponents(_:from:)and date(from:)and methods

#2. 使用Calendarrange(of:in:for:)dateComponents(_:from:)并且date(from:)和方法

With this pattern, you get a range of absolute day values in a month and then retrieve the dates of the first day and last day of the month from it. The Playground code below shows how to set it:

使用此模式,您可以获得一个月中的绝对日期值范围,然后从中检索该月的第一天和最后一天的日期。下面的 Playground 代码显示了如何设置它:

import Foundation

// Set calendar and date
let calendar = Calendar.current
let date = calendar.date(byAdding: DateComponents(day: -10), to: Date())!

// Get range of days in month
let range = calendar.range(of: .day, in: .month, for: date)! // Range(1..<32)

// Get first day of month
var firstDayComponents = calendar.dateComponents([.year, .month], from: date)
firstDayComponents.day = range.lowerBound
let firstDay = calendar.date(from: firstDayComponents)!

// Get last day of month
var lastDayComponents = calendar.dateComponents([.year, .month], from: date)
lastDayComponents.day = range.upperBound - 1
//lastDayComponents.day = range.count // also works
let lastDay = calendar.date(from: lastDayComponents)!

// Set date formatter
let dateFormatter = DateFormatter()
dateFormatter.locale = Locale(identifier: "en_UK")
dateFormatter.dateStyle = .long
dateFormatter.timeStyle = .long

// Print results
print(dateFormatter.string(from: date)) // prints: 22 March 2017 at 18:07:15 CET
print(dateFormatter.string(from: firstDay)) // prints: 1 March 2017 at 00:00:00 CET
print(dateFormatter.string(from: lastDay)) // prints: 31 March 2017 at 00:00:00 CEST

回答by rubik

This is the simplest way that I found (Swift 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
    }
}