Convert time format to relative time Objective C - objective-c

How do I convert 2011-05-08T22:08:38Z to a relative time format in Objective C?

// create a date formatter
NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
// set the formatter to parse RFC 3339 dates
[formatter setDateFormat:#"yyyy'-'MM'-'dd'T'HH':'mm':'ss'Z'"];
// the formatter parses your date into an NSDate instance
NSDate *date = [formatter dateFromString:#"2011-05-08T22:08:38Z"];
// now to get relative information you can do things like this, which
// will give you the number of seconds since now
NSTimeInterval secondsFromNow = [date timeIntervalSinceNow];
// or this, which will give you the time interval between this data
// and another date
NSTimeInterval secondsFromOther = [date timeIntervalSinceDate:someOtherDateInstance];

Related

Converting timestamp into NSDate

I have a date in timestamp which looks something like this: 1474914600000
Now, I want to covert this timestamp to NSDate in format of dd-mm-yyyy.
How can this be done in objective c?
You need to convert your timestamp to NSDate and then get NSDate in your desired format. Also your timestamp seems to be in millisecond so you will have to divide it be 1000. You can use below code:
double timeStamp = 1474914600000;
NSTimeInterval timeInterval=timeStamp/1000;
NSDate *date = [NSDate dateWithTimeIntervalSince1970:timeInterval];
NSDateFormatter *dateformatter=[[NSDateFormatter alloc]init];
[dateformatter setDateFormat:#"dd-MM-yyyy"];
NSString *dateString=[dateformatter stringFromDate:date];
dateString value as an output will be: "27-09-2016"
Hope it helps.
To elaborate on balkaran's answer incase you're new to the iOS world. The timestamp you provided seems to go down to milliseconds which you wouldn't need for day times that's why he's dividing by 1000. You would use the dateformatter as follows to return an NSString you can use with the formatted date.
NSDate *date = [NSDate dateWithTimeIntervalSince1970:1474914600000];
NSDateFormatter *formatter = [NSDateFormatter new];
formatter.dateFormat = #"dd-MM-yyyy";
NSString *formattedDate = [formatter stringFromDate:date];
use this:
NSDate *date = [NSDate dateWithTimeIntervalSince1970:timeStamp/1000];
then convert your date in the format you want.

iOS create NSDate from output of Python datetime.isoformat()?

My python backend uses the isoformat() method on UTC date times, which results in strings that look like 2014-01-14T18:07:09.037000. Following other examples, I'm trying to create NSDates from those strings (passed up in JSON packets):
NSDateFormatter *dateFormatter = [NSDateFormatter new];
[dateFormatter setDateFormat:#"yyyy-MM-dd'T'HH:mm:S"];
NSLog(#"cycle_base %#", myFields[#"cycle_base"]);
self.cycleBase = [dateFormatter dateFromString: myFields[#"cycle_base"]];
NSLog(#"cycleBase %#", self.cycleBase);
I've tried variants on the S part (which is supposed to be fractional seconds?) of the format string, but to no avail. I always get a nil back. What am I doing wrong?
iOS 7 follows the Unicode Technical Standard #35, which is a list of format patterns.
In this document you will find that the format string for fractional seconds is capitalized S.
NSString *string = #"2014-01-14T18:07:09.037000";
NSDateFormatter *formatter = [NSDateFormatter new];
formatter.dateFormat = #"yyyy-MM-dd'T'HH:mm:ss.S";
NSDate *date = [formatter dateFromString:string];
NSLog(#"%#", date);
This will net you a valid NSDate object. Don't forget to set the proper time zone and locale on your NSDateFormatter object.

Problems formatting dates

Here is the set up, I have a JSON feed I am using and I want to find the difference between two specific dates called posted_date and planned_expiration_date. They are in an odd format I so I thought I could truncate them down to just the date.I could then use NSTimeInterval to find the difference in seconds.
// Time Interval Left
NSDateFormatter *formatter = [[NSDateFormatter alloc]init];
NSString *startDate = [firstPerson objectForKey:#"posted_date"];
NSString *endDate = [firstPerson objectForKey:#"planned_expiration_date"];
//Ammend the strings to YYYY-MM-DD
[formatter setDateFormat:#"yyyy-mm-dd"];
int newlength = 9;
NSDate *startDateAmmended =[formatter dateFromString:[startDate substringFromIndex:newlength]];
NSDate *endDateAmmended = [formatter dateFromString:[endDate substringFromIndex:newlength]];
Here is the bit I'm not too sure about. The date appears something like this "2013-06-07T13:40:01Z" straight from the feed. I don't know how to deal with the T and Z chars in the date formatter method so I truncate the string with substringFromIndex to make it 10 chars and then attempted the following code.
//Difference in Date
NSTimeInterval *startDifference = [startDateAmmended timeIntervalSinceNow];
NSTimeInterval *endDifference = [endDateAmmended timeIntervalSinceNow];
NSTimeInterval timeDifferenceInSeconds = startDifference - endDifference;
I get the following error, .../JSONParser/ViewController.m:52:21: Initializing 'NSTimeInterval *' (aka 'double *') with an expression of incompatible type 'NSTimeInterval' (aka 'double') at the first two calls to NSTimeInterval.
I am sure I'm going wrong in a few places and I'm sure this isn't the easiest method of doing it. Could anyone recommend how I would fix this issue or an easier way to go about getting the differences between dates?
Your error comes from your lines that say:
NSTimeInterval *startDifference = [startDateAmmended timeIntervalSinceNow];
NSTimeInterval *endDifference = [endDateAmmended timeIntervalSinceNow];
They should be:
NSTimeInterval startDifference = [startDateAmmended timeIntervalSinceNow];
NSTimeInterval endDifference = [endDateAmmended timeIntervalSinceNow];
Or, more simply, don't define those two difference variables at all, and just use:
NSTimeInterval timeDifferenceInSeconds = [endDateAmmended timeIntervalSinceDate:startDateAmmended];
To calculate the difference between two ISO 8601 / RFC 3339 date strings, you can do:
NSDate *startDate = [self dateFromISO8601String:#"2013-06-01T16:27:35Z"];
NSDate *endDate = [self dateFromISO8601String:#"2013-06-07T13:40:01Z"];
NSTimeInterval elapsed = [endDate timeIntervalSinceDate:startDate];
NSLog(#"Time elapsed (in seconds) is %.0f", elapsed);
where dateFromISO8601String is defined as:
- (NSDate *)dateFromISO8601String:(NSString *)string
{
static NSDateFormatter *formatter = nil;
if (formatter == nil)
{
formatter = [[NSDateFormatter alloc] init];
NSLocale *enUSPOSIXLocale = [[NSLocale alloc] initWithLocaleIdentifier:#"en_US_POSIX"];
formatter.locale = enUSPOSIXLocale;
formatter.dateFormat = #"yyyy'-'MM'-'dd'T'HH':'mm':'ss'Z'";
formatter.timeZone = [NSTimeZone timeZoneForSecondsFromGMT:0];
}
return [formatter dateFromString:string];
}
You can get the difference in seconds between two NSDate objects like this:
double difference = [startDateAmmended timeIntervalSinceDate:endDateAmmended];
Note that with the substring operation you don't have the time, only the date, so the difference will be in seconds but with steps of whole days.

current Date and Time - NSDate

I need to display the current Date and Time.
I have used ;
NSDate *currentDateNTime = [NSDate date];
I want to have the current date and time (Should display the system time and not GMT time).
The output should be in a NSDate format and not NSString.
for example;
NSDate *currentDateNTime = [NSDate date];
// Do the processing....
NSDate *nowDateAndTime = .....; // Output should be a NSDate and not a NSString
Since all NSDate is GMT referred, you probably want this:
(don'f forget that the nowDate won't be the actual current system date-time, but it's "shifted", so if you will generate NSString using NSDateFormatter, you will see a wrong date)
NSDate* currentDate = [NSDate date];
NSTimeZone* currentTimeZone = [NSTimeZone timeZoneWithAbbreviation:#"GMT"];
NSTimeZone* nowTimeZone = [NSTimeZone systemTimeZone];
NSInteger currentGMTOffset = [currentTimeZone secondsFromGMTForDate:currentDate];
NSInteger nowGMTOffset = [nowTimeZone secondsFromGMTForDate:currentDate];
NSTimeInterval interval = nowGMTOffset - currentGMTOffset;
NSDate* nowDate = [[NSDate alloc] initWithTimeInterval:interval sinceDate:currentDate];
Every moment in time is the same moment in time everywhere around the world —- it is just expressed as different clock times in different timezones. Therefore, you can't change the date to some other date that represents the time in your timezone; you must use an NSDateFormatter that you feed with the timezone you are in. The resulting string is the moment in time expressed in the clock time of your position.
Do all needed calculations in GMT, and just use a formatter for displaying.
Worth reading
Does [NSDate date] return the local date and time?
Some useful resources for anyone coming to this more recently:
Apple date and time programming guide do read it if you're doing anything serious with dates and times.
https://developer.apple.com/library/content/documentation/Cocoa/Conceptual/DatesAndTimes/DatesAndTimes.html#//apple_ref/doc/uid/10000039i?language=objc
Useful category on NSDate with lots of utilities does allow a ~new~ date to be generated based on an existing date.
https://github.com/erica/NSDate-Extensions
There's also a swift version of the category
https://github.com/erica/SwiftDates
You need an NSDateFormatter and call stringFromDate this method to get a string of your date.
NSDateFormatter *dateformater = [[NSDateFormatter alloc] init];
[dateformater setDateFormat:#"yyyyMMdd,HH:mm"];
NSString *str = [dateformater stringFromDate: currentDateNTime];
use this method
-(NSDate *)convertDateToDate:(NSDate *) date
{
NSDateFormatter *formatter = [[[NSDateFormatter alloc] init] autorelease];
NSDate *nowDate = [[[NSDate alloc] init] autorelease];
[formatter setTimeZone:[NSTimeZone timeZoneForSecondsFromGMT:0]];
[formatter setDateFormat:#"yyyy-MM-d H:m:s"];
NSString * strdate = [formatter stringFromDate:date];
nowDate = [formatter dateFromString:strdate];
return nowDate;
}
this may return you what you want.
i hope you this may help you.

What's the best/easiest way to compare two times in Objective-C?

I've got a string representation of a time, like "11:13 AM." This was produced using an NSDateFormatter and the stringFromDate: method.
I'd like to compare this time to the current time, but when I use the dateFromString: method to turn the string back into a date, a year, month and day are added - which I don't want. I just need to know if right now is < or > the time stored in the string.
What's going to be the best way to handle that? Thanks in advance for your help.
Instead of using the string representation, use the NSDate you got from the picker. You can convert that hour/min/sec using NSDateComponents, then also convert [NSDate date] to NSDateComponents. Compare the hours/minutes/seconds of the two sets of components.
EDIT -- use a utility function for things like this that converts the hr/min/sec components of NSDate into a secondsOfTheDay (seconds since midnight).
You can directly use two time of day values since they are both seconds since midnight. Simple integers can be easily compared and stored and manipulated. You don't have to use NSDate all the time.
//----------------------------------------------------------------------------
// extracts hour/minutes/seconds from NSDate, converts to seconds since midnight
//----------------------------------------------------------------------------
unsigned secondOfTheDay( NSDate* time )
{
NSCalendar* curCalendar = [NSCalendar currentCalendar];
const unsigned units = NSHourCalendarUnit | NSMinuteCalendarUnit | NSSecondCalendarUnit;
NSDateComponents* comps = [curCalendar components:units fromDate:time];
int hour = [comps hour];
int min = [comps minute];
int sec = [comps second];
return ((hour * 60) + min) * 60 + sec;
}
If I understand the problem correctly, you’re using the dateFromString: method of NSDateFormatter. This is giving you the correct time, but with a default date of January 1, 1970, which is useless to compare against the current date/time.
This is easy to solve. Use setDefaultDate: to set the default date to today.
NSDate *now = [NSDate date];
NSDateFormatter *formatter = [[[NSDateFormatter alloc] init] autorelease];
[formatter setDateFormat:#"hh:mm a"];
[formatter setDefaultDate:now];
NSDate *theDate = [formatter dateFromString:#"11:13 AM"];
NSComparisonResult theResult = [theDate compare:now];
Can you reuse the string formatter that you used to create the string? So, let's say you created the string like this:
NSDateFormatter *formatter = [[[NSDateFormatter alloc] init];
[formatter setDateFormat:#"HH:mm a"];
NSString *dateAsString = [formatter stringFromDate:[NSDate date]];
You can get an NSDate like this:
NSDateFormatter *formatter = [[[NSDateFormatter alloc] init];
[formatter setDateFormat:#"HH:mm a"];
NSDate *date = [formatter dateFromString:dateAsString];
The day, month, year and timezone information will not be kept, but you'll have an NSDate object with the values of 1/1/1970 and GMT for the timezone offset.
At this point you can use the compare: (which is typically reserved for sorting operations) or the laterDate: or earlierDate: methods.
Be careful using NSDateFormatter like this, as you may run into issues with internationalization.
If you need to add information about the current date to the date you get from dateFromString:, such as the month day and year, you'll need to use NSCalendar's dateByAddingComponents:toDate:options: method.
If the string was originally created from an NSDate, then you'll want to use that original NSDate to compare against [NSDate date] using NSDate's compare: method (or some variant, such as earlierDate: or laterDate:).
You should use 24-hour based NSDateFormatter and compare as strings ("09:00am" > "08:00pm", but "09:00" < "20:00") . But in general it is right to operate with NSDate instances instead of strings