Adding a day to current date in iOS - ios

I saw this post: iOS and finding Tomorrow.
The code provided is:
units = NSYearCalendarUnit | NSMonthCalendarUnit | NSDayCalendarUnit;
NSDateComponents* comps = [[NSCalendar currentCalendar] components:units fromDate:[NSDate date]];
// Add one day
comps.day = comps.day+1; // no worries: even if it is the end of the month it will wrap to the next month, see doc
// Recompose a new date, without any time information (so this will be at midnight)
NSDate* tomorrowMidnight = [[NSCalendar currentCalendar] dateFromComponents:comps];
Problem: I need to add a day to my current date so that for example, the difference between 21st Jun 2013 and 21st May 2013 is 1 month instead of 0 month.
The code I am using:
NSDate *selectedDate = [picker2 date];
unsigned int unitFlags = NSHourCalendarUnit | NSMinuteCalendarUnit | NSDayCalendarUnit | NSMonthCalendarUnit;
NSDateComponents *conversionInfo = [currCalendar components:unitFlags fromDate:selectedDate toDate:[NSDate date] options:0];
DLog(#"%i",conversionInfo.month);
DLog(#"%i",conversionInfo.day);
conversionInfo.day +=1;
DLog(#"%i",conversionInfo.day);
DLog(#"%i",conversionInfo.month);
int months = [conversionInfo month];
But when I tried to get the difference between 21st Jun 2013 and 21st May 2013 -> still returns me 0 month instead of 1 month.
Need some help on this.

Form a date component with number of days you want to add to your original date. From the current calendar form the date by adding the this component to your original date.
NSDateComponents *dateComponents = [NSDateComponents new];
dateComponents.day = 1;
NSDate *newDate = [[NSCalendar currentCalendar]dateByAddingComponents:dateComponents
toDate: selectedDate
options:0];

Here is a method I use:
+ (NSDate *)addDays:(NSInteger)days toDate:(NSDate *)originalDate {
NSDateComponents *components= [[NSDateComponents alloc] init];
[components setDay:days];
NSCalendar *calendar = [NSCalendar currentCalendar];
return [calendar dateByAddingComponents:components toDate:originalDate options:0];
}
With it, you can add as many days as you want. It also works with negative numbers, so you can subtract days.

Simple and straight forward solution :
NSDate *currentDate = [NSDate date];
NSDate *nextDate = [currentDate dateByAddingTimeInterval:(24*3600)];
This is working fine for me.

For swift googlers:
NSCalendar.currentCalendar().dateByAddingUnit(NSCalendarUnit.CalendarUnitDay, value: 1, toDate: date, options: nil)!

First Thing,you are assigning day instead of month to NSDateComponent.
Execute following code and find difference between inDate And newDate
NSCalendar *calendar = [NSCalendar currentCalendar];
NSDateComponents *components = [calendar components:NSCalendarUnitMonth fromDate:inDate];
NSInteger monthFlag = 1;
components.month = minuteFlag;
// Retrieve date with increased days count
NSDate *newDate = [[NSCalendar currentCalendar]
dateByAddingComponents:components
toDate:monthFlag
options:0];

To add any number of any components to the date, for example: 2 days or 2 months, 1 year, do the following:
Calendar.current.date(byAdding: DateComponents(month: -1), to: date)! //this create date with previous month for date.
you can initialize DateComponents with anything:
public init(calendar: Calendar? = default, timeZone: TimeZone? = default, era: Int? = default, year: Int? = default, month: Int? = default, day: Int? = default, hour: Int? = default, minute: Int? = default, second: Int? = default, nanosecond: Int? = default, weekday: Int? = default, weekdayOrdinal: Int? = default, quarter: Int? = default, weekOfMonth: Int? = default, weekOfYear: Int? = default, yearForWeekOfYear: Int? = default)

Related

Wrong Year and weekOfYear in Gregorian Calendar objective-c

+ (NSCalendar*)getGregorianCalendarInstance {
NSCalendar *calendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSCalendarIdentifierGregorian];
return calendar;
}
+ (NSInteger)currentGregorianWeekOfYear:(NSDate*) date {
NSCalendar *gregorianCalendar = [self getGregorianCalendarInstance];
gregorianCalendar.firstWeekday = 2; // Monday = 2
NSDateComponents *components = [gregorianCalendar components:NSCalendarUnitWeekOfYear fromDate:date];
NSUInteger weekOfYear = [components weekOfYear];
return weekOfYear;
}
+ (NSInteger)currentGregorianYear:(NSDate*) date {
NSCalendar *gregorianCalendar = [self getGregorianCalendarInstance];
gregorianCalendar.firstWeekday = 2;
[gregorianCalendar setTimeZone:[NSTimeZone defaultTimeZone]];
gregorianCalendar.locale = [NSLocale localeWithLocaleIdentifier:#"en_US_POSIX"];
NSDateComponents *comps = [gregorianCalendar components: NSCalendarUnitYear fromDate:date];
NSInteger year = [comps year];
return year;
}
week number returns 52 instead of 1 in currentGregorianWeekOfYear function and year returns 2019 instead of 2020 in currentGregorianYear function for date = 2019-12-30 15:00:00 +0000
Specific reason to use the Gregorian calendar is to display 1st January in the 1st week of the year. With the ISO calendar, 1st January will be indicated as the 52nd or 53rd week of the year.
I already checked multiple references but it does not solve my problem:
WeekOfYear overflowing to 1 in 53rd week in gregorian calendar?
NSDateComponents weekOfYear returns wrong value
Swift: Gregorian Calendar and weeks/weekdays - inconsistent behavior

NSDateComponents: How to replace deprecated NSWeekCalendarUnit to calc week start date?

I am currently updating an old iOS App that uses NSDateComponents to calculate the start date of the week a given NSDate is in:
NSDate* someDate = [MyDateFactory dateFromDay:31 month:8 year:2017];
NSCalendar *calendar = [NSCalendar currentCalendar];
NSDateComponents *comps = [calendar components:(NSYearCalendarUnit | NSWeekCalendarUnit) fromDate:someDate];
// For 2017-08-31 comps is now year=2017, week (obsolete)=35
comps.calendar = calendar;
NSDate* weekStartDate = [comps date];
// weekStartDate = 2017-08-27
This works fine, but NSYearCalendarUnit and NSWeekCalendarUnit are both deprecated. Replacing NSYearCalendarUnit with the new NSCalendarUnitYear is no problem. But what it the correct replacemtn for NSWeekCalendarUnit.
It seems that NSWeekCalendarUnit returns the same value (week of year) as the new NSCalendarUnitWeekOfYear. But this does not result in the same weekStartDate:
// ... same as above. Now use new enum values
NSDateComponents *comps = [calendar components:(NSCalendarUnitYear | NSCalendarUnitWeekOfYear) fromDate:someDate];
// For 2017-08-31 comps is now year=2017, week of year=35 <== Same es above
comps.calendar = calendar;
NSDate* weekStartDate = [comps date];
// weekStartDate = 2017-01-01
So using NSCalendarUnitWeekOfYear returns the same week value (week 35), but it seems that this value is not considered when calculating the date from the the NSDateComponents object. 2017-01-01 is obviously not the date week 35 starts at in 2017.
So, how to solve this?
You can use other methods of NSCalendar instead.
To get the day on which weeks start, use calendar.firstWeekday.
Then put this into some date components:
NSDateComponents *search = [[NSDateComponents alloc] init];
search.weekDay = calendar.firstWeekday;
Now you can use the calendar to find the previous date which matches the components:
NSDate *weekStart = [calendar nextDateAfterDate: someDate matchingComponents: search options: NSCalendarSearchBackwards];

exact year difference between two nsdates

I am taking two NSDates from datepicker
I want to calculate the exact year difference between the dates..if I change the second date's day one greater, it should give me the year difference 2..and if take the day lesser it should give me 0 year difference..how can I achieve that? please help me..
this is my code to calculate difference
NSCalendar *gregorian1 = [NSCalendar currentCalendar];
NSUInteger unitFlags = NSYearCalendarUnit;
NSDateComponents *components1 = [gregorian1 components:unitFlags
fromDate:startDate
toDate:endDate options:0];
NSInteger diff = [components1 year];
Try this:
NSCalendar *calendar = [[[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar] autorelease];
NSDateComponents *components = [calendar components:NSYearCalendarUnit|NSMonthCalendarUnit|NSDayCalendarUnit
fromDate:dateA
toDate:dateB
options:0];
NSLog(#"Difference in date components: %i/%i/%i", components.day, components.month, components.year);
As the result you have difference in date components.
Swift 3
extension Date{
func yearsTo(_ date : Date) -> Int{
return Calendar.current.dateComponents([.year], from: self, to: date).year ?? 0
}
}

NSCalendar, why does setting the firstWeekday doesn't effect calculation outcome?

i need to calculate the weekday for a given date, however, depending on the calendar a week can star on Monday and somwhere on Sunday
so i wanted to set it, to start on Monday, using
[[NSCalendar currentCalendar] setFirstWeekday:2];
however, the calculation outcome is the same
{
[[NSCalendar currentCalendar] setFirstWeekday:1];
NSDateComponents *weekdayComponents = [[NSCalendar currentCalendar] components:(NSDayCalendarUnit | NSWeekdayCalendarUnit) fromDate:date];
NSInteger weekday = [weekdayComponents weekday] - 1;
NSLog(#"%d", weekday);
}
{
[[NSCalendar currentCalendar] setFirstWeekday:2];
NSDateComponents *weekdayComponents = [[NSCalendar currentCalendar] components:(NSDayCalendarUnit | NSWeekdayCalendarUnit) fromDate:date];
NSInteger weekday = [weekdayComponents weekday] - 1;
NSLog(#"%d", weekday);
}
returns same numbers, but why?
The behavior you see is correct. The weekday component is not affected by the firstWeekday property. If you have a date representing a sunday it will always be a sunday wether you start your week on that sunday or on monday. What this should affect is the week number in the week property of your date components.
I believe you need to use the ordinalityOfUnit:inUnit:forDate: method rather than attempting to extract the date components. So something like this:
NSUInteger weekday = [[NSCalendar currentCalendar] ordinalityOfUnit:NSWeekdayCalendarUnit inUnit:NSWeekCalendarUnit forDate:date];
Basically that call is asking for the day (NSWeekdayCalendarUnit) in the week (NSWeekCalendarUnit) for the given date.
If that doesn't work as is, you may need to create your own calendar, rather than trying to modifying the first week day on the currentCalendar.
For example:
NSCalendarIdentifier calendarIdentifier = [[NSCalendar currentCalendar] calendarIdentifier];
NSCalendar *calendar = [[[NSCalendar alloc] initWithCalendarIdentifier:calendarIdentifier] autorelease];
[calendar setFirstWeekday:2];
Then use that new calendar object rather than [NSCalendar currentCalendar] in the ordinalityOfUnit:inUnit:forDate: call.
A useful function to get corrected weekday number for different firstWeekday cases
Swift 3.0
func dayOfWeek(day: Int, month: Int, year: Int) -> Int {
let calendar = Calendar.current
let dateComponents = DateComponents(year: year, month: month, day: day)
guard let date = calendar.date(from: dateComponents) else {
fatalError("Can't create date form specified date components")
}
var weekday = calendar.component(.weekday, from: date)
//handling the case when calendar starts from Monday: firstWeekday == 2
if calendar.firstWeekday == 2 {
weekday = (weekday == 1) ? 7 : (weekday - 1)
}
return weekday
}

NSDateFormatter format the week of the date

I've been looking for a way to format the following NSDate object:
19 Feb 2013
Like that
18-25 Feb 2013
The 19 occurs within the week between the 18th and the 25th of Feb.
I couldn't an easy method to do so, is there build in functionality in to the NSDateFormater? should I implement it myself?
I don't think there is built in functionality in NSDateFormatter to do this. However, Apple has an example of how to get the NSDate values for the first and last days of a the week given a date. Here's their example on getting the Sunday of the current week:
NSDate *today = [[NSDate alloc] init];
NSCalendar *gregorian = [[NSCalendar alloc]
initWithCalendarIdentifier:NSGregorianCalendar];
// Get the weekday component of the current date
NSDateComponents *weekdayComponents = [gregorian components:NSWeekdayCalendarUnit
fromDate:today];
/*
Create a date components to represent the number of days to subtract from the current date.
The weekday value for Sunday in the Gregorian calendar is 1, so subtract 1 from the number of days to subtract from the date in question. (If today is Sunday, subtract 0 days.)
*/
NSDateComponents *componentsToSubtract = [[NSDateComponents alloc] init];
[componentsToSubtract setDay: 0 - ([weekdayComponents weekday] - 1)];
NSDate *beginningOfWeek = [gregorian dateByAddingComponents:componentsToSubtract
toDate:today options:0];
/*
Optional step:
beginningOfWeek now has the same hour, minute, and second as the original date (today).
To normalize to midnight, extract the year, month, and day components and create a new date from those components.
*/
NSDateComponents *components =
[gregorian components:(NSYearCalendarUnit | NSMonthCalendarUnit |
NSDayCalendarUnit) fromDate: beginningOfWeek];
beginningOfWeek = [gregorian dateFromComponents:components];
Since Sunday is not the beginning of the week in all locales, they also show how to get the beginning of the week as defined by the calendar's locale:
NSDate *today = [[NSDate alloc] init];
NSDate *beginningOfWeek = nil;
BOOL ok = [gregorian rangeOfUnit:NSWeekCalendarUnit startDate:&beginningOfWeek
interval:NULL forDate: today];

Resources