Number of weekend days in a month - ios

How I can get number of weekends in month or between two NSDate ?
I was try do some tricks with
calendar.components( NSCalendarUnit.WeekCalendarUnit, fromDate: startDate, toDate: endDate, options: nil)
But no result

NSInteger count = 0;
NSInteger saturday = 7;
// Set the incremental interval for each interaction.
NSDateComponents *oneDay = [[NSDateComponents alloc] init];
[oneDay setDay:1];
// Using a Gregorian calendar.
NSCalendar *calendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
NSDate *currentDate = fromDate;
// Iterate from fromDate until toDate
while ([currentDate compare:toDate] == NSOrderedAscending) {
NSDateComponents *dateComponents = [calendar components:NSWeekdayCalendarUnit fromDate:currentDate];
if (dateComponents.weekday == saturday) {
count++;
}
// "Increment" currentDate by one day.
currentDate = [calendar dateByAddingComponents:oneDay
toDate:currentDate
options:0];
}
NSLog(#"count = %d", count);

According TENSRI I write code in swift with some fixs
func numberOfWeekdaysBeetweenDates(#startDate:NSDate,endDate:NSDate)->Int{
var count = 0
var oneDay = NSDateComponents()
oneDay.day = 1;
// Using a Gregorian calendar.
var calendar = NSCalendar.currentCalendar()
var currentDate = startDate;
// Iterate from fromDate until toDate
while (currentDate.compare(endDate) != .OrderedDescending) {
var dateComponents = calendar.components(.WeekdayCalendarUnit, fromDate: currentDate)
if (dateComponents.weekday == 1 || dateComponents.weekday == 7 ) {
count++;
}
// "Increment" currentDate by one day.
currentDate = calendar.dateByAddingComponents(oneDay, toDate: currentDate, options: nil)!
}
return count
}

Related

How to check if NSDate is in current week?

How to check if NSDate falls in current week of the year? I tried below but last week's date is also falling inside "Date is in this week" condition.
- (NSInteger)thisW:(NSDate *)date
{
NSCalendar *gregorian = [[NSCalendar alloc]
initWithCalendarIdentifier:NSGregorianCalendar];
NSDateComponents *todaysComponents =
[gregorian components:NSWeekCalendarUnit fromDate:[NSDate date]];
NSUInteger todaysWeek = [todaysComponents weekday];
NSDateComponents *otherComponents =
[gregorian components:NSWeekCalendarUnit fromDate:date];
NSUInteger datesWeek = [otherComponents weekday];
NSLog(#"Date %#",date);
if(todaysWeek==datesWeek){
//NSLog(#"Date is in this week");
return 1;
}else if(todaysWeek+1==datesWeek){
//NSLog(#"Date is in next week");
return 2;
} else {
return 0;
}
}
What about this short extension in Swift 4?
extension Calendar {
func isDayInCurrentWeek(date: Date) -> Bool? {
let currentComponents = Calendar.current.dateComponents([.weekOfYear], from: Date())
let dateComponents = Calendar.current.dateComponents([.weekOfYear], from: date)
guard let currentWeekOfYear = currentComponents.weekOfYear, let dateWeekOfYear = dateComponents.weekOfYear else { return nil }
return currentWeekOfYear == dateWeekOfYear
}
}
A solution using the method rangeOfUnit:startDate:interval:forDate of NSCalendar to calculate the start date and the interval of the current week
- (BOOL)isInCurrentWeek:(NSDate *)date
{
NSDate *startDate = nil;
NSTimeInterval interval = 0.0;
NSCalendar *calendar = [NSCalendar currentCalendar];
// calendar.firstWeekday = 1; set the index of the first weekday if necessary
[calendar rangeOfUnit:NSWeekOfYearCalendarUnit startDate: &startDate interval: &interval forDate: [NSDate date]];
NSDate *endDate = [calendar dateByAddingUnit:NSSecondCalendarUnit value: (NSInteger)interval toDate: startDate options:NSCalendarMatchNextTime];
return [date compare:startDate] == NSOrderedDescending && [date compare:endDate] == NSOrderedAscending;
}
or in Swift
func isDateInCurrentWeek(_ date : Date) -> Bool
{
var startDate = Date()
var interval : TimeInterval = 0.0
let calendar = Calendar.current
// calendar.firstWeekday = 1 set the index of the first weekday if necessary
calendar.dateInterval(of: .weekOfYear, start: &startDate, interval: &interval, for: Date())
let endDate = calendar.date(byAdding:.second, value: Int(interval), to: startDate)!
return date >= startDate && date < endDate
}
I had to replace NSWeekCalendarUnit with NSCalendarUnitWeekOfYear
- (NSInteger)thisW:(NSDate *)date
{
NSCalendar *gregorian = [[NSCalendar alloc]
initWithCalendarIdentifier:NSGregorianCalendar];
NSDateComponents *todaysComponents = [gregorian components:NSCalendarUnitWeekOfYear fromDate:[NSDate date]];
NSUInteger todaysWeek = [todaysComponents weekOfYear];
NSDateComponents *otherComponents = [gregorian components:NSCalendarUnitWeekOfYear fromDate:date];
NSUInteger datesWeek = [otherComponents weekOfYear];
//NSLog(#"Date %#",date);
if(todaysWeek==datesWeek){
//NSLog(#"Date is in this week");
return 1;
}else if(todaysWeek+1==datesWeek){
//NSLog(#"Date is in next week");
return 2;
} else {
return 0;
}
}
Swift 5.3.x, modified Vadian's answer. Other answers didn't work for me. For instance, test the method with the date from last year (2020), they return true.
Here's a Swift extension of NSDate because I have to use this function in an Objective-C class.
import Foundation
extension NSDate {
#objc func isInCurrentWeek() -> Bool {
var startDate = Date()
var interval : TimeInterval = 0.0
let calendar = Calendar.current
// calendar.firstWeekday = 1 set the index of the first weekday if necessary
calendar.dateInterval(of: .weekOfYear, start: &startDate, interval: &interval, for: Date())
let endDate = calendar.date(byAdding:.second, value: Int(interval), to: startDate)!
return (self as Date) >= startDate && (self as Date) < endDate
}
}
And sample test/use case:
let df = DateFormatter()
df.dateFormat = "yyyy-MM-dd'T'HH:mm:ssZ"
let d = "2021-01-23T13:56:49+0000"
let d2 = df.date(from: d)
print((d2! as NSDate).isInCurrentWeek()) // prints true, current date is Jan 21, 2021
Use this function to get number of week:
- (NSInteger)numberOfWeek:(NSDate *)date
{
NSCalendar *calender = [NSCalendar currentCalendar];
NSDateComponents *components = [calender components:NSCalendarUnitWeekOfYear fromDate:date];
return [components weekOfYear];
}
Using this code, you can compare week like this. I am just use next week date using dateWithTimeIntervalSinceNow: only for comparison.
if ([self numberOfWeek:[NSDate date]] == [self numberOfWeek:[NSDate dateWithTimeIntervalSinceNow: (60.0f*60.0f*24.0f*7.0f)]])
{
NSLog(#"Same Week");
}
else
{
NSLog(#"Different Week");
}
First get the firstday and lastday of the week of current date.
NSCalendar *myCalendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
NSDateComponents *currentComps = [myCalendar components:( NSYearCalendarUnit | NSMonthCalendarUnit | NSWeekOfYearCalendarUnit | NSWeekdayCalendarUnit | NSHourCalendarUnit | NSMinuteCalendarUnit) fromDate:[NSDate date]];
[currentComps setWeekday:1]; // 1: sunday
NSDate *firstDayOfTheWeek = [myCalendar dateFromComponents:currentComps];
[currentComps setWeekday:7]; // 7: saturday
NSDate *lastDayOfTheWeek = [myCalendar dateFromComponents:currentComps];
Now use a method given bellow putting your interested date
BOOL isInCurrentWeek = [self date:your given date isBetweenDate:firstDayOfTheWeek andDate:lastDayOfTheWeek];
NSLog(#"%d",isInCurrentWeek);
The expecting method
- (BOOL)date:(NSDate*)date isBetweenDate:(NSDate*)beginDate andDate:(NSDate*)endDate
{
if ([date compare:beginDate] == NSOrderedAscending)
return NO;
if ([date compare:endDate] == NSOrderedDescending)
return NO;
return YES;
}

Get last tuesday in month ios

Can get last weekday in the month through NSDateComponents? For example: last monday in month or last friday in month. etc
Just another way to solve. Find the first day of the next month, then search backwards for Tuesday.
let calendar = NSCalendar.currentCalendar()
let today = NSDate()
let components = calendar.components([.Year, .Month], fromDate: today)
components.month += 1
// If today is 2016-07-12 then nextMonth will be the
// first day of the next month: 2016-08-01
if let nextMonth = calendar.dateFromComponents(components) {
// Search backwards for weekday = Tuesday
let options: NSCalendarOptions = [.MatchPreviousTimePreservingSmallerUnits, .SearchBackwards]
calendar.nextDateAfterDate(nextMonth, matchingUnit: .Weekday, value: 3, options: options)
}
Here's a solution; tested, and fairly robust, I think.
We'll let NSCalendar walk through the month, a day at a time, and pull out all matching weekdays as NSDates. Then you can answer questions like, "The 3rd Wednesday of this month"
I believe the comments are clear about what is happening, and why.
If you need further clarification, I'll be happy to do so.
//What weekday are we interested in? 1 = Sunday . . . 7 = Saturday
NSInteger targetWeekday = 1;
//Using this methodology, GMT timezone is important to set
NSCalendar *calendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSCalendarIdentifierGregorian];
calendar.timeZone = [NSTimeZone timeZoneWithAbbreviation:#"GMT"];
//set the components to the first of the current month
NSDateComponents *startComponents = [calendar components:NSCalendarUnitMonth | NSCalendarUnitYear fromDate:[NSDate date]];
startComponents.day = 1;
//the enumeration starts "afterDate", so shift the start back one day (86400 seconds) to include the 1st of the month
NSDate *startDate = [[calendar dateFromComponents:startComponents] dateByAddingTimeInterval:-86400];
//the enumeration searches for a match; we'll match at the midnight hour and find every occurance of midnight
NSDateComponents *dayByDay = [[NSDateComponents alloc] init];
dayByDay.hour = 0;
//I've opted to put all matching weekdays of the month into an array, so you can find any instance easily
__block NSMutableArray *foundDates = [NSMutableArray arrayWithCapacity:5];
[calendar enumerateDatesStartingAfterDate:startDate
matchingComponents:dayByDay
options:NSCalendarMatchPreviousTimePreservingSmallerUnits
usingBlock:^(NSDate *date, BOOL exactMatch, BOOL *stop){
NSDateComponents *thisComponents = [calendar components:NSCalendarUnitMonth | NSCalendarUnitWeekday fromDate:date];
//as long as the month stays the same... (or the year, if you wanted to)
if (thisComponents.month == startComponents.month) {
//does this date match our target weekday search?
if (thisComponents.weekday == targetWeekday) {
//then add it to our result array
[foundDates addObject:date];
}
//once the month has changed, we're done
} else {
*stop = YES;
}
}];
//Now, with our search result array, we can find the 1st, last, or any specific occurance of that weekday on that month
NSLog(#"Found these: %#", foundDates);
So, if you only wanted the last one, then just use [foundDates lastObject]
Try this code. This works for me.
NSCalendar *gregorian = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
NSDateComponents *comps = [gregorian components:NSWeekdayCalendarUnit fromDate:[NSDate date]];
int weekday = [comps weekday];
int lastTues;
int lastSatDay;
if (weekday==1) {
lastTues=5;
lastSatDay=1;
}
else if (weekday==2)
{
lastTues=6;
lastSatDay=2;
}
else if (weekday==3)
{
lastTues=7;
lastSatDay=3;
}
else if (weekday==4)
{
lastTues=1;
lastSatDay=4;
}
else if (weekday==5)
{
lastTues=2;
lastSatDay=5;
}
else if (weekday==6)
{
lastTues=3;
lastSatDay=6;
}
else if (weekday==7)
{
lastTues=4;
lastSatDay=7;
}
NSDate *lastTuesDay = [[NSDate date] addTimeInterval:-3600*24*(lastTues)];
NSDate *lastSaturday = [[NSDate date] addTimeInterval:-3600*24*(lastSatDay)];

Getting the first date of current quarter

I'm trying to get the first and the last date of current quarter, i'm using it:
NSDateComponents *components = [[NSCalendar currentCalendar] components:NSCalendarUnitQuarter | NSCalendarUnitDay | NSCalendarUnitMonth | NSCalendarUnitYear fromDate:[NSDate date]];
components.quarter = 1;
funStartDate = [[NSCalendar currentCalendar] dateFromComponents: components];
NSLog(#"First day of quater: %#", funStartDate);
[components setQuarter:[components quarter]+1];
funEndDate = [[NSCalendar currentCalendar] dateFromComponents: components];
NSLog(#"Last day of quater: %#", [funEndDate descriptionWithLocale:[NSLocale currentLocale]]);
But in both console print I see today's date. What I'm doing wrong?
UPDATED: I've found that Apple's bug with quarter unit is still there in iOS 7.1, so avoid using this unit in your date components.
Here I got working solution for you:
first day of a quarter:
NSDate *date = <whatever>;
NSCalendar *currentCalendar = [NSCalendar currentCalendar];
NSDate *startOfQuarter;
[currentCalendar rangeOfUnit: NSQuarterCalendarUnit
startDate: &startOfQuarter
interval: NULL
forDate: date];
NSLog(#"quarter starts at %#", startOfQuarter);
last day of a quarter:
NSDateComponents* comps = [currentCalendar components:(NSCalendarUnitYear | NSCalendarUnitMonth | NSCalendarUnitDay)
fromDate:date];
NSUInteger quartalNum = (comps.month - 1) / 3 + 1;
NSUInteger lastQuartalMonthNum = quartalNum * 3;
NSUInteger nextQuartalFirstMonth = lastQuartalMonthNum + 1
[comps setMonth: nextQuartalFirstMonth];
[comps setDay: 0]; // with 0 day we get last day of previous month
NSLog(#"quarter ends at %#", [currentCalendar dateFromComponents: comps]);
Swift 3.1. Quarter component still not working. Workaround:
extension Date {
public var startOfQuarter: Date {
let startOfMonth = Calendar.current.date(from: Calendar.current.dateComponents([.year, .month], from: Calendar.current.startOfDay(for: self)))!
var components = Calendar.current.dateComponents([.month, .day, .year], from: startOfMonth)
let newMonth: Int
switch components.month! {
case 1,2,3: newMonth = 1
case 4,5,6: newMonth = 4
case 7,8,9: newMonth = 7
case 10,11,12: newMonth = 10
default: newMonth = 1
}
components.month = newMonth
return Calendar.current.date(from: components)!
}
}
Usage:
Date().startOfQuarter

Number of days between two NSDate objects

I'm trying to compare two days of NSDate objects, I used at the first time NSDateComponents to calculate difference between my two dates Objects, but it is working correctly.
NSString *dateStr =#"2012-11-05 15:00:00";
NSDate *date = [dateFormat dateFromString:dateStr];
NSDateComponents *datesDiff = [calendar components: NSDayCalendarUnit
fromDate: date
toDate: [NSDate date]
options: 0];
That does not resolve my problem. Indeed when date1 = 2012-11-05 23:00:00 and date2 = 2012-11-06 10:00:00, the difference between the tow dates is 0 day and 11 hours.
I am looking for something that allows me to detect day changes, in other words when date1 = 2012-11-05 23:00:00 and date2 = 2012-11-06 00:01:00, there's one day diffrence.
If someone knows the solution for that, i would welcome his suggestion.
Thanks in advance
I think you are looking for this (from the Date and Time Programming Guide):
Listing 13 Days between two dates, as the number of midnights between
#implementation NSCalendar (MySpecialCalculations)
-(NSInteger)daysWithinEraFromDate:(NSDate *) startDate toDate:(NSDate *) endDate
{
NSInteger startDay=[self ordinalityOfUnit:NSDayCalendarUnit
inUnit: NSEraCalendarUnit forDate:startDate];
NSInteger endDay=[self ordinalityOfUnit:NSDayCalendarUnit
inUnit: NSEraCalendarUnit forDate:endDate];
return endDay-startDay;
}
#end
EDIT: Swift version:
extension NSCalendar {
func daysWithinEraFromDate(startDate: NSDate, endDate: NSDate) -> Int {
let startDay = self.ordinalityOfUnit(.Day, inUnit: NSCalendarUnit.Era, forDate: startDate)
let endDay = self.ordinalityOfUnit(.Day, inUnit: NSCalendarUnit.Era, forDate: endDate)
return endDay - startDay
}
}
NSString *start = #"2010-09-01";
NSString *end = #"2010-12-01";
NSDateFormatter *f = [[NSDateFormatter alloc] init];
[f setDateFormat:#"yyyy-MM-dd"];
NSDate *startDate = [f dateFromString:start];
NSDate *endDate = [f dateFromString:end];
[f release];
NSCalendar *gregorianCalendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
NSDateComponents *components = [gregorianCalendar components:NSDayCalendarUnit
fromDate:startDate
toDate:endDate
options:0];
[gregorianCalendar release];
components now holds the difference.
NSLog(#"%ld", [components day]);
func daysBetweenDates(startDate: NSDate, endDate: NSDate) -> Int
{
let calendar = NSCalendar.currentCalendar()
let components = calendar.components([.Day], fromDate: startDate, toDate: endDate, options: [])
return components.day
}
or
let calendar = NSCalendar.currentCalendar();
let component1 = calendar.component(.Day, fromDate: fromDate)
let component2 = calendar.component(.Day, fromDate: toDate)
let difference = component1 - component2
For Swift 3:
Expanding from #masa's answer:
extension Calendar {
func daysWithinEraFromDate(startDate: Date, endDate: Date) -> Int? {
guard let startDay = ordinality(of: .day, in: .era, for: startDate) else {
return nil
}
guard let endDay = ordinality(of: .day, in: .era, for: endDate) else {
return nil
}
return endDay - startDay
}
}

Get firstdate, lastdate of month?

I want to get firstdate、lastdate of month,I try
NSDateComponents *components = [calendar components:units fromDate:[NSDate date]];
[components setDay:1];
self.currentDate = [calendar dateFromComponents:components];
int m = components.month;
int y = components.year;
int d = components.day;
log: 2012,5,1
How can i get lastdate od month?
please give me some advice,thank you!!
Some NSDate category methods I wrote will help you:
Here's an easy way to find the start of a month:
(NSDate *) startOfMonth
{
NSCalendar * calendar = [NSCalendar currentCalendar];
NSDateComponents * currentDateComponents = [calendar components: NSYearCalendarUnit | NSMonthCalendarUnit fromDate: self];
NSDate * startOfMonth = [calendar dateFromComponents: currentDateComponents];
return startOfMonth;
}
All it does is take the year and month components from the current day, then convert back to a date again.
For the end of the month, I use a couple of methods:
- (NSDate *) dateByAddingMonths: (NSInteger) monthsToAdd
{
NSCalendar * calendar = [NSCalendar currentCalendar];
NSDateComponents * months = [[NSDateComponents alloc] init];
[months setMonth: monthsToAdd];
return [calendar dateByAddingComponents: months toDate: self options: 0];
}
and
- (NSDate *) endOfMonth
{
NSCalendar * calendar = [NSCalendar currentCalendar];
NSDate * plusOneMonthDate = [self dateByAddingMonths: 1];
NSDateComponents * plusOneMonthDateComponents = [calendar components: NSYearCalendarUnit | NSMonthCalendarUnit fromDate: plusOneMonthDate];
NSDate * endOfMonth = [[calendar dateFromComponents: plusOneMonthDateComponents] dateByAddingTimeInterval: -1]; // One second before the start of next month
return endOfMonth;
}
This is a 3 step process - add one month to the current date, find the start of the next month, then subtract 1 second to find the end of this month.
Swift 3
extension Date {
func startOfMonth() -> Date? {
let calendar = Calendar.current
let currentDateComponents = calendar.dateComponents([.year, .month], from: self)
let startOfMonth = calendar.date(from: currentDateComponents)
return startOfMonth
}
func dateByAddingMonths(_ monthsToAdd: Int) -> Date? {
let calendar = Calendar.current
var months = DateComponents()
months.month = monthsToAdd
return calendar.date(byAdding: months, to: self)
}
func endOfMonth() -> Date? {
guard let plusOneMonthDate = dateByAddingMonths(1) else { return nil }
let calendar = Calendar.current
let plusOneMonthDateComponents = calendar.dateComponents([.year, .month], from: plusOneMonthDate)
let endOfMonth = calendar.date(from: plusOneMonthDateComponents)?.addingTimeInterval(-1)
return endOfMonth
}
}
Swift 2
extension NSDate {
func startOfMonth() -> NSDate? {
let calendar = NSCalendar.currentCalendar()
let currentDateComponents = calendar.components(.CalendarUnitYear | .CalendarUnitMonth, fromDate: self)
let startOfMonth = calendar.dateFromComponents(currentDateComponents)
return startOfMonth
}
func dateByAddingMonths(monthsToAdd: Int) -> NSDate? {
let calendar = NSCalendar.currentCalendar()
let months = NSDateComponents()
months.month = monthsToAdd
return calendar.dateByAddingComponents(months, toDate: self, options: nil)
}
func endOfMonth() -> NSDate? {
let calendar = NSCalendar.currentCalendar()
if let plusOneMonthDate = dateByAddingMonths(1) {
let plusOneMonthDateComponents = calendar.components(.CalendarUnitYear | .CalendarUnitMonth, fromDate: plusOneMonthDate)
let endOfMonth = calendar.dateFromComponents(plusOneMonthDateComponents)?.dateByAddingTimeInterval(-1)
return endOfMonth
}
return nil
}
}
Try this trick.
Day Param: 1 is to Get first date of this month
Day Param: 0 is to Get last date of this month by getting last date of month previous to next month (means this month))
- (void)returnDate:(NSDate *)date {
NSCalendar * calendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
unsigned unitFlags = NSYearCalendarUnit | NSMonthCalendarUnit;
NSDateComponents *comps = [calendar components:unitFlags fromDate:date];
NSDate * firstDateOfMonth = [self returnDateForMonth:comps.month year:comps.year day:1];
NSDate * lastDateOfMonth = [self returnDateForMonth:comps.month+1 year:comps.year day:0];
NSLog(#"date %#", date); // date 2013-06-20
NSLog(#"First %#", firstDateOfMonth); // firstDateOfMonth 2013-06-01
NSLog(#"Last %#", lastDateOfMonth); // lastDateOfMonth 2013-06-30
}
Next
- (NSDate *)returnDateForMonth:(NSInteger)month year:(NSInteger)year day:(NSInteger)day {
NSDateComponents *components = [[NSDateComponents alloc] init];
[components setDay:day];
[components setMonth:month];
[components setYear:year];
NSCalendar *gregorian = [[NSCalendar alloc]
initWithCalendarIdentifier:NSGregorianCalendar];
return [gregorian dateFromComponents:components];
}
Don't forget for right Date Formater
Updated for IOS 8.0
- (void)returnDate:(NSDate *)date {
NSCalendar * calendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSCalendarIdentifierGregorian];
unsigned unitFlags = NSCalendarUnitYear | NSCalendarUnitMonth;
NSDateComponents *comps = [calendar components:unitFlags fromDate:date];
NSDate * firstDateOfMonth = [self returnDateForMonth:comps.month year:comps.year day:1];
NSDate * lastDateOfMonth = [self returnDateForMonth:comps.month+1 year:comps.year day:0];
NSLog(#"date %#", date); // date 2013-06-20
NSLog(#"First %#", firstDateOfMonth); // firstDateOfMonth 2013-06-01
NSLog(#"Last %#", lastDateOfMonth); // lastDateOfMonth 2013-06-30
}
Next
- (NSDate *)returnDateForMonth:(NSInteger)month year:(NSInteger)year day:(NSInteger)day {
NSDateComponents *components = [[NSDateComponents alloc] init];
[components setDay:day];
[components setMonth:month];
[components setYear:year];
NSCalendar *gregorian = [[NSCalendar alloc]
initWithCalendarIdentifier:NSCalendarIdentifierGregorian];
return [gregorian dateFromComponents:components];
}
Now your are working with:
NSCalendarUnitYear
NSCalendarUnitWeekOfMonth
NSCalendarIdentifierGregorian
Ok, since I'm rolling my own calendar control, I went ahead and created a NSCalendar category. Here's my lastOfMonth method:
- (NSDate *)lastOfMonth:(NSDate *)date
{
NSDateComponents *dc = [self components:NSEraCalendarUnit | NSYearCalendarUnit | NSMonthCalendarUnit fromDate:date];
NSRange dim = [self rangeOfUnit:NSDayCalendarUnit inUnit:NSMonthCalendarUnit forDate:date];
dc.day = dim.length;
return [self dateFromComponents:dc];
}
For Swift 2.0 to get the first day of the current month:
let date = NSDate()
let calendar = NSCalendar.currentCalendar()
let dateComponents = calendar.components([NSCalendarUnit.Month, NSCalendarUnit.Year], fromDate: date)
let firstDay = self.returnDateForMonth(dateComponents.month, year: dateComponents.year, day: 1)
let dateFormatter = NSDateFormatter()
dateFormatter.dateFormat = "dd-MMM-yy"
print("First day of this month: \(firstDay)") // 01-Sep-15
And the function to do this:
func returnDateForMonth(month:NSInteger, year:NSInteger, day:NSInteger)->NSDate{
let comp = NSDateComponents()
comp.month = month
comp.year = year
comp.day = day
let grego = NSCalendar.currentCalendar()
return grego.dateFromComponents(comp)!
}
You can get last date of month using :-
NSDate currDate=[NSDate date];
-(NSString *)getLastDateMonth:(NSDate *)currDate{
NSCalendar *gregCalendar=[[[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar] autorelease];
NSDateComponents *components=[gregCalendar components:NSMonthCalendarUnit|NSYearCalendarUnit fromDate:currDate];
NSInteger month=[components month];
NSInteger year=[components year];
if (month==12) {
[components setYear:year+1];
[components setMonth:1];
} else {
[components setMonth:month+1];
}
[components setDay:1];
NSDateFormatter *dateFormat = [[NSDateFormatter alloc] init];
[dateFormat setDateStyle:NSDateFormatterShortStyle];
NSString *lastDateOfMonth = [dateFormat stringFromDate:(NSDate *)[[gregCalendar dateFromComponents:components] dateByAddingTimeInterval:-86400]];
dateFormat=nil;
return lastDateOfMonth;
}
In Swift based in Nazir's answer
func getFirstAndLastDateOfMonth(date: NSDate) -> (fistDateOfMonth: NSDate, lastDateOfMonth: NSDate) {
let calendar = NSCalendar(calendarIdentifier: NSCalendarIdentifierGregorian)
let calendarUnits = NSCalendarUnit.CalendarUnitYear | NSCalendarUnit.CalendarUnitMonth
let dateComponents = calendar?.components(calendarUnits, fromDate: date)
let fistDateOfMonth = self.returnedDateForMonth(dateComponents!.month, year: dateComponents!.year, day: 1)
let lastDateOfMonth = self.returnedDateForMonth(dateComponents!.month + 1, year: dateComponents!.year, day: 0)
println("fistDateOfMonth \(fistDateOfMonth)")
println("lastDateOfMonth \(lastDateOfMonth)")
return (fistDateOfMonth!,lastDateOfMonth!)
}
func returnedDateForMonth(month: NSInteger, year: NSInteger, day: NSInteger) -> NSDate? {
var components = NSDateComponents()
components.day = day
components.month = month
components.year = year
let gregorian = NSCalendar(calendarIdentifier: NSCalendarIdentifierGregorian)
return gregorian!.dateFromComponents(components)
}
Swift 5 getting last day of month - base on different sources
// -------------------------------------------------------
// lastDayOfMonth
// -------------------------------------------------------
static func lastDayOfMonth(year:Int, month:Int) -> Int {
let calendar:Calendar = Calendar.current
var dc:DateComponents = DateComponents()
dc.year = year
dc.month = month + 1
dc.day = 0
let lastDateOfMonth:Date = calendar.date(from:dc)!
let lastDay = calendar.component(Calendar.Component.day, from: lastDateOfMonth)
return lastDay
}
Looks like there is no need for any tricks or hacks, NSCalendar's rangeOfUnit does the job pretty nicely:
NSCalendar *cal = [NSCalendar currentCalendar];
NSDateComponents *dc = [[NSDateComponents alloc] init];
dc.year = 1947;
dc.month = 8; //desired month
//calculate start date
dc.day = 1; //As far as I can think start date of a month will always be 1
NSDate *start = [cal dateFromComponents:dc];
//calculate last date of month
NSRange dim = [cal rangeOfUnit:NSCalendarUnitDay inUnit:NSCalendarUnitMonth forDate:start]; // we used start date as it has the same month & year value as desired
dc.day=dim.length; //this is the simply the last day of the desired month
NSDate *last = [[NSCalendar currentCalendar] dateFromComponents:dc];
Log the values for verification:
NSLog(#"Start day of month Date: %#", start);
NSLog(#"Last day of month Date: %#", last);
Apple docs on NSCalendar rangeOfUnit: https://developer.apple.com/documentation/foundation/nscalendar/1418344-rangeofunit
p.s looks like this uses the same logic as #Scott Means's answer, but doesn't require any category, so use which ever answer you prefer!

Resources