converting day of week index to string objective c - objective-c

currently, i am working on an app that uses Core Data. One of my managed objects has a property that keeps track of the day of week (Sunday - Saturday) as an integer (0-6). For the sake of sorting the objects by day as well as less overhead in saving, i definitely believe the best practice is to save the days as indexes and then convert to string during runtime. The question becomes the best practice to convert the index to its corresponding day as a string. ie. 0=>#"Sunday" and 6 => #"Saturday". I can obviously use NSCalendar and NSDate and NSDateComponents to achieve this. It just seems like a very roundabout way to go about it given the simplicity of the task. Naturally, a simple NSString array defined as such could do the trick:
NSString *dayOfWeek[7] = {#"Sunday",#"Monday",#"Tuesday",#"Wednesday",#"Thursday",#"Friday'"#"Saturday"};
But then i find myself constantly redefining this same variable over and over again. A global constant NSString could work. Another idea I had was creating a function that used this dayOfWeek array and then including it in the files that need it. What do you think. What's the best practice?

How about one of the weekdaySymbols methods of NSDateFormatter?

Another solution would be to define a category method on NSString, for example, to return the string based on the number. Then the strings array can be static and only used in that method.

Related

Ordering NSStrings that are numbers of a particular format (ex 3:23.123)?

I have NSStrings that represent times of the format mm:ss.SSS in my app. I am trying to generate a list of "fastest times" and I'm struggling trying to figure out what data types to use to order these numbers.
What is the easiest way to order these strings from least to greatest amount of time? I'm assuming converting to a numbered data type would do the trick, but what data type should I be using? I need to preserve the mm:ss.SSS formatting.
If you have NSString objects you can convert to NSDate objects (such as these, presumably, which you could, for example, convert into ISO 8601 format using a suitable offset), then you can sort an NSArray instance of NSDate objects very easily (example) and pick from the top or bottom of the list, depending on whether you sort in descending or ascending order.
The advantage of this approach is that you are working with standard date processing functions, which can result in less code and less debugging. Reinventing the wheel may get you a faster solution, but it can also introduce bugs.
You can also use (abuse ?) localizedStandardCompare: for that purpose, because that method compares numbers embedded in the string according to their numerical value:
NSArray *times = #[ #"11:22.333", #"2:44.555" ];
NSArray *sortedTimes = [times sortedArrayUsingSelector:#selector(localizedStandardCompare:)];
NSLog(#"%#", sortedTimes);
Output:
(
"2:44.555",
"11:22.333"
)
If the strings are well-formed, with leading zeros, form an NSArray and then invoke sortedArrayUsingComparator:. But if you have values like 12:34.567 and 2:34.567, this approach won't work. You'll have to convert, either to double or NSNumber, storing seconds (that is, 2:34.567 converts to 154.567).
Note that these are not NSDate objects. An NSDate marks a particular instant in time, and these appear to be simply durations.
If you use NSNumber, you can still use sortedArrayUsingComparator:. You'll have to write a subclass of NSFormatter, to convert between mm:ss.SSS and NSNumber and back again.
See the documentation for NSComparator for a blocks-based example. You'll also need the Class Reference for NSFormatter. The FormatterKit project on GitHub has some nice NSFormatter sample code.
My advice is to create your own class that represents the datatype for mm, ss and SSS. You can then write your own prettyprint and compare methods for the datatype. The compare method itself would be fairly simple to implement and you can then use that compare method to sort an array of such objects.

What's the difference between NSDate and CFGregorianDate?

I have some objective-c code I'm converting from iPhone to iPad. CFGregorianDate is used throughout for date functions. I have never used it, preferring to use NSDate.
I want to take the date and format it so I get the full month name, using the format string "MMMM", which I don't seem to be able to do using CFGregorianDate.
What's the difference between the two, and does it make any difference in usage?
From the docs:
CFDate is “toll-free bridged” with its Cocoa Foundation counterpart, NSDate. What this means is that the Core Foundation type is interchangeable in function or method calls with the bridged Foundation object. In other words, in a method where you see an NSDate * parameter, you can pass in a CFDateRef, and in a function where you see a CFDateRef parameter, you can pass in an NSDate instance. This also applies to concrete subclasses of NSDate.
So, no difference in usage, really. The main difference is that CFDate and its subclasses are legacy types.
However, as has been pointed out, CFGregorianDate is extremely different from CFDate. It doesn't store a timestamp but rather the year, month, day, hour minute and second as separate integers.
So your best bet is to create a method like cfGregorianToNSDate: in which you parse these integers and construe a new NSDate object.

Sort array with string dates Objective C

I have an NSMutableArray of Strings. The Strings in the array, are converted from dates to Strings and I need to sort them and show them in a tableview.
I need:
June 24, 2011
June 26, 2011
July 1, 2011
And so on.
I know questions similar to this have been asked, but I didn´t get it to work. So I would really appreciate if someone could help me!
Sort them while they're still dates, keep them as a sorted list of dates, and only format them as text as needed for display (i.e., during -tableView:cellForIndexPath:).
Alternatively, the ISO 8601 date formats (an example formatted date would be 20110603T1345.123-4) mostly sort lexicographically the same as they would as dates. Times in different time zones or that cross a summer time shift can invalidate this property, though, so leaving dates as dates would still be your best bet.
Easy way to do this is to create a function of the form
NSInteger funcName(id left, id right, void* extra);
you can then use NSMutableArray's sortUsingFunction:context: passing your comparison function in. Jeremy is correct in stating that dates are easier to sort, they have built in comparison functions:
– isEqualToDate:
– earlierDate:
– laterDate:
– compare:
See NSMutableArray for sorting information and NSDate for its comparison methods
Your NSMuatbleArray must have the NSDate object.
First you need to sort the array using -[NSMutableArray sortUsingSelector:] and need to pass #selector(compare:).
The compare: function of NSDate will do the job for you and sort the array in ascending order ..
After following the above you just need to call reloadData function of UITableView.

Searching an NSArray o strings with an NSDate

Hard to get the headline correct since there is so much to tell.
I got this NSArray (A portion of it):
Mon, 06:00, Radioshow Morning, Mon, 10:00, Lunch radio, 14:00, Afternoon Radio and so on.
The NSArray is from an plist in the app.
What I need to build (and failed with) is a search function that shows me the right program with these search values:
searchDay and searchTime
Both those values are from NSDate.
I've been Googling for about and hour now and hasn't come up with anything usefull so my last hope stands to stackoverflow to show me what I am missing.
I've been dabbling with dateFromString, compare, timeIntervalSinceNow but for some reason failed to achive what I am about to do.
Greatful for any help givven.
TIA
Mattias
You should use an NSArray of NSDictionary objects instead of various object types in your NSArray:
NSDictionary *morningShow = [NSDictionary dictionaryWithObjectsAndKeys:#"Mon",#"day","10:00",#"time","morning",#"name",nil];
Then add that to your array. Then, when you are searching, you have a uniform data structure to search inside of.
I think I have solved it.
But I must say I am intrigued by phooze answer.
The way I am doing it now is reading the values (NSString) from the array converting them into an NSDate object and comparing those with timeIntervalSinceDate.
By that I can figure out if currentTime is between two times in the array and such I know what show is on. I've just come up with the solution, the base code is working but the whole code isn't done yet, just on paper/in my mind.
But it feels like a somewhat ugly code... lots of doing small things.
But I will pre sue this to the end and if it still looks inefficient and ugly I will look in to other solutions.

Add missing objects to create an ordered collection

The subject is vague because I'm not sure how to articulate in one sentence what I want.
Here goes:
I have an NSArray of NSDictionaries. Each NSDictionary represents one day of the calendar year. Each NSDictionary has a key "date" with a value of NSDate. There should be 365 NSDictionary items in the array. The dictionary is created by a server that I don't control, and it sometimes is missing as many as 100 days.
I need to ensure the array has 365 dictionaries, each one day later than the next.
I currently sort the array by date, iterate through it, copying the NSDictionaries from the current array to a new array. While so doing, I compare the current Dictionary's date value with the date value for the next dictionary. If there is more than one day between the two dates, I add enough new dictionaries to the new array to cover those missing days (and set their dates accordingly), then continue through.
Since the dates are supposed to ordered, I wonder if there is not already a mechanism in the framework or language that I can use to say "Here is an array, and this keypath is supposed to be consecutive. Find and create the elements that are missing, and here's a block or method you can use to initialize them".
Something about my method just feels poorly implemented, so I turn to you. Thoughts?
Thanks.
The way you did it sounds perfectly sane, and there is nothing to my knowledge that will do it automatically in the base framework.
This code will sort them.
NSArray *dates; // wherever you get this...
NSArray *sortedDates = [dates sortedArrayUsingComparator:^(id obj1, id obj2)
{
return [[obj1 valueForKey:#"date"] compare:[obj2 valueForKey:#"date"]];
}];
As for creating the missing entries, you'll have to do that yourself.
You don't need to do the sort:
Create an array with 365 (or 366) placeholder dictionaries (you can possibly use the same one for all slots, or use NSNull)
iterate through the passed in array and figure out which day each of the dictionaries is for. Place each dictionary in its rightful slot in your array.