I need to build a mortgage calculator for iPhone as a task and I need to be able to read startdate from DatePicker in MainView, then an enddate for another DatePicker in FlipView and calculate the difference in the number of months between both dates. As I am new to Apple programming I do not know how to do it. Help, please :)
From your edit, it seems that the more specific problem you have is reading the date from a UIDatePicker
From the docs, the method you need to call is date
NSDate *dateFromPicker = [myDatePickerObject date];
you could use - (NSTimeInterval)timeIntervalSinceDate:(NSDate *)anotherDate .
The result will be NSTimeInterval which will be a double that is equivalent to the amount of seconds. Take that amount and divide by the appropriate number (seconds? 60. hours? 360. etc…)
The code would resemble:
[[datePicker1 date] timeIntervalSinceDate:[datePicker2 date]];
Good luck!
NSCalendar *calendar = [NSCalendar currentCalendar];
NSDateComponents *differenceComponents = [calendar components:NSMonthCalendarUnit | NSDayCalendarUnit fromDate:startDate toDate:endDate options:0];
int monthDifference = differenceComponents.month;
Related
I'm trying to learn Objective-C/iPhone SDK and right now I'm doing a kind of to-do app playing with local notifications.
I have a "timeOfDay" ivar stored as an NSDate from a DatePicker and a "numberOfDays" ivar stored as an NSNumber.
When I press a specific button, I would like to schedule a local notification x numberOfDays from the time the button is pressed but at the specific timeOfDay.
I seems easy to add an NSTimeInterval to the current date which would give me the a way to schedule the notification numberOfDays from current time but adding the timeOfDay feature makes it more complex.
What would be the correct way of achieving this?
Thanks
Use NSDateComponents to add time intervals to an existing date while respecting all the quirks of the user's current calendar.
NSCalendar *calendar = [NSCalendar autoupdatingCurrentCalendar];
// Get the year, month and day of the current date
NSDateComponents *dateComponents = [calendar components:(NSYearCalendarUnit | NSMonthCalendarUnit| NSDayCalendarUnit) fromDate:[NSDate date]];
// Extract the hour, minute and second components from self.timeOfDay
NSDateComponents *timeComponents = [calendar components:(NSHourCalendarUnit | NSMinuteCalendarUnit | NSSecondCalendarUnit) fromDate:self.timeOfDay];
// Apply the time components to the components of the current day
dateComponents.hour = timeComponents.hour;
dateComponents.minute = timeComponents.minute;
dateComponents.second = timeComponents.second;
// Create a new date with both components merged
NSDate *currentDateWithTimeOfDay = [calendar dateFromComponents:dateComponents];
// Create new components to add to the merged date
NSDateComponents *futureComponents = [[NSDateComponents alloc] init];
futureComponents.day = [self.numberOfDays integerValue];
NSDate *newDate = [calendar dateByAddingComponents:futureComponents toDate:currentDateWithTimeOfDay options:0];
There is a pretty simple method to do this that won't involve as many lines of code.
int numDays = 5;
myDate = [myDate dateByAddingTimeInterval:60*60*24*numDays];
+ (id)dateWithTimeInterval:(NSTimeInterval)seconds sinceDate:(NSDate *)date
That should give you what you're looking for.
I am able to display the calendar (dates) of this month in table view and I am highlighting the current date and it is working fine, but now what I want to do is to display next coming 2 weeks from the current date.
I am using the following code to get the dates of the month
NSDate *today = [NSDate date];
NSCalendar *calender = [NSCalendar currentCalendar];
days = [calender rangeOfUnit:NSDayCalendarUnit
inUnit:NSMonthCalendarUnit
forDate:today];
How to calculate the up coming two weeks from today?
Check my answer from this post. There you can set value for daysToAdd that you want and get the NSDate corresponding.
May be you can try with:
NSDate *inTwoWeeks = [NSDate dateWithTimeIntervalSinceNow:60*60*24*7*2]
I searched it a lot but coudn't find any instance of showing how to store the specified time. For example, i need to save time of 15:48 in code in a proper variable (i guess that should be NSDate object). That is needed because i want to hold the exact time to replace the method below with not the time interval since now but my exact specified time to fire notification. Thanks for the help.
NSDate *notificationDate = [NSDate dateWithTimeIntervalSinceNow:5];
notification.fireDate = notificationDate;
Use NSDateComponents:
NSDateComponents *comps = [[NSDateComponents alloc] init];
[comps setHour:15]; // 15:48 from your example
[comps setMinute:48]; // 15:48 from your example
/// also set year, month and day
NSCalendar *gregorian = [[NSCalendar alloc]
initWithCalendarIdentifier:NSGregorianCalendar];
NSDate *date = [gregorian dateFromComponents:comps];
[comps release];
You can also use NSDateCompnents to read the components from the current date and time - so if you want to set an NSDate to 15:48 today, you would first create an NSDate for now and then extract the day, month and year from it but overwrite the hour and minutes.
Use NSDateComponents to generate an NSDate object. I guess the Apple document is what you want http://developer.apple.com/library/mac/#documentation/Cocoa/Reference/Foundation/Classes/NSDateComponents_Class/Reference/Reference.html
Take a look at NSDateFormatter and especially - (NSDate *)dateFromString:(NSString *)string
I am writing an app which uses core-data to store my data. Included in this is a date field of which I am only interested in the date not the time.
I need to select records based on the date (not time) and so I have created a category on NSDate to return a date, normalised to a set time as follows:
+ (NSDate *)dateWithNoTime:(NSDate *)dateTime {
if( dateTime == nil ) {
dateTime = [NSDate date];
}
NSDateComponents* comps = [[NSCalendar currentCalendar] components:NSYearCalendarUnit|NSMonthCalendarUnit|NSDayCalendarUnit fromDate:dateTime];
NSDate *dateOnly = [[NSCalendar currentCalendar] dateFromComponents:comps];
[dateOnly dateByAddingTimeInterval:(60.0 * 60.0 * 12.0)]; // Push to Middle of day.
return dateOnly;
}
I then use this when I add data to the core-data store (I have a setter which uses this method to set the primitive date value) and then I use this method to create a date that I use to compare the dates when performing a fetch request. So in theory this should always work - ie pick out the dates I'm looking for.
I'm slightly nervous though as I'm not totally sure what effect changing time-zone or locale will have. Will it still work ?
What is considered best practice when storing and searching on a date only when you aren't interested in the time.
Cheers.
EDIT
After reading the discussion recommended I think that I should modify my code to be as follows. The thinking being that if I ensure that I push it to a specific calendar system and a specific timezone (UTC) then the dates should always be the same regardless of where you are when you set the date and when you read the date. Any comments on this new code appreciated.
+ (NSDate *)dateWithNoTime:(NSDate *)dateTime {
if( dateTime == nil ) {
dateTime = [NSDate date];
}
NSCalendar *calendar = [[[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar] autorelease];
[calendar setTimeZone:[NSTimeZone timeZoneWithAbbreviation:#"UTC"]];
NSDateComponents *components = [[[NSDateComponents alloc] init] autorelease];
components = [calendar components:NSYearCalendarUnit|NSMonthCalendarUnit|NSDayCalendarUnit
fromDate:dateTime];
NSDate *dateOnly = [calendar dateFromComponents:components];
[dateOnly dateByAddingTimeInterval:(60.0 * 60.0 * 12.0)]; // Push to Middle of day.
return dateOnly;
}
You have a few issues to deal with here. First, as you noted, timezones. You also need to worry about daylight savings, which change the concept of “midday.”
Take a look at this discussion on CocoaDev where an Apple Engineer gives some answers and discusses some best practices.
A simpler solution is to use a predicate that looks for dates within a certain range.
Use NSCalendarComponent to create a start date and an end date for you "day" and then include those in the predicate.
NSPredicate *p=[NSPredicate predicateWithFormat:#"$# <= date <= $#",startDate,endDate];
That will provide the maximum flexibility without to much complexity. Date and time programing is deceptively complex. Be prepared to do some work.
I also ended up in a scenario where I needed to have an NSDate to compare a date without taking into consideration time.
I hade a filter mechanisme and as part of the UI, if the user chose today the minimum date as start date and the end date as today, I would display "All time periods" as opposed to a string in the format:
1/5/2006 - 24/12/2009
So I needed to take todays date using +date of NSDate, and compare it to the end date. That end date came from a UIDatePicker set to without time, but +date returned the date and time of right now.
So I wrote this short handy method, it receives a date object, uses NSDateComponents and the NSCalendar class to extract the day, month and year.
These 3 parameters are then used to create a new NSDate using NSDateFormatter's -dateFromString: method, the result is an NSDate corresponding to the same "date" (in the traditional human concept) as the parameter date but without time.
- (NSDate *)strictDateFromDate:(NSDate *)date{
NSUInteger flags = NSYearCalendarUnit | NSMonthCalendarUnit | NSDayCalendarUnit;
NSDateComponents *components = [[NSCalendar currentCalendar] components:flags
fromDate:[NSDate date]];
NSString *stringDate = [NSString stringWithFormat:#"%d/%d/%d", components.day, components.month, components.year];
NSDateFormatter *formatter = [[[NSDateFormatter alloc] init] autorelease];
formatter.dateFormat = #"dd/MM/yyyy";
return [formatter dateFromString:stringDate];
}
I hope you can use and enjoy this function in future.
For those familiar with Excel, I'm trying to use a similiar NETWORKDAYS function within Cocoa.
Can anyone help with the type of info I'll need to construct an NSDate catagory that can give me only the working days betweek two dates?
many thanks
Nik
I know that I'll give is not optimized, but it's just to give you a way to explore.
You can use the NSCalendar and the NSDateComponents like that:
// Date of today
NSDate *today = [NSDate date];
// init the gregorian calendar
NSCalendar *gregorian = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
// Retrieve the NSDateComponents for the current date
NSDateComponents *weekdayComponents = [gregorian components:(NSDayCalendarUnit | NSWeekdayCalendarUnit) fromDate:today];
// Number of the day in the week (e.g 2 = Monday)
NSInteger weekday = [weekdayComponents weekday];
(see Calendars, Date Components, and Calendar Units)
From there you start from your first date and you iterate this for each day until your end date and using the weekday you can determine if the day is during a weekend or not. (I repeated that's not optimized but it's just a track)