I'm struggling to figure out how to dynamically create a date object for the most previous sunday at 12:00 AM
I was thinking I could get today's date and then subtract the current day of the week + 1 at which point I could just subtract the time of the day do get down to 12AM.
so far I have the current day of the week:
NSCalendar *gregorian = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
NSDateComponents *comps = [gregorian components:NSWeekdayCalendarUnit fromDate:[NSDate date]];
int weekday = [comps weekday];
at which point I can get today's date and subtract the difference of weekday * seconds in a day. However, how can I get today's time in seconds ??
No need to manually calculate seconds (which is dangerous anyway because of daylight saving etc.). The following should do exactly what you want:
NSDate *today = [NSDate date];
NSCalendar *calendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
[calendar setLocale:[[NSLocale alloc] initWithLocaleIdentifier:#"en-US"]]; // force US locale, because other countries (e.g. the rest of the world) might use different weekday numbering
NSDateComponents *nowComponents = [calendar components:NSYearCalendarUnit | NSWeekCalendarUnit | NSHourCalendarUnit | NSMinuteCalendarUnit | NSSecondCalendarUnit fromDate:today];
[nowComponents setWeekday:1]; //Sunday
[nowComponents setHour:0]; // 12:00 AM = midnight (12:00 PM would be 12)
[nowComponents setMinute:0];
[nowComponents setSecond:0];
NSDate *previousSunday = [calendar dateFromComponents:nowComponents];
I'll leave worrying about transitions between daylight savings time to you:
NSCalendar *gregorian = [[NSCalendar alloc]initWithCalendarIdentifier:NSGregorianCalendar];
NSDate *date = [NSDate date];
NSLog(#"date %#", date);
NSDateComponents *componentsToday = [gregorian components:NSWeekdayCalendarUnit fromDate:date]; // NSYearCalendarUnit | NSMonthCalendarUnit | NSDayCalendarUnit |
NSInteger days = componentsToday.weekday - 1;
NSLog(#"Days=%d", days);
NSDate *lastSunday = [date dateByAddingTimeInterval:-days*60*60*24];
NSLog(#"lastSunday %#", lastSunday);
NSDateComponents *componentsSunday = [gregorian components:NSYearCalendarUnit | NSMonthCalendarUnit | NSDayCalendarUnit fromDate:lastSunday];
[componentsSunday setHour:0];
[componentsSunday setMinute:0];
[componentsSunday setSecond:0];
NSDate *targetDate = [gregorian dateFromComponents:componentsSunday];
NSLog(#"TargetDate %#", targetDate);
#AndreasLey solution in Swift 2.0:
func getLastSunday() -> NSDate?
{
let today = NSDate();
let calendar : NSCalendar! = NSCalendar(calendarIdentifier: NSCalendarIdentifierGregorian)
calendar.locale = NSLocale(localeIdentifier: "en-US") // force US locale, because other countries (e.g. the rest of the world) might use different weekday numbering
let flags : NSCalendarUnit = [.Year , .Month, .Weekday, .WeekOfMonth, .Minute , .Second]
let nowComponents = calendar.components(flags, fromDate: today)
nowComponents.weekday = 1 //Sunday
nowComponents.hour = 0 // 12:00 AM = midnight (12:00 PM would be 12)
nowComponents.minute = 0
nowComponents.second = 0;
let previousSunday = calendar.dateFromComponents(nowComponents);
return previousSunday
}
This code is setting 12:00 am in your selected date from UIDatePicker.
NSDate *oldDateSelected = datePicker.date;
unsigned unitFlags = NSCalendarUnitYear | NSCalendarUnitMonth | NSCalendarUnitDay;
NSCalendar *calendar = [NSCalendar currentCalendar];
NSDateComponents *comps = [calendar components:unitFlags fromDate:oldDateSelected];
comps.hour = 00;
comps.minute = 00;
comps.second = 44;
NSDate *newDate = [calendar dateFromComponents:comps];
return newDate;
Related
I have searched for the solution to find the date of the sunday of the particular week.I have found questions that have been answered but it doesnt show the correct date of sunday.
NSCalendar *calendar = [NSCalendar currentCalendar];
unsigned unitFlags = NSCalendarUnitYear | NSCalendarUnitMonth | NSCalendarUnitDay | NSCalendarUnitHour | NSCalendarUnitMinute | NSCalendarUnitWeekday | NSCalendarUnitWeekOfYear;
NSDateComponents *comps = [calendar components:unitFlags fromDate:[NSDate date]];
comps.weekday = 1; //Sunday
comps.weekOfMonth = 1;
NSDate *sundayDate = [calendar dateFromComponents:comps];
When i print out the date it gives this.
2015-07-08 10:14:00 +0000
Its the current date.What am i doing wrong?
hope this helps you :
NSDate *today = [NSDate date];
NSCalendar *calenderObj = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
calenderObj.firstWeekday = 1; // Sunday = 1,
// NSDateComponents *components = [calenderObj components:NSWeekOfYearCalendarUnit fromDate:today];
NSDate *objDate = nil;
[calenderObj rangeOfUnit:NSWeekCalendarUnit startDate:&objDate interval:NULL forDate:today];
NSLog(#" === %#", objDate);
Output :
=== 2015-07-15 10:26:00 +0000
I am working on a Calender app and it's working fine when i navigate to next month as i am able to get the last day of the month and from where i am able to get the first day of coming month .but when i navigate to previous month i m not able to get the last month's first day.Is there any way to get first day of last month.
The following works fine for me
NSCalendar *calendar = [NSCalendar currentCalendar];
NSDate *currentDate = [NSDate date];
NSDateComponents *components = [calendar components:(NSCalendarUnitDay | NSCalendarUnitMonth | NSCalendarUnitDay) fromDate:currentDate];
components.month = components.month - 1;
components.day = 1;
NSDate *newDate = [calendar dateFromComponents:components];
This also works if your current month is january. NSDateComponents will automatically decrement the year and set the month to december.
NSDateComponents *components = [[NSCalendar currentCalendar] components:NSCalendarUnitDay | NSCalendarUnitMonth | NSCalendarUnitYear
fromDate:[NSDate date]];
components.day = 1;
components.month = components.month - 1;
NSDate *lastmonthDay1 = [[NSCalendar currentCalendar] dateFromComponents: components];
NSLog(#"First day of last month====: %#", [lastmonthDay1 descriptionWithLocale:[NSLocale currentLocale]]);
You can do something like below....
NSCalendar *gregorian = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
[gregorian setTimeZone:[NSTimeZone timeZoneWithAbbreviation:#"UTC"]];
NSDateComponents *comp = [gregorian components:(NSYearCalendarUnit | NSMonthCalendarUnit | NSDayCalendarUnit) fromDate:[NSDate date]];
[comp setDay:1];
[comp setMonth:CurrentMonth];//previous month
[comp setYear:currentYear];
NSDate *firstDayOfMonthDate = [gregorian dateFromComponents:comp];
NSCalendar *cal1=[[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
NSDateComponents *comps1 = [cal1 components:NSWeekdayCalendarUnit fromDate:firstDayOfMonthDate];
// 1 for mon 8 for sun
int startWithDay=[comps1 weekday]==1?8:[comps1 weekday];
//1 for monday
// 2 for tuesday and so on....
Let me know it is working or not!!!
Happy Coding!!!!
How to get the first day of a week for a date
this seems more easy at it is, since :
when the week starts with sunday, i need to get back the sunday date
if it starts on monday, i need to get the monday date
the input date is any date in week with time... i tried several approaches, but the edge case make it difficould
i made a function, which however doesn't work in 100% (not sure about the [components setDay: -weekday + 2];)
- (NSDate *)firstDateOfWeek {
NSCalendar * calendar = [NSCalendar currentCalendar];
NSDateComponents *weekdayComponents = [calendar components:(NSDayCalendarUnit | NSWeekdayCalendarUnit) fromDate:self];
// because sunday is 0, we need it to be 6
NSInteger weekday = (([weekdayComponents weekday] + 6) % 7);
NSDateComponents *components = [calendar components:(NSYearCalendarUnit | NSMonthCalendarUnit | NSDayCalendarUnit | NSWeekdayCalendarUnit) fromDate:self];
[components setDay: -weekday + 2];
return [calendar dateFromComponents:components];
}
It is easier to use the rangeOfUnit calendar method, which handles "start of the week" correctly according to the current locale:
NSDate *date = your date;
NSCalendar *calendar = [NSCalendar currentCalendar];
NSDate *startOfWeek;
[calendar rangeOfUnit:NSWeekOfYearCalendarUnit
startDate:&startOfWeek
interval:NULL
forDate:date];
Using NSDateComponents, it would work as follows (assuming that a week has 7 days):
NSDate *date = your date;
NSDateComponents *comp = [calendar components:NSYearCalendarUnit|NSMonthCalendarUnit|NSDayCalendarUnit|NSWeekdayCalendarUnit
fromDate:date];
NSDate *startOfDay = [calendar dateFromComponents:comp];
NSInteger diff = (NSInteger)[calendar firstWeekday] - (NSInteger)[comp weekday];
if (diff > 0)
diff -= 7;
NSDateComponents *subtract = [[NSDateComponents alloc] init];
[subtract setDay:diff];
NSDate *startOfWeek = [calendar dateByAddingComponents:subtract toDate:startOfDay options:0];
Why am I getting this output time:
2013-01-12 18:24:37.783 Code testings[10328:c07] 0001-01-01 17:12:52 +0000
when I run this code:
NSCalendar *calendar = [NSCalendar currentCalendar];
calendar.timeZone = [NSTimeZone localTimeZone];
NSDateComponents *components = [calendar components:NSHourCalendarUnit fromDate:[NSDate date]];
components.hour = 17;
components.minute = 47;
components.second = 0;
NSDate *fire = [calendar dateFromComponents:components];
NSLog(#"%#", fire);
I have tried default timezone, system timezone. And it always gives me an output with different minutes and seconds! plus wrong date 0001-01-01!!!! Any idea why?
Additional Tests:
When running this code:
NSCalendar *calendar = [NSCalendar currentCalendar];
calendar.timeZone = [NSTimeZone localTimeZone];
NSDateComponents *components = [calendar components:NSHourCalendarUnit fromDate:[NSDate date]];
components.hour = (components.hour + 1) % 24;
components.minute = 0;
components.second = 0;
NSDate *fire = [calendar dateFromComponents:components];
NSLog(#"%#", fire);
It gives me this output:
2013-01-12 18:41:41.552 Code testings[10648:c07] 0001-01-01 18:25:52 +0000
2013-01-12 18:42:16.274 Code testings[10648:c07] 0001-01-01 18:25:52 +0000
2013-01-12 18:42:30.310 Code testings[10648:c07] 0001-01-01 18:25:52 +0000
You are mising the year, month and day components.
Do:
NSDateComponents *components = [calendar components:NSUIntegerMax fromDate:[NSDate date]];
Now that should give you the correct date.
Side note: since the NSCalendarUnit is a bitfield typedef for NSUInteger, I pass in NSUIntegerMax to retrieve all possible calendar units. That way I don't have to have a massive bitwise OR statement.
You also need to request the year, month and day with the calendar components: method.
From Apple docs:
An instance of NSDateComponents is not responsible for answering
questions about a date beyond the information with which it was
initialized.
NSDateComponents *components = [calendar components:NSYearCalendarUnit | NSMonthCalendarUnit | NSDayCalendarUnit | NSHourCalendarUnit fromDate:[NSDate date]];
NSLog of the date will display the time with the default timezone.
I have a calendar application in which I want to get the next year from the current date (NSDate).
How can I do this?
You can make NSDateComponents do all the hard work of calculating leap years and leap seconds:
NSDate *today = [[NSDate alloc] init];
NSCalendar *gregorian = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
NSDateComponents *offsetComponents = [[NSDateComponents alloc] init];
[offsetComponents setYear:1];
NSDate *nextYear = [gregorian dateByAddingComponents:offsetComponents toDate:today options:0];
As VdesmedT mentioned, you can use dateByAddingTimeInterval and add the seconds of one year. But to be more precise, you can do the following:
NSDate *today = [NSDate date]; // get the current date
NSCalendar* cal = [NSCalendar currentCalendar]; // get current calender
NSDateComponents* dateOnlyToday = [cal components:( NSYearCalendarUnit | NSMonthCalendarUnit | NSDayCalendarUnit ) fromDate:today];
[dateOnlyToday setYear:([dateOnlyToday year] + 1)];
NSDate *nextYear = [cal dateFromComponents:dateOnlyToday];
Hope this helps.
Swift 4:
let calendar = Calendar.current
let newDate = calendar.date(byAdding: .year, value: 1, to: Date())
This is my version: in swift.
let calendar = NSCalendar.currentCalendar()
let newDate = calendar.dateByAddingUnit(.Year, value: 1, toDate: NSDate(), options: NSCalendarOptions.MatchNextTime)