Is it possible to code a custom date picker for iOS in objective C to display only the last 30 days from today in this format: Day, Month Day, Year
I am trying to build a view that will display a list of item (fetched from API) based on the date selection but I only want the user to select from the last 30 days only. The entire date should be scrollable, not individual date or month.
Yes, overlapping the month.
For example:
Fri, May 19, 2017 ... scroll all the way back to... Wed, Apr 19, 2017
Thanks.
I think you want something like this.
NSCalendar *calendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSCalendarIdentifierGregorian];
NSDate *currentDate = [NSDate date];
NSDateComponents *comps = [[NSDateComponents alloc] init];
[comps setMonth: -1];
// or
//[comps setDay: -30];
NSDate *minDate = [calendar dateByAddingComponents:comps toDate:currentDate options:0];
[datePicker setMaximumDate:currentDate];
[datePicker setMinimumDate:minDate];
Related
I need to filter search results based on values that were added yesterday. I have seen plenty on finding yesterday using:
NSCalendar *cal = [NSCalendar currentCalendar];
NSDateComponents *components = [cal components:( NSHourCalendarUnit | NSMinuteCalendarUnit | NSSecondCalendarUnit ) fromDate:[[NSDate alloc] init]];
[components setHour:-24];
[components setMinute:0];
[components setSecond:0];
NSDate *yesterday = [cal dateByAddingComponents:components toDate:[NSDate date] options:0];
predicate = [NSPredicate predicateWithFormat:#"created_at >= %#", yesterday];
But this finds 24 hours since this exact moment in time. I need to filter yesterday as 12:01am-12:00pm. So the actual 24 hour period that was yesterday.
I'm guessing that I need to do something along the lines of:
1. Take the current date
2. Find the time from the current date to 12:01am of the same day
3. Then subtract 24 hours from that date
I feel confident I can do #3 (and #1 of course), but I'm not sure how to go about #2. I maybe over thinking it but I can't seem to grasp how to say: "Ok, it's 8:03am, I need to remove 8 hours and 2 minutes which will put me at 12:01am".
Start with some date of today, for example "now":
NSCalendar *cal = [NSCalendar currentCalendar];
NSDate *now = [NSDate date];
Subtract one day to get some date of yesterday:
NSDateComponents *minusOneDay = [[NSDateComponents alloc] init];
[oneDay setDay:-1];
NSDate *nowMinusOneDay = [cal dateByAddingComponents:minusOneDay toDate:now options:0];
Compute start and end date of the "day calendar unit" that contains yesterday's date:
NSDate *startOfYesterday;
NSTimeInterval lengthOfYesterday;
[cal rangeOfUnit:NSDayCalendarUnit startDate:&startOfYesterday interval:&lengthOfYesterday forDate:nowMinusOneDay];
NSDate *endOfYesterday = [startOfYesterday dateByAddingTimeInterval:lengthOfYesterday];
This should work even if a daylight savings time transition occurs between today and yesterday.
Generally one should avoid to use explicit time intervals such as "24 hours", because not every day has that length.
I need to fetch objects from core data within specific time periods; i.e. weekly, monthly, yearly.
I would then feed the dates generated from the components into a predicate like this:
[NSPredicate predicateWithFormat:#"(date >= %#) AND (date <= %#",
intervalStartDate, intervalEndDate];
Examples of intervals/periods:
start end start end
weekly Jan 2, 2012 to Jan 08, 2012, Jan 9, 2012 to Jan 15, 2012, etc.
monthly Jan 1, 2012 to Jan 31, 2012, Feb 1, 2012 to Feb 29, 2012, etc.
yearly Jan 1, 2011 to Dec 31, 2011, Jan 1, 2012 to Dec 31, 2012, etc.
With these, I could get the specific objects during that time period.
My problem is, that I don't know what would be the best way to increment the date components. I have to account for leap years, etc.
What would be the best way to achieve this?
As long as you use the correct NSCalendar and as long as you treat each calculation of dates independent of each other, the resulting dates should be fine.
NSDateComponents *dateOffset = [[NSDateComponents alloc] init];
[dateOffset setWeek:1]; // weekly
// [dateOffset setMonth:1]; // monthly
// [dateOffset setYear:1]; // yearly
NSDate *endDate = [gregorian dateByAddingComponents:dateOffset toDate:startDate options:0];
So long as you use the NSGregorianCalendar, e.g.
NSCalendar *gregorian = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
your date calculations should take advantage of the subtleties (really, oddities) of that calendar.
For example:
// get your start date
NSDateComponents *components = [NSDateComponents new];
components.day = 1;
components.month = 5;
components.year = 2012;
NSCalendar *gregorian = [[NSCalendar alloc]
initWithCalendarIdentifier:NSGregorianCalendar];
NSDate *date = [gregorian dateFromComponents:components];
// add 7 days
NSDateComponents *addWeekComps = [NSDateComponents new];
components.day = 7;
NSDate *weekAddedDate = [gregorian dateByAddingComponents:addWeekComps toDate:date options:0];
I want to get difference between dates skipping time means if one date is 13 Jan 2012 - 11 pm and other date is 14 Jan 2012 - 12 am,then difference should be 1 day not 0 day.I mean I want difference between date only, 14 Jan 2012 - 13 Jan 2012, skipping time. I know I can use NSDate api to calculate difference but the problem is it consider time also.So I thought while calculating difference I will skip time but I do not know how to skip time because if I use NSDateFormatter it will return string not date.Please help me what I can do?
Thanks in advance!
What you need to do is get the NSDateComponents of each date first. Once you do that you can compare the 'day' component to get you difference.
NSCalendar *cal = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
[cal setTimeZone:[NSTimeZone timeZoneForSecondsFromGMT:0]];
NSDate *date1 = ....;
NSDate *date2 = ....;
NSDateComponents *comps1 = [cal components:NSDayCalendarUnit|NSYearCalendarUnit|NSMonthCalendarUnit fromDate:date1];
NSDateComponents *comps2 = [cal components:NSDayCalendarUnit|NSYearCalendarUnit|NSMonthCalendarUnit fromDate:date2];
date1 = [cal dateFromComponents:comps1];
date2 = [cal dateFromComponents:comps2];
NSDateComponents *diffComps = [cal components:NSDayCalendarUnit fromDate:date1 toDate:date2 options:0];
NSLog(#"Days diff = %d", diffComps.day);
The date API can be kind of weird to wrap your head around, but once you do it is quite powerful.
How to get date for every year of july month using NSDate .I am getting the data from the web service which I called. And now I am showing the full data in the graph which is very huge. The data which we are having is from 1998 to till now. so I want to show the data only every year of july. For this I need the help. Can anyone help me?
Well, NSDate is a specific date and time and not just month and year. If you're fine with something like every July 1 at 12 AM (or whatever time/day) then you can use NSDateComponents to set the components of the date.
NSDateComponents *comps = [[NSDateComponents alloc] init];
[comps setMonth:5];
[comps setYear:2004];
NSCalendar *gregorian = [[NSCalendar alloc]
initWithCalendarIdentifier:NSGregorianCalendar];
NSDate *date = [gregorian dateFromComponents:comps];
[comps release];
[gregorian release];
This is straight from the Apple documentation. If you want to get the next year, then you can use dateByAddingTimeInterval: on your NSDate to return a new date (or you can use the original NSDateComponents and setYear: in a loop).
I would like to know the dates of all Monday's in a month using NSCalendar in Objective-C. So Please help me.
Thanks in advance
I blogged a solution for this a few months ago
http://brandontreb.com/case-of-the-mondays/
From https://discussions.apple.com/thread/1700102?start=0&tstart=0 and the Apple NSCalendar reference:
How about using something like this -
NSDateComponents *comps = [[NSDateComponents alloc] init];
[comps setYear:1965]; // Year of the calendar month
[comps setMonth:1]; // Month
[comps setDay:6]; // Any day
NSDate *date = [gregorian dateFromComponents:comps];
[comps release];
Then, once you have the NSDate, do this:
NSDate * testDate = [NSDate date];
NSString * weekdayString = [testDate descriptionWithCalendarFormat:#"%A" timeZone:nil
locale:[[NSUserDefaults standardUserDefaults] dictionaryRepresentation]];
NSLog(#"Day of the week: %#", weekdayString);
// weekdayString should look like "Monday", etc.
So, you can loop through the month's days until;
[weekdayString isEqualToString:#"Monday"] // or your desired day
And then just add 7 days to get the other 4 or so dates.
This may not be the prettiest solution, but it should work.