How to set time range in a day using UIDatePickerView - iphone

I am using UIDatePickerView, just like we can set the date range using "maximumDate" and "minimumDate", is there any way to set time range in a day like from 9.00 am to 6.00 pm ?

Not really. minimumDate and maximumDate can include a time of day (NSDate is more like a timestamp than a calendar date), but this only has an effect if they are both on the same day because otherwise all (clock) times are possible within the date range.

Actually you should set the time using these two as well. NSDate objects have both date and time components. You should do something like this:
NSCalendar *gregorian = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
NSDateComponents *dateComponents = [[NSDateComponents alloc] init];
//set the date using setDate: setMonth: setYear:
[dateComponents setHour:9]; //setHour:18 for maximumDate
NSDate *targetDate = [gregorian dateFromComponents::dateComponents];
[dateComponents release];
[gregorian release];
datepick.minimumDate = targetDate;
If that doesnt help, have a look at these Qs:
UI Datepicker range. iPhone
How to set time on NSDate?

Related

How to get date from day of the year in iPhone?

How do I get date from the day of the year?
for e.g., if I give day as "1" then date should be "January 1"
How do I get that in iPhone? I have found answer in javascript but I want to know how to do the achieve same thing in Objective?
I guess this code will work for you:
I have created a sample function where a textfield gives input values for how many days to add. And a button to calculate final day. Here is the button event logic.
NSDateComponents *dateComponent = [[NSDateComponents alloc] init];
NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
[formatter setDateFormat:#"yyyy-mm-dd"];
NSDate *newDate = [formatter dateFromString:#"2012-01-01"];
// add days to current date
dateComponent.day = [dayTextField.text intValue];
// get a new date by adding components
newDate = [[NSCalendar currentCalendar] dateByAddingComponents: dateComponent toDate:newDate options:0];
[finalDate setText:[NSString stringWithFormat:#"%#", newDate]];
Here dayTextField.text is the text which says how many number of days want to calculated. (For example 125 days) and finalDate is an label which displays final generated date (means date after 125 days since 1 Jan 2012).
Benefit of this code is, any time you can change the start day parameter. For example, for other requirement, i need to count my days from "31 May 1999" then i will change it easily in one line and the same code will work.
Enjoy Coding :)
NSCalendar *gregorian =
[[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
NSUInteger dayOfYear =
[gregorian ordinalityOfUnit:NSDayCalendarUnit
inUnit:NSYearCalendarUnit forDate:[NSDate date]];
[gregorian release];
return dayOfYear;
Take from the post:
How do you calculate the day of the year for a specific date in Objective-C?

How to set variable with specified date and time?

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

How to tell if a particular NSDate (from a list of NSDates in an NSMutableArray) is part of a different week?

Basically I want to know I a user chooses from my settings what day they want a week to start on (This would have a value in the format, #"Mon" for example) and I have an NSMutableArray that holds NSDates (users add theses dates throughout the life of the app) ordered in a chronologically ascending manner, but not necessarily consecutive (there could be day's that users missed and did not add the date to the array), how could I determine that a particular NSDate in the array is part of a different week (relative to the date the user chose for a week to start on)?
This will give you the difference between two dates in weeks:
NSDateComponents *dateDifference = [gregorian components:NSWeekCalendarUnit fromDate:day1 toDate:day2 options:0];
NSUInteger weeksDiff = [dateDifference week];
So if(!weekDiff){ /*same week*/}
Complete example:
NSCalendar *gregorian = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
NSDateComponents *comps1 = [[NSDateComponents alloc] init];
NSDateComponents *comps2 = [[NSDateComponents alloc] init];
[comps1 setDay:5];
[comps2 setDay:12];
NSDate *day1 = [gregorian dateByAddingComponents:comps1 toDate:[NSDate date] options:0];
NSDate *day2 = [gregorian dateByAddingComponents:comps2 toDate:[NSDate date] options:0];
NSDateComponents *dateDifference = [gregorian components:NSWeekCalendarUnit fromDate:day1 toDate:day2 options:0];
NSLog(#"\n%# \n%#\n%d", day1, day2, [dateDifference week]);
[comps1 release];
[comps2 release];
[gregorian release];
For converting strings to NSDates, see NSDateFormatter
edit as response to comment
if you want to have a week that starts with the first date you pass in, you could instead count the days and check if they have more than 7 days difference.
NSDateComponents *dateDifference = [gregorian components:NSDayCalendarUnit fromDate:day1 toDate:day2 options:0];
NSUInteger daysDiff = [dateDifference day];
if(weekDiff < 7){ /*same week*/}
Use NSDateComponents. You can get them from date with NSCalendar instance.

Getting NSDate for today with 00:00:00 as time

I am writing a categorie in Xcode, that would extend the current NSDate class. I want to add two methods which I use regularly and somehow I can't get them to work properly.
Currently I have this code:
+ (NSDate*) today
{
NSCalendar *gregorian = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
NSDateComponents *todayComponents = [gregorian components:(NSDayCalendarUnit | NSMonthCalendarUnit | NSYearCalendarUnit) fromDate:[NSDate date]];
NSInteger theDay = [todayComponents day];
NSInteger theMonth = [todayComponents month];
NSInteger theYear = [todayComponents year];
NSDateComponents *components = [[NSDateComponents alloc] init];
[components setDay:theDay];
[components setMonth:theMonth];
[components setYear:theYear];
NSDate* todayDate = [gregorian dateFromComponents:components];
[components release];
[gregorian release];
return todayDate;
}
I want it to return a date like this: "2010-11-03 00:00:00 +01". But somehow the timezone keeps buggin me, because this code returns "2010-11-02 23:00:00 +0000".
Can anyone tell me how to fix this code to actually return the correct date? Or can I just use this date and my application will convert it itself because of the timezone the machine is set to.
I have to log certain events in my app to a database, which also just uses the [NSDate date] method. Does that mean that the [NSDate date] method also uses the time without timezone information?
EDIT:
I think it has something to do with the Daylight savings time bug. The things I see is exactly the same as probably the Clock app has, with the bug making people wake up late. Also, the TimeZone defaults to the TimeZone currently set on your device, so it should stay the same until you change the timezone in your settings screen.
EDIT2:
Ok, some more tests:
NSLog(#"CurrentDate: %#", [NSDate date]);
NSLog(#"TZ: %#", [NSTimeZone defaultTimeZone]);
Gives me the following results:
2010-11-03 23:23:49.000 App[8578:207] CurrentDate: 2010-11-03 22:23:49 +0000
2010-11-03 23:23:49.001 App[8578:207] TZ: Europe/Amsterdam (GMT+01:00) offset 3600
See Using Time Zones. You'll want to set the calendar's time zone using NSCalendar's -setTimeZone: method before you start asking it for dates.
This is an interesting question and I worked at a solution for many hours. These are my findings:
NSLog(#"CurrentDate: %#", [NSDate date]);
The code shown above will have the same result as the code shown below:
NSLog(#"CurrentDate: %#", [[NSDate date] description]);
Reading through the NSDate Class Reference produces this documentation on the NSDate's description method.
The representation is not guaranteed to remain constant across different releases of the operating system. To format a date, you should use a date formatter object instead (see NSDateFormatter and Data Formatting Guide)
I also ran across the documentation for descriptionWithLocale: (id) locale:
“Returns a string representation of the receiver using the given locale.”
So, change your code
NSLog(#"CurrentDate: %#", [NSDate date]);
To:
NSLog(#"CurrentDate: %#", [[NSDate date] descriptionWithLocale:[NSLocale currentLocale]]);
Which should result in what you are looking for. And I can also prove that the [NSDate date] really give's the correct date, but is just being displayed with wrong method:
We can use the [today] (Wim Haanstra) to create two dates.
dateLastDay: 2010-11-02 23:59:00 +01
dateToday: 2010-11-03 24:01:00 +01
Then we use the code below to show the two dates:
NSLog(#"CurrentDate: %#", dateLastDay);
NSLog(#"CurrentDate: %#", dateToday);
Or:
NSLog(#"CurrentDate: %#", [dateLastDay description]);
NSLog(#"CurrentDate: %#", [dateToday description]);
The two groups show the same results, like this: "2010-11-02 22:59:00 +0000" and "2010-11-02 23:01:00 +0000". It looks like the two dates have the same ‘day’, but really?
Now we compare the days of the dates:
NSCalendar *gregorian = [[NSCalendar alloc]
initWithCalendarIdentifier:NSGregorianCalendar];
NSUInteger unitFlags = NSDayCalendarUnit;
NSDateComponents *lastDayComponents = [gregorian components:unitFlags fromDate:dateLastDay];
NSDateComponents *todayComponents = [gregorian components:unitFlags fromDate:dateToday];
NSInteger lastDay = [lastDayComponents day];
NSInteger today = [todayComponents day];
return (lastDay == today) ? YES : NO;
We will get NO! Although the two dates appear to have the same day, month and year, they DON'T. It only appears that way because we displayed them in the wrong way.
Did you try using:
NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
[formatter setDateFormat:#"yyyy-MM-dd"];
todayAtOO = [formatter dateFromString:[formatter stringFromDate:[NSDate date]]];
I'm still trying to figure out exactly why this bug happens, but I do know a solution. Setting the timezone of your NSCalendar to GMT before sending it dateFromComponents: will solve the issue.
[gregorian setTimeZone:[NSTimeZone timeZoneWithName:#"GMT"]];
PS if there's a different solution that you found based on Joshua's suggestion, could you let us know what it is? It seems like you've solved the issue since you accepted his answer, but it's not really clear what you did. Thanks!
As far as I can see, it is giving you the correct answer if your timezone is GMT+1. Midnight your time is 23:00 the day before in GMT.
The problem is probably in formatting the returned date for output. It's given you a string for GMT instead of your current locale.

Difference between 2 NSDates, excluding Weekends?

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)