iPhone + Twitter API: Converting time? - iphone

Is there an easy way to convert the time stamp you get from twitter into unix time or minutes since now? I could parse through the string and convert everything myself but I'm hoping there is a way to convert that doesn't need that. Here is an example of a created_at element with a time stamp.
Sun Mar 18 06:42:26 +0000 2007

You can use NSDateFormatter with something like this :
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
NSLocale *usLocale = [[NSLocale alloc] initWithLocaleIdentifier:#"en_US"];
[dateFormatter setLocale:usLocale];
[usLocale release];
[dateFormatter setDateStyle:NSDateFormatterLongStyle];
[dateFormatter setFormatterBehavior:NSDateFormatterBehavior10_4];
// see http://unicode.org/reports/tr35/tr35-6.html#Date_Format_Patterns
[dateFormatter setDateFormat: #"EEE MMM dd HH:mm:ss Z yyyy"];
NSDate *date = [dateFormatter dateFromString:[currentDict objectForKey:#"created_at"]];
[dateFormatter release];
NSTimeInterval seconds = [date timeIntervalSince1970];

I have been strugeling with this all day, but this thread helped me to find a solution.
This is how I convert the Twitter "created_at" attribute to a NSDATE;
NSDateFormatter *fromTwitter = [[NSDateFormatter alloc] init];
// here we set the DateFormat - note the quotes around +0000
[fromTwitter setDateFormat:#"EEE MMM dd HH:mm:ss '+0000' yyyy"];
// We need to set the locale to english - since the day- and month-names are in english
[fromTwitter setLocale:[[NSLocale alloc] initWithLocaleIdentifier:#"en-US"]];
NSString *dateString = [item objectForKey:#"created_at"];
NSDate *tweetedDate = [fromTwitter dateFromString:dateString];
I hope someone will find this helpful.

File a feature request with Apple and let them know you want this functionality on the iPhone. NSDateFormatter provides a legacy init method that takes a boolean flag indicating you want it to parse natural language, but it's only available on OS X. Wil Shipley wrote an interesting post a while back about this functionality in the context of heuristics and human factors.
It doesn't seem likely that Apple will provide this functionality as this note would indicate from the NSDateFormatter docs:
iPhone OS Note: iPhone OS supports
only the 10.4+ behavior. 10.0-style
methods and format strings are not
available on iPhone OS.
In other words, I think you'll have to parse it yourself.

Sounds like you need something like: ISO 8601 parser and unparser.

Related

iOS get Time from Date

I'm developing an application and I need to parse a Tweet timestamp that actually is a string like this:
"Mon, 17 Oct 2011 10:20:40 +0000"
However what I need it is only the time. So what I'm trying to get it is:
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:#"HH:mm"];
NSDate *date = [dateFormatter dateFromString:timestamp];
but when I try to print the Date with NSLog the output is (null) and I don't understand why. What I need, if it is possible, is to create a date object only with the time. Indeed later on I need to compare different dates but I care only about the time. It is not important if the date are different because of the day, month or year, the important is that I can compare them with the "timeIntervalSinceDate" to get the difference in seconds.
Any help will be really appreciated.
Thanks
Ale
NSDATE is al full date object, it needs a date en time.
You can use NSDateFormatter to only display the time, but you will need to parse the full string to get the NSDate object.
Here some code you can use:
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
//Mon, 11 Jul 2011 00:00:00 +0200
[dateFormatter setLocale:[[[NSLocale alloc] initWithLocaleIdentifier:#"EN"] autorelease]];
[dateFormatter setDateFormat:#"EEE, d MMM yyyy HH:mm:ss ZZZZ"];
NSDate *date = [dateFormatter dateFromString: timestamp];
[dateFormatter release], dateFormatter = nil;
You need to set the local to make sure it read the timestamp in the correct language.
Also alloced the dateFormatter outside any loops and release it after you're done with the loop.
Look at NSDateComponents. You should be able to create a date from components. You'll have to parse the timestamp yourself, though (which should be easy — just split on the colon and grab the number from each component).

Changing timezones in a textbox

I have a small IOS program and that get a time from a database server. I would like to convert that to the users localtime (I always know the timezone of the server).
I have been playing with replacing the hour piece of the string, but that seems like a bad idea.
In C# I would convert the string into a DateTime and add the hours in the diference between the server time and the localtime, but I simply cant figure out how to do that in ObjectiveC.
So could anyone give a few hints? The date/time string I get from the sever looks like this:
2011-02-27 12:10:02
I would convert the date from the string into and NSDate object using NSDateFormatter. The you can use the dateByAddingTimeInterval method to add in your hour. Also NSCalendar has more advanced functions for adding time intervals.
I believe this should work for local time:
NSDateFormatter *dateFormatter = [NSDateFormatter alloc] init];
NSLocale *serverLocale = [NSLocale alloc] initWithLocaleIdentifier:#"en_US"];//Change to Server Locale
[dateFormatter setLocale:serverLocale];
[serverLocale release];
[dateFormatter setDateFormat:#"YYYY-MM-DD HH:MM:SS"];
NSDate *date = [dateFormatter dateFromString:#"2011-02-27 12:10:02 "];
//Replace the locale below with what you need
NSString *dateString = [date descriptionWithLocale:[NSLocale currentLocale]];
[dateFormatter release];
textField.text = dateString;

NSDateFormatter issue

I just referred to the Q & A at iOS reference for NSDateFormatter.
Link: http://developer.apple.com/library/ios/#qa/qa2010/qa1480.html
Here is my problem I get a string from a webservice which is of this format:
"dd-mm-yyyy xx:xx:xx AM"
My actual purpose is just to use the date and not the time at all. But I just use the same format in the NSDateFormatter and I was able to get the answers properly for all date related problems except on one mobile which is iOS 4.1.
Please let me know what is the most optimal solution for this problem. I think, I should just use date and that will solve my problem or any other suggestions for this problem?
Your question wasn't really helpful in terms of the result you get form iOS 4.1. Anyways...
Try this...
// convert date
NSString *webStr = [NSString stringWithFormat:#"28-10-2010 04:44:22 AM"];
NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
[formatter setDateFormat:#"dd-MM-yyyy HH:mm:ss a"];
NSDate* date = [formatter dateFromString:webStr];
// set up the new date format
[formatter setDateFormat:#"dd-MM-yyyy"];
NSString *myDate = [formatter stringFromDate:date];
[formatter release];

NSDateFormatter dateFromString and iPhone in 24 Hour Format Confusion

I'm having a problem. I get incoming time strings in 12-hour format, and I'm turning them into NSDate objects. When the iPhone is in 12 hour format, no problem. But when it's in 24 Hour format, things go wrong. Here's some sample code to demonstrate:
NSString *theTime = #"3:19 PM";
NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
[formatter setDateFormat:#"h:mm a"]; // "3:19 PM"
NSDate *date = [formatter dateFromString:theTime];
NSString *theString = [formatter stringFromDate:date];
In 24 hour mode, date is 1970-01-01 03:19:00, and theString is "3:19" - WRONG
In 12 hour mode, date is 1970-01-01 15:19:00, and theString is "3:19 PM" - RIGHT
So... question 1: why is the device's 24 hour setting overriding my date formatter setting?
and more importantly, question 2: How do I get a proper conversion from 12 hour time to 24 hour time?
I already have code to detect if the phone is in 24 hour mode, but other than digging around in the string and swapping the 3 with a 15, there doesn't seem to be a clean way to do this.
Not sure if you still need it, but I've had a similar problem which got solved by setting the locale for the date formatter. That is, if you want to force it to 12-hour mode, regardless of the user's 24/12 hour mode setting, you should set the locale to en_US_POSIX.
The reason for this behaviour is Locale, set the correct Locale
NSString *strAgendaDate = #"01/17/2012 12:00 AM";
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setLocale:[[[NSLocale alloc] initWithLocaleIdentifier:#"en_US"] autorelease];
[dateFormatter setDateFormat:AgendaDateFormatForMeeting];
NSDate *meetingDate = [dateFormatter dateFromString:aStrDate];
[dateFormatter setDateFormat:AgendaDateRepresentation];
strAgendaDate = [dateFormatter stringFromDate:meetingDate];
It works for both 24-hour and 12 hour format
I believe the #"h:mm a" should be #"HH:mm a".
If you use the pre-build dateformatter in cocoa, everything will be taken care of for you.
NSDateFormatter *timeFormatter = [[[NSDateFormatter alloc] init] autorelease];
[timeFormatter setTimeStyle:NSDateFormatterShortStyle];
[timeFormatter setDateStyle:NSDateFormatterNoStyle];
NSDateFormatterShortStyle and NSDateFormatterNoStyle comes in different varieties.
Using those will make sure you respect the settings the user has selected for dates and times.
The 12-14 hour clock conversion is taken care of by the SDK, if you have a model or some value object for storing your dates try to keep them as NSDate. This way you can format them only when you need to display them. Saving dates as strings could open a world of trouble when you maybe parse them from xml where the GMT is specified separately or try to add and subtract NSTimeIntervals.
I changed from #"hh:mm:ss" to #"HH:mm:ss" and time style was changed from "1:03 PM" to "13:03".
Hope this will help you.
Okay, I left a comment, but it squished all the code together, so I'll have to "answer" my question with a comment:
Thanks. I gave it a whirl with this code:
NSString *theTime = #"3:19 PM";
NSDateFormatter *timeFormatter = [[[NSDateFormatter alloc] init] autorelease];
[timeFormatter setTimeStyle:NSDateFormatterShortStyle];
[timeFormatter setDateStyle:NSDateFormatterNoStyle];
NSDate *date = [timeFormatter dateFromString:theTime];
NSString *theString = [timeFormatter stringFromDate:date];
And date comes up nil. I ran into this earlier when I tried this route, and it's not working. Very frustrating.

NSDateFormatter, am I doing something wrong or is this a bug?

I'm trying to print out the date in a certain format:
NSDate *today = [[NSDate alloc] init];
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:#"yyyyMMddHHmmss"];
NSString *dateStr = [dateFormatter stringFromDate:today];
If the iPhone is set to 24 hour time, this works fine, if on the other hand the user has set it to 24 hour time, then back to AM/PM (it works fine until you toggle this setting) then it appends the AM/PM on the end even though I didn't ask for it:
20080927030337 PM
Am I doing something wrong or is this a bug with firmware 2.1?
Edit 1: Made description clearer
Edit 2 workaround: It turns out this is a bug, to fix it I set the AM and PM characters to "":
[dateFormatter setAMSymbol:#""];
[dateFormatter setPMSymbol:#""];
The reason for this behaviour is Locale, It sets the correct Locale.
Set the local of your NSDateFormatter to en_US_POSIX will fix this.
It works for both 24-hour and 12 hour format.
On iPhone OS, the user can override the default AM/PM versus 24-hour time setting (via Settings > General > Date & Time > 24-Hour Time), which causes NSDateFormatter to rewrite the format string you set. From apple doc
Try this,
NSDate *today = [[NSDate alloc] init];
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setLocale:[[NSLocale alloc] initWithLocaleIdentifier:#"en_US_POSIX"]];
[dateFormatter setDateFormat:#"yyyyMMddHHmmss"];
NSString *dateStr = [dateFormatter stringFromDate:today];
Here's the explanation of the iPhone SDK bug (also still there in 3.1 beta SDK)
First, a little background on the iPhone user interface. When iPhone
users change their region format between, say, “United States” and
“France”, the users’ “24-Hour Time” setting is automatically switched
to the mode that is most prevalent in that region. In France, that
would set 24-Hour Time to “ON”, and in the U.S., that would set it to
“OFF”. The users can then manually override that setting and that’s
where trouble starts.
The problem comes from NSDateFormatter somehow “getting stuck” in the
12 or 24-hour time mode that the user has manually selected. So if a
French user manually selects 12-hour mode, and the application
requested NSDateFormatter to output time with the 24-hour format
“HHmm”, it would actually receive time in a 12-hour format, e.g.
“01:00 PM”, as if the application had instead requested “hhmm aa”.
The reverse would happen if a US user manually selected 24-hour mode:
outputting time with the 12-hour format “hhmm aa” would actually get
you time in the 24-hour format instead, e.g. “17:00″.
More details and a possible workaround can be found on this blog.
Using the code you posted on both the simulator and a phone with the 2.1 firmware and 24-hour time set to off, I never had an AM/PM appended to dateStr when I do:
NSLog(#"%#", dateStr);
Are you doing anything else with dateStr that you didn't post here? How are you checking the value?
Follow up
Try turning the am/pm setting on then off. I didn't have the problem either, until I did that. I am printing it out the same way you are.
Okay, I see it when I do this also. It's gotta be a bug. I recommend you file a bug report and just check for and filter out the unwanted characters in the meantime.
Setting locale on date formatter to en_US fixes the problem for me:
NSDateFormatter * f = [[NSDateFormatter alloc] init];
[f setDateFormat:#"yyyy-MM-dd'T'HH:mm:ss'Z'"];
f.timeZone = [NSTimeZone timeZoneForSecondsFromGMT:0];
f.calendar = [[[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar] autorelease];
f.locale = [[[NSLocale alloc] initWithLocaleIdentifier:#"en_US"] autorelease];
I'm not sure if adding the calendar is also needed, but this works well.
I think this is the solution .
NSDateFormatter *df =[[NSDateFormatter alloc] init];
[df setDateFormat:#"yyyy-MM-dd HH:mm:ss"];
NSLocale *usLocale = [[NSLocale alloc] initWithLocaleIdentifier:#"en_US"];
[df setLocale: usLocale];
[usLocale release];
NSDate *documento_en_Linea =[[[NSDate alloc] init]autorelease];
documento_en_Linea=[df dateFromString:#"2010-07-16 21:40:33"];
[df release];
NSLog(#"fdocumentoenLineaUTC:%#!",documento_en_Linea);
//ouput
fdocumentoenLineaUTC:2010-07-16 09:40:33 p.m. -0500!
For those finding this question who want to use NSDateFormatter to parse 24-hour time and are hitting this bug, using NSDateComponents to parse dates and times which have a known format sidesteps this issue:
NSString *dateStr = #"2010-07-05";
NSString *timeStr = #"13:30";
NSDateComponents *components = [[NSDateComponents alloc] init];
components.year = [[dateStr substringToIndex:4] intValue];
components.month = [[dateStr substringWithRange:NSMakeRange(5, 2)] intValue];
components.day = [[dateStr substringFromIndex:8] intValue];
components.hour = [[timeStr substringToIndex:2] intValue];
components.minute = [[timeStr substringFromIndex:3] intValue];
NSCalendar *calendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
NSDate *date = [calendar dateFromComponents:components];
[components release];
[calendar release];
This should also work (I am seeing some bizzare results though).
-(NSString*)lowLevTime:(NSString*)stringFormat {
char buffer[50];
const char *format = [stringFormat UTF8String];
time_t rawtime;
struct tm * timeinfo;
time(&rawtime);
timeinfo = localtime(&rawtime);
strftime(buffer, sizeof(buffer), format, timeinfo);
return [NSString stringWithCString:buffer encoding:NSASCIIStringEncoding];
}
Short answer: try [dateFormatter setDateFormat:#"yyyyMMddhhmmss"]; for 12 hour format (note the lowercase hh).
It's been a frustrating topic because so many websites indicate to use HH for hours (including the official Apple documentation), but that sets it to 24 hour format, whereas hh uses 12 hour format. See http://unicode.org/reports/tr35/tr35-6.html#Date_Format_Patterns for more details.
As a bonus, note that you can also use KK or kk for hour of the day format, which will likely be off by one.
Update:
I was recently looking at NSLocale (https://developer.apple.com/library/mac/#documentation/Cocoa/Reference/Foundation/Classes/NSLocale_Class/Reference/Reference.html) and it would seem that you can use autoupdatingCurrentLocale to apply changes made from within the app to the Locale. The upshot of this is that even if the phone is set to use a 24 hour clock (like when you switched to France), you can make a 12/24 toggle for the app that won't impact any other apps on the phone, or require you to leave the app to make the change.