iphone: find date for 4th day of week - iphone

I used NSDateComponents to find date for 4th, 2nd day of the week like this
NSDate *today = [NSDate date];
NSCalendar *gregorian = [[NSCalendar alloc]
initWithCalendarIdentifier:NSGregorianCalendar];
NSDateComponents *weekdayComponents = [gregorian components:(NSDayCalendarUnit |
NSMonthCalendarUnit |
NSYearCalendarUnit |
NSWeekCalendarUnit |
NSWeekdayCalendarUnit)
fromDate:today];
[weekdayComponents setWeekday:4];
NSLog(#"Date at that day was %#",[gregorian dateFromComponents:weekdayComponents]);
but every time the output is
Date at that day was 2011-06-20 18:30:00 +0000
Can you help in this
Thanks in advance

[weekdayComponents setDay:weekdayComponents.day+ (4-weekdayComponents.weekday)];
As for the NSlog output: NSLog (#"%#", somedate) displays the time in GMT0, but actions with NSDateComponents made taking into account time zone, so 2011-06-20 18:30:00 +0000 is beginning оf 21.06.2011 in your time zone

Related

Get the first day and last day of a week

I am using this method to get the current week first and last days:
NSDate *weekDate = [NSDate date];
NSCalendar *myCalendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
NSDateComponents *currentComps = [myCalendar components:( NSYearCalendarUnit | NSMonthCalendarUnit | NSWeekOfYearCalendarUnit | NSWeekdayCalendarUnit | NSHourCalendarUnit | NSMinuteCalendarUnit) fromDate:weekDate];
int ff = currentComps.weekOfYear;
NSLog(#"1 %d", ff);
[currentComps setWeekday:1]; // 1: sunday
NSDate *firstDayOfTheWeek = [myCalendar dateFromComponents:currentComps];
[currentComps setWeekday:7]; // 7: saturday
NSDate *lastDayOfTheWeek = [myCalendar dateFromComponents:currentComps];
NSDateFormatter *myDateFormatter = [[NSDateFormatter alloc] init];
myDateFormatter.dateFormat = #"dd/MM/yyyy";
NSString *firstStr = [myDateFormatter stringFromDate:firstDayOfTheWeek];
NSString *secondStr = [myDateFormatter stringFromDate:lastDayOfTheWeek];
NSLog(#"first - %# \nlast - %#", firstStr, secondStr);
And i want to know what i should change in this to get the next week first and last day and two weeks from now to?
To get the next week, add 7 days to firstDayOfTheWeek and then lastDayOfTheWeek.
NSDateComponents *comps = [[NSDateComponents alloc] init];
[comps setDay:7];
NSDate *firstDayOfNextWeek = [myCalendar dateByAddingComponents:comps toDate:firstDayOfTheWeek options:0];
This code assumes a 7-day week. Ideally you would replace this assumption with code that gets the actual length of the week.
Side Note: Your code assume the week starts on Sunday. Many locales start their week on others days such as Monday. Change:
[currentComps setWeekday:1];
to:
[currentComps setWeekday:[myCalendar firstWeekday]];
I would then change your calculation of lastDayOfTheWeek to simply add 6 days to firstDayOfWeek.
Use Below code which returns index of current current weekly days. For example if its today is saturday than it will give you 7 means last day of week.
-(int)currentdayweeklynumber{
NSDate *CurrentDate = [NSDate date];
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:#"yyyy-MM-dd"];// you can use your format.
//Week Start Date
NSCalendar *gregorian = [[NSCalendar alloc]initWithCalendarIdentifier:NSGregorianCalendar];
NSDateComponents *components = [gregorian components:NSWeekdayCalendarUnit | NSYearCalendarUnit | NSMonthCalendarUnit | NSDayCalendarUnit fromDate:CurrentDate];
int dayofweek = [[[NSCalendar currentCalendar] components:NSWeekdayCalendarUnit fromDate:CurrentDate] weekday];
NSLog(#" dayofweek=%d",dayofweek);
return dayofweek;
}
Using this number you add or subtract to get first or last of week. You can also use this get next week start and end date by just simple calculation.

Forming a predicate to filter between dates

Say I have two dates:
minDate:2012-08-29 12:22:17 +0000
maxDate:2011-12-01 18:14:38 +0000
I have a Core Data object called MBDate which has an NSDate property. I want to get all MBDate's with days including and in between the days above. So it should disregard the hours, seconds, and minutes, and just get all days in between and including 8/29 - 12/01.
Something like:
predicate = [NSPredicate predicateWithFormat:#"date < %# AND date > %#", maxDate, minDate];
But I'm not sure how I would tell it to disregard the hours and minutes and just look at the days. Any ideas?
You could use NSDateComponents to set a 'low' and 'high' date and use these in your predicate.
NSCalendar *gregorian = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
gregorian.timeZone = [NSTimeZone timeZoneWithAbbreviation"#"UTC"];
NSDateComponents *dateComponents = [gregorian components:(NSDayCalendarUnit | NSMonthCalendarUnit | NSYearCalendarUnit) fromDate:minDate];
[dateComponents setHour:0];
[dateComponents setMinute:0];
[dateComponents setSecond:0];
NSDate *lowDate = [gregorian dateFromComponents:dateComponents];
dateComponents = [gregorian components:(NSDayCalendarUnit | NSMonthCalendarUnit | NSYearCalendarUnit) fromDate:maxDate];
[dateComponents setHour:23];
[dateComponents setMinute:59];
[dateComponents setSecond:59];
NSDate *highDate = [gregorian dateFromComponents:dateComponents];

Compare dates - overlooking the hour part

I frequently use the NSDate compare method - but I want to consider two dates similar if they are equal in year, month, day. I have made a procesure called "cleanDate" to remove the hour part before I compare.
-(NSDate*)cleanDate:(NSDate*)date {
NSCalendarUnit unitflags;
NSDateComponents *component;
NSCalendar *calendar;
calendar=[[[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar]autorelease];
unitflags=NSYearCalendarUnit | NSMonthCalendarUnit | NSDayCalendarUnit;
component=[calendar components:unitflags fromDate:date];
return [calendar dateFromComponents:component]; //Dato uten klokke
}
But my dates come out as:
2011-10-28 22:00:00
and some dates as:
2011-10-28 23:00:00
I want the hour part to be similar, e.g. 00:00.
Whats wrong? Does it have something to do with daylight saving time? Other? Thanks.
-(NSDate*)cleanDate:(NSDate*)date {
NSDateComponents *comps = [[NSCalendar currentCalendar]
components:NSDayCalendarUnit | NSYearCalendarUnit | NSMonthCalendarUnit
fromDate:date];
[comps setHour:0];
[comps setMinute:0];
[comps setSecond:[[NSTimeZone systemTimeZone] secondsFromGMT]];
return [[NSCalendar currentCalendar] dateFromComponents:comps];
}
Seems like this is a Time Zone issue...
I thought NSLog would default to the local time zone - but it seems to default to GMT...
Date with GMT time zone is: Sat, 29 Oct 2011 22:00:00 GMT+00:00
Date with system time zone is: Sun, 30 Oct 2011 00:00:00 GMT+02:00
NSlog shows 2011-10-29 22:00:00 +0000
When using NSLog(#"NSlog shows %#",finalDate); it seems to print the GMT time...
When using this code - I will get the local date in my time zone:
NSDateFormatter *dateFormatter = [[[NSDateFormatter alloc] init] autorelease];
[dateFormatter setDateFormat:#"EEE, d MMM yyyy HH:mm:ss z"];
[dateFormatter setTimeZone:[NSTimeZone systemTimeZone]];
NSString *dateString = [dateFormatter stringFromDate:myDate];
NSLog(#"Date with system time zone is: %#",dateString);
... so my original cleanDate actually seems to do what I want after all...

How can I create a date with no hours in the current time zone?

This question follows on from a previous question...
How do I create the current date (or any date) as an NSDate without hours, minutes and seconds?
I would use this code as follows...
NSDate *todaysDate = [General makeAbsoluteNSDate:[NSDate date]];
My problem is that I have users in different countries and UTC isn't their timezone and the date produced by this function at certain times of the day won't be correct.
How do I get the current time zone to correct my function ?
Or should I be using a different approach ?
Heres the function I've been using...
+ (NSDate *)makeAbsoluteNSDate:(NSDate*)datSource {
NSCalendar *calendar = [[NSCalendar alloc] initWithCalendarIdentifier:
NSGregorianCalendar];
[calendar setTimeZone:[NSTimeZone timeZoneWithAbbreviation:#"UTC"]];
NSDateComponents *dateComponents = [calendar components:NSYearCalendarUnit |
NSMonthCalendarUnit | NSDayCalendarUnit
fromDate:datSource];
[dateComponents setHour:0];
[dateComponents setMinute:0];
[dateComponents setSecond:0];
NSDate *midnightUTC = [calendar dateFromComponents:dateComponents];
[calendar release];
return midnightUTC;
}
You get the timezone object from this call:
[NSTimeZone localTimeZone]
And you can use the secondsFromGMT method to figure out the difference and create a date with the timezone.
You can even build a Category for NSDate that includes a method to transform a date into the current timezone date, which would be even simpler.

iPhone SDK, how to get NSDate object of coming friday's 20:00?

Does anyone know how to get the NSDate of the coming friday's 20:00 ?
Yes, this article teaches you how to get the current week's Sunday.
I quickly adapted it to get friday at 20:00 (Assuming a Gregorian calendar)
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 add to the current date.
The weekday value for Friday in the Gregorian calendar is 6, so add the difference between 6 and today to get the number of days to add.
Actually, on Saturday that will give you -1, so you want to subtract from 13 then take modulo 7
*/
NSDateComponents *componentsToAdd = [[NSDateComponents alloc] init];
[componentsToAdd setDay: (13 - [weekdayComponents weekday]) % 7];
NSDate *friday = [gregorian dateByAddingComponents:componentsToAdd toDate:today options:0];
/*
friday 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: friday];
// And to set the time to 20:00
[components setHour:22];
friday = [gregorian dateFromComponents:components];