Ich versuche, den ersten und letzten Tag des Monats schnell zu erreichen.
Bisher habe ich folgendes:
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")
Aber ich bin mir nicht sicher, wie ich das letzte Date bekommen soll. Gibt es eine eingebaute Methode, die mir fehlt? Offensichtlich muss es Schaltjahre usw. berücksichtigen.
ios
swift
nsdate
nscalendar
user2363025
quelle
quelle
Antworten:
Sie erhalten den ersten Tag des Monats einfach mit
let components = calendar.components([.Year, .Month], fromDate: date) let startOfMonth = calendar.dateFromComponents(components)! print(dateFormatter.stringFromDate(startOfMonth)) // 2015-11-01
Um den letzten Tag des Monats zu erhalten, addieren Sie einen Monat und subtrahieren Sie einen Tag:
let comps2 = NSDateComponents() comps2.month = 1 comps2.day = -1 let endOfMonth = calendar.dateByAddingComponents(comps2, toDate: startOfMonth, options: [])! print(dateFormatter.stringFromDate(endOfMonth)) // 2015-11-30
Alternativ können Sie die
rangeOfUnit
Methode verwenden, mit der Sie den Beginn und die Länge des Monats angeben:var startOfMonth : NSDate? var lengthOfMonth : NSTimeInterval = 0 calendar.rangeOfUnit(.Month, startDate: &startOfMonth, interval: &lengthOfMonth, forDate: date)
Addieren Sie für ein Datum am letzten Tag des Monats die Länge des Monats minus eine Sekunde:
let endOfMonth = startOfMonth!.dateByAddingTimeInterval(lengthOfMonth - 1)
Aktualisiert für 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 } }
quelle
if date >= startDate && date < endDate
Schnelle Drop-In-Erweiterungen für 3 und 4
Mit Swift 3+ wird dies tatsächlich viel einfacher:
DateComponents
es sich jetzt um einen nicht optionalen Typ handelt, ist er nicht mehr erforderlich).startOfDayForDate
(jetztstartOfDay
) müssen Sie die Zeit nicht manuell auf 12 Uhr einstellen, es sei denn, Sie führen einige wirklich verrückte Kalenderberechnungen über Zeitzonen hinweg durch.Es ist erwähnenswert, dass einige der anderen Antworten behaupten, Sie könnten dies mit verwenden
Calendar.current.date(byAdding: .month, value: 0, to: Date())!
, aber wenn dies fehlschlägt, ist es, dass es den Tag nicht auf Null setzt oder Unterschiede in den Zeitzonen berücksichtigt.Bitte schön:
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"
quelle
Non-optional expression of type 'Calendar' used in a check for optionals
. Irgendwelche Vorschläge?DateComponents(month: 1, day: -1)
weil Sie sich auf undokumentiertes Verhalten verlassen, wobei diesmonth
vorher der Fall istday
. Wenn heute beispielsweise der 15. Mai ist, ist der Monatsanfang der 1. Mai, und wenn er Tag vor Monat abgezogen wird, erhalten Sie den 30. Mai anstelle des 31. Mai. Es scheint sicherer zu sein, Monat +1 und Tag -1 in zwei getrennten Operationen auszuführen. Oder verwenden Siecalendar.range(of:in:for:)
stattdessen.Calendar.current.date(from: Calendar.current.dateComponents([.year, .month, .day], from: Calendar.current.startOfDay(for: self)))!
Mit Swift 3 & iOS 10 der einfachste Weg , fand ich , dies zu tun ist
Calendar
‚sdateInterval(of:for:)
:guard let interval = calendar.dateInterval(of: .month, for: Date()) else { return }
Sie können dann
interval.start
und verwendeninterval.end
, um die Daten zu erhalten, die Sie benötigen.quelle
Swift 3
Viele Datumsbeispiele für:
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)! } }
quelle
Swift 4
Wenn Sie nur den Ordnungszeitpunkt benötigen:
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
quelle
2017 ...
Holen Sie sich zuerst den Monat, den Sie brauchen:
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
So erhalten Sie den Wochentag für den ersten Tag des Monats:
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.
So ermitteln Sie die Anzahl der Tage im Monat:
let r = cal.range(of: .day, in: .month, for: d)! let kDays = r.count print("the number of days is ... \(kDays)")
quelle
Hier ist die einfachste Lösung:
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) }}
und rufen Sie diese dann mit Ihrer Datumsinstanz auf:
print(Date().startOfMonth()) print(Date().endOfMonth())
quelle
Mit Swift 3 können Sie eines der beiden folgenden Muster auswählen, um den ersten und den letzten Tag eines Monats abzurufen.
# 1. Unter Verwendung
Calendar
dateComponents(_:from:)
,date(from:)
unddate(byAdding:to:wrappingComponents:)
MethodenMit diesem Muster erhalten Sie zuerst das Datum des ersten Tages eines Monats, fügen dann einen Monat hinzu und entfernen einen Tag daraus, um das Datum des letzten Tages des Monats zu erhalten. Der folgende Spielplatzcode zeigt, wie Sie ihn einstellen:
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. Unter Verwendung
Calendar
range(of:in:for:)
,dateComponents(_:from:)
unddate(from:)
und MethodenMit diesem Muster erhalten Sie einen Bereich von absoluten Tageswerten in einem Monat und rufen dann die Daten des ersten Tages und des letzten Tages des Monats ab. Der folgende Spielplatzcode zeigt, wie Sie ihn einstellen:
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
quelle
Wenn Sie in Swift 3 die Komponente 0 auf Tag setzen, können Sie den letzten Tag des Monats abrufen. Es gibt einen Beispielcode:
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 }
quelle
Dies ist der einfachste Weg, den ich gefunden habe (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 } }
quelle
/** Get last day of month.. */ private func getLastDay(year:Int, month:Int) -> Int { var ret:Int = -1 switch month { case 1: ret = 31 break case 2: break case 3: ret = 31 break case 4: ret = 30 break case 5: ret = 31 break case 6: ret = 30 break case 7: ret = 31 break case 8: ret = 31 break case 9: ret = 30 break case 10: ret = 31 break case 11: ret = 30 break case 12: ret = 31 break default: print("bad num") } if(month == 2) { ret = 28 let t4 = year % 4 let l100 = year % 100 let l400 = year % 400 if(t4 == 0 && l100 != 0) { ret = 29 } if(l400 == 0) { ret = 29 } } return ret }
quelle