Getting date info into an array in Objective-C Cocoa framework - objective-c

I have a function that returns an array to hold date info.
- (NSArray*) getTodayArray
{
NSDate *today = [NSDate date];
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:#"YYYY"];
NSString *year = [dateFormatter stringFromDate:today];
[dateFormatter setDateFormat:#"MM"];
NSString *month = [dateFormatter stringFromDate:today];
[dateFormatter release];
NSArray *res = [NSArray arrayWithObjects: year, month, nil];
return res;
}
Q1 : Is there any easy way to get all the info (year, month, date, hour, minute ...) in an array not using setDateFormat over and over again?
Q2 : Is there a way so that I can access the content of array using res['year'] or similar? I mean using dictionary?
Q3 : Do I need to release NSArray *res in the caller of this function?

A1: You can do smth like this:
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:#"YYYY|MM"];
NSArray* d_arr = [[dateFormatter stringFromDate: [NSDate date]] componentsSeparatedByString: #"|"];
A2: Use NSDictionary:
[NSDictionary dictionaryWithObjectsAndKeys: [d_arr objectAtIndex: 0], #"year", [d_arr objectAtIndex: 1], #"month", nil]
A3: return value is autoreleased. you don't need to release it.

#prosseek
1 - I dont think you have another choice to get the year, month, date, hour, minute ... from NSDate other than this.(I am not sure about it though.)
2 - you can access the objects in the dictionary in the above format but something more like objective-c style. like this
[dateDictionary obectForKey:#"year"];
but you need to define the dictionary in that format
like this
NSDictionary *dateDictionary = [NSDictionary dictionaryWithObjects:year,min,hr,nil forKeys:#"year", #"min", #"hour", nil];
3 - no you dont need to release or autorelease the NSArray in the above method . but i think you need to retain it in the array that is receiving res array if you want to use it after a while.

Why don't you just use a NSArray of NSDates?
You can probably get all of your desired functionality out of its plethora of functions.

A1: You could dump it all out into a string, but then you'd have to parse the string, which wouldn't be any easier.
A2: You could do that if you used an NSDictionary instead of an NSArray.*
A3: No, it's already autoreleased.
* Why don't you write a category for NSDate instead?
NSDate+Convenience.h
#interface NSDate (Convenience)
- (NSInteger)year;
- (NSInteger)month;
#end
NSDate+Convenience.m
#implementation NSDate (Convenience)
- (NSInteger)year {
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:#"YYYY"];
NSString *myYear = [dateFormatter stringFromDate:self];
[dateFormatter release];
return myYear;
}
- (NSInteger)month {
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:#"MM"];
NSString *myMonth = [dateFormatter stringFromDate:self];
[dateFormatter release];
return myMonth;
}
#end
Just #include NSDate+Convenience.h wherever you want to use your handy date and month accessors. All of your NSDate instances will then get them:
NSDate *myDate = [NSDate date];
NSLog(#"%ld %ld", [myDate year], [myDate month]);
No need for loosely-typed NSArrays or NSDictionaries to store this stuff.
(Note you could modify the above code to use a shared NSDateFormatter.)

Q1: Not an array, but you can use -[NSCalendar components:fromDate:] to get an NSDateComponents object. You can use it directly or build an array from it, if that is your preference.
Q2: No, but if you return an NSDateComponents object, then you can use -year, -month, etc methods on it.
Q3: No, you don't need to release it in this method or the caller, unless the caller retains it (which may be desirable).

You're looking for the NSDateComponents class. You'll need to create an NSCalendar object first, then call the components:fromDate: method to get the DateComponents object, after which you can access the object's month, year etc. properties.
Not quite sure what you want here. As it stands, the array cannot be accessed in the manner you describe, though if you want you could always create a dictionary and assign values for keys such as 'month' or 'year'. However, it might just be easier to return the DateComponents object, and access its properties.
No, there is no need to release the NSArray. You constructed it using the NSArray class method, which is already autoreleased.

Related

how to use nsdate string objec for later use?

I'm so fedup with NSDate string object.
currently I am generating an unique id on the bases of NSDate as follows:
NSDate *current_date = [[NSDate date]retain];
NSDateFormatter *df = [[NSDateFormatter alloc]init];
[df setDateFormat:#"HHmmssddMMYY"];
NSString *unique_id=[df stringFromDate:current_date];
NSString * current_Test_id=[NSString stringWithString:unique_id];
NSLog(#"current_test_idString %#",current_Test_id);
The code above is generating unique id and prints successfully but if I am printing or accessing currtent_Test_id in another IBAction method then app crashes.
stringWithString will create an autorelease string, modify your code as
NSString * current_Test_id = [[NSString stringWithString:unique_id]retain];
Use this Method
- (NSString *)stringDateFromDate: (NSDate *) date{
NSDateFormatter *df = [[NSDateFormatter alloc]init];
[df setDateFormat:#"HHmmssddMMYY"];
NSString *current_Test_id=[NSString stringWithString:[df stringFromDate:date]];
[df release];
NSLog(#"current_tst_id %#",current_Test_id);
return current_Test_id;
}
Call Method Like that
NSString *current_tst_id = [self stringDateFromDate:[NSDate date]];
an NSString (or any object, for that matter) created with a class method, and not an init method, will be autoreleased. This means on the next iteration of the event loop, current_Test_id is released, and now you have a pointer to a dead object.
See this similar question
As current_Test_id is instance method.
in the init (in case of mac os) or viewDidLoad (for ios) alloc+init it.
and then assign :
current_Test_id=[NSString stringWithString:unique_id]; //it will be in autorelease mode.
or
current_Test_id=[[NSString stringWithString:unique_id]retain];

How do I sort my UITableViewCells based on the dates in a property list?

(Prepare to witness a newbie being very, very confused at what I'd assume is a basic form of logic that my brain is struggling to grasp.)
I have a .plist file at the moment. In the "Key" column there are names of events (it's just dummy content at the moment), and in the "Value" column there are dates in this format: 19-07-2012. Each row is of the "string" type.
In the viewDidLoad method, I use the following code:
NSString *theFile = [[NSBundle mainBundle] pathForResource:#"dates" ofType:#"plist"];
theDates = [[NSDictionary alloc] initWithContentsOfFile:theFile];
theDatesList = [theDates allKeys];
This loads the plist file into the dictionary, then I load the keys into an array, which is the way I've learned to populate a UITableView, specifically with this code in the cellForRowAtIndexPath method:
NSString *eventFromFile = [theDatesList objectAtIndex:indexPath.row];
NSString *dateFromFile = [theDates objectForKey:[theDatesList objectAtIndex:indexPath.row]];
But what I'm confused about now is, how do I order the cells of the UITableView based on what dates are the soonest? So, the cell for the 19th of July would appear before the 21st of August, no matter what order it's in within the plist file.
Within the UITableViewCell I've managed to calculate the number of days between the current date and the date defined within the plist. That's this code:
// Set the date format
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:#"dd-MM-yyyy"];
// Get the current, then future date
NSDate *currentDate = [NSDate date];
NSDate *futureDate = [dateFormatter dateFromString:dateFromFile];
// Create the calendar object
NSCalendar *theCalendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
// Extract the "day" component from the calendar object
NSDateComponents *theDifferenceBetweenDays = [theCalendar components:NSDayCalendarUnit
fromDate:currentDate
toDate:futureDate
options:0];
NSInteger theRemainingDays = [theDifferenceBetweenDays day];
But I really have no idea what I'm doing. Could someone give me a nudge in the right direction? I've looked into NSSortDescriptors and the sortedArrayUsingSelector method, which seem to be relevant, but the act of actual implementation has left me stuck for the past six hours. Or maybe they're not the right track. Like I said, I'm quite confused.
Thanks.
There are several ways to sort an NSArray of NSDates in descending order.
You could use sortedArrayUsingDescriptors::
NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:#"self" ascending:NO];
theDatesList = [theDatesList sortedArrayUsingDescriptors:[NSArray arrayWithObject:sortDescriptor]];
But I personally prefer sortedArrayUsingComparator::
theDatesList = [theDatesList sortedArrayUsingComparator:^NSComparisonResult(NSDate *date1, NSDate *date2){
return [date2 compare:date1];
}];
There exists a objective C equvialent for monotouch.dialog.
with this, it should be really easy.

Sort objects of array according to date wise in iphone dev?

I've objects of array, in each object i have different type of strings in one string i am getting date from xml parsing, now my task is that to sort whole data according to time wise(like before date then current date then after date). I am having two problems.
How to sort array on this structure like objects of arrays if simple
then it'll more easy for me?
Which function should I use to sort date wise?
One of several options would be using a comparator block. You didn't provide enough informations, so I made some assumptions:
The date string is at the 3rd index of the NSArrays
The date string looks like 31-12-2011
Code
NSDateFormatter *dateFormatter = [[[NSDateFormatter alloc] init] autorelease];
[dateFormatter setDateFormat:#"dd-MM-yyyy"];
array = [array sortedArrayUsingComparator: ^(id a, id b) {
NSArray *array1 = (NSArray *)a;
NSArray *array2 = (NSArray *)b;
NSDate *date1 = [dateFormatter dateFromString:[array1 objectAtIndex:2]];
NSDate *date2 = [dateFormatter dateFromString:[array2 objectAtIndex:2]];
return [date1 compare:date2]
}
But you should also consider to have an class representing the data.
In that case you would inter ate over the raw dater and create a object for every data set, put it in an NSMutableArray and sort this. similar.

Save NSDate to CoreData

i want to save NSDate from XML to coreData.
I dont know how to set the Value for NSDate. Can someone give me little help?
My Entity attribute is NSDate. Or should it be a String and Save the Date as String??
[Sets setValue:[TBXML textForElement:xmlDate] forKey:#"beginDate"];
Thanks for any response and help,
brush51
Whether you are intentionally obfuscating or not, you don't say it, so I'm going to guess that:
[TBXML textForElement:xmlDate] returns an NSString
beginDate is a Date property of entity Sets
In which case your code is obviously incorrect: you must pass an instance of NSDate to setValue:forKey:. Your code would look like:
NSDateFormatter *myXMLdateReader = [[NSDateFormatter alloc] init];
[myXMLdateReader setDateFormat:#"yyyy-MM-dd"]; // for example
NSDate *itsDate = [myXMLdateReader dateFromString:[TBXML textForElement:xmlDate]];
[myXMLdateReader release];
[Sets setValue:itsDate forKey:#"beginDate"];
It is no problem to add NSDate to CoreData. All you need to do is to convert NSString from XML file to NSDate object. For converting NSString <-> NSDate you can use NSDateFormatter class. In example below you can see how I do this:
NSDateFormatter *parseFormatter = [[[NSDateFormatter alloc] init] autorelease];
[parseFormatter setLocale:[[[NSLocale alloc] initWithLocaleIdentifier:#"US"] autorelease]];
[parseFormatter setDateFormat:#"EEE, dd MMM yyyy HH:mm:ss Z"];
NSString *dateString = #"Mon, 02 May 2011 21:12:56 +0000";
NSDate *dateToAdd = [parser.parseFormatter dateFromString:dateString];
You can set needful date format and use this code in your project.

iPhone simple method definition and calling the current date/time

I'm very new to iPhone development, and I'm trying to write a function which will accept one parameter, and return the current date/month and store it in a variable.
But I'm getting a (null) value with NSLog.
Method:
-(NSString *) getNowDateMonth:(NSString *)type {
NSDate *now = [[NSDate alloc] init];
if (type==#"month") {
NSDateFormatter *monthFormat = [[NSDateFormatter alloc] init];
[monthFormat setDateFormat:#"MM"];
NSString *theMonth = [monthFormat stringFromDate:now];
[monthFormat release];
return theMonth;
} else if (type==#"day") {
NSDateFormatter *dateFormat = [[NSDateFormatter alloc] init];
[dateFormat setDateFormat:#"dd"];
NSString *theDate = [dateFormat stringFromDate:now];
//int setDate = theDate;
[dateFormat release];
return theDate;
}
[now release];
return NULL;
}
Calling the function to get value:
NSString *month = [self getNowDateMonth:#"month"];
NSLog(#"%#", month);
Am I going about this the right way?
First of all, compare the strings using [#"month" isEqualToString:type], because two strings containing the same text ("month") may not be equal by the == operator. == checks if they're the same string object, not strings object with the same contents.
Second of all, you're leaking the date when returning the month or day (not releasing now). You should use [NSDate date]; instead of [[NSDate alloc] init].
To sum up, a suggested better version of this method would be:
-(NSString *) getNowDateMonth:(NSString *)type {
NSDate *now = [NSDate date];
if ([#"month" isEqualToString:type]) {
NSDateFormatter *monthFormat = [[NSDateFormatter alloc] init];
[monthFormat setDateFormat:#"MM"];
NSString *theMonth = [monthFormat stringFromDate:now];
[monthFormat release];
return theMonth;
} else if ([#"day" isEqualToString:type]) {
NSDateFormatter *dateFormat = [[NSDateFormatter alloc] init];
[dateFormat setDateFormat:#"dd"];
NSString *theDate = [dateFormat stringFromDate:now];
[dateFormat release];
return theDate;
} else {
return nil;
}
}
Also, there are a few other points that can be taken into consideration to improve this method:
do not use NSString as type; use an enum
do not allocate NSDateFormatter on each call to the method; instead use a static variable in the method
You want to use NSDateComponents to reliably and easily extract unit information i.e. month, day, week etc from an NSDate.
See Date and Time Programming Guide for Cocoa.
Dates are a deceptively complex programing problem so Cocoa has a fully developed set of classes for dealing with them. However, the learning curve is a bit steep.