Formatting NSDate - objective-c

I am having some trouble comparing NSDate as they have a different format.
From one side I have a NSDate who looks like this:
2013-12-05T10:12:00.120Z
And from the other side I have another NSDate that looks this way:
2013-12-01 10:1200 +00000
My question is, how could I make the first NSDate look like the 2nd one?
And more important, what does 120Z mean? I guess it's the timezone, but I am not really sure of it.
By the way, is it there any way to can format the NSDate's and updating the time respecting the timezone hour difference?
Thanks a lot!
EDITED:
To get the 1st NSDate I do the following (I need to get the last opened date of a file):
MDItemRef item = MDItemCreate(NULL, (__bridge CFStringRef)filePath);
NSDate *date = (NSDate*)CFBridgingRelease(MDItemCopyAttribute(item,
kMDItemLastUsedDate));
And to get the 2nd NSDate I do the following:
NSDate* threeDaysAgo = [NSDate dateWithTimeIntervalSinceNow:-259200];

Convert both the dateStrings to NSDate and then you can easily compare the dateObjects.
For converting string to date thing you need :
NSDateFormatter
For comparing two dates :
resultant = [dateOne compare:dateTwo]
resultant can be NSOrderedAscending or NSOrderedSame or NSOrderedDescending.

You have a misunderstanding of what an NSDate is. It is not "in a format" at all, but is actually a wrapper around a a double which is the number of seconds since Jan 1st 1970 12:00am UTC. You can compare your two dates directly to see which one is the earlier. However, if you are trying to compare for equality, it's more tricky. If you want to see if they are within one minute of each other, you can do something like
[date1 timeIntervalSinceDate: date2] < 60.0;

Related

Remove time from NSDate object and save it in NSDate not in string?

There are lot of questions about date and time, but my question is a bit different.
Why NSDate comes with times added to it?
Why can not time be removed from NSDate? I can remove the time but it needs to be saved in String, Why it is not allowed to save it in NSDate?
NSDate actually stores a number of seconds from reference date (Jan 1, 2001). Everything rest are calendar calculations based on this amount of seconds. If you truncate time components and store result as 'NSDate' you will have different dates on different time zones.
You should consider using NSDateFormatter to convert NSDate values to string. Use:
[formatter setDateStyle:NSDateFormatterMediumStyle];
[formatter setTimeStyle:NSDateFormatterNoStyle];
to setup date formatter to ignore time.
Is this what you were looking for?
func dayOf(date: NSDate) -> NSDate {
return NSCalendar.currentCalendar().dateBySettingHour(0, minute: 0, second: 0, ofDate: date, options: NSCalendarOptions())!
}
A reusable way to solve this problem in swift is writing an extension on NSDate to trim the time off of the object.
import Foundation
extension NSDate {
func trimTime() -> NSDate {
let cal = NSCalendar(calendarIdentifier: NSCalendarIdentifierGregorian)!
let components = cal.components([.Day, .Month, .Year], fromDate: self)
return cal.dateFromComponents(components)!
}
}
This is not possible to remove TimeStamp from NSDate. NSDate is always packed with timestamp.
NSDate is based on the UTC time zone. If it is 1AM in US, it will be 12:30 PM in some other country and the date will be different. It will become trouble to get who entered when if different dates are there. So to make the date consistent timestamp-ing is required.
EDIT:
UTC update as suggested by Zaph :)
tiemstamp as suggested by Daij-Djan
NSDate is a presentation way of time stamp, you can get different date with different timezone of the same NSDate object, so you cannot just save the "date" part of NSDate object, that's not the way NSDate works.
If you don't want time present in date string, just format it without time.
My suggestion is save time stamp in your database, if you need to find certain date, use a range query, that way you can deal with timezone problem.
Timezone function is hard to implement with date field.

NSDateFormatter dateFromString returns incorrect date [duplicate]

This question already has answers here:
Get NSDate from NSDate adjusted with timezone
(2 answers)
Closed 9 years ago.
I am trying to use NSDateFormatter in my app which takes a date string and formats it to an NSDate so that I can do Date Comparisons, however I am finding when I use dateFromString and format it the date is losing one day.
NSString *dateString = #"02-06-2012";
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:#"dd-MM-yyyy"];
NSDate *dateFromString = [[NSDate alloc] init];
dateFromString = [dateFormatter dateFromString:dateString];
NSLog(#"My Date = %#", dateFromString);
[dateFormatter release];
This outputs to the console:
My Date = 2012-06-01 23:00:00 +0000
Try adding this lines to your code,
[dateFormatter setTimeZone:[NSTimeZone timeZoneWithAbbreviation:#"GMT+0:00"]];
or
[dateFormatter setTimeZone:[NSTimeZone timeZoneWithName:#"GMT"]];
SWIFT update :
Code from quetion,
let dateString = "02-06-2012"
var dateFormatter = NSDateFormatter()
dateFormatter.dateFormat = "dd-MM-yyyy"
var dateFromString : NSDate = dateFormatter.dateFromString(dateString)!
println("My Date \(dateFromString)")
And Solution ,
dateFormatter.timeZone = NSTimeZone(name: "GMT")
OR
dateFormatter.timeZone = NSTimeZone(abbreviation: "GMT+0:00")
I don't believe that Dhruv's answer is correct. In fact, it's not clear there's any problem at all. You just seem to have an incorrect expectation of what should happen and/or interpretation of what's happening.
NSDate represents a moment in time. This moment does not have one unique name. It will be known by different names in different places and under different naming systems (time zones, calendars). NSDate doesn't deal with any of this, except lamely in its -description method, where it has to produce a string representation of that moment.
Second, a string like "02-06-2012" doesn't specify a precise moment in time. First of all, it's just a date with no time information, so NSDateFormatter just defaults to the first moment for that date. Second, it doesn't specify the time zone. The first moment of the calendar day is a different moment in each time zone. Unless you specify a time zone with -setTimeZone: or the string itself carries time zone information, NSDateFormatter assumes that any date strings you ask it to parse are in the current time zone.
So, your dateFromString object represents the first moment of the specified date, 02-06-2012, in your time zone. I expect this is what you wanted. However, you then got confused by the way that NSDate describes itself when logged. As I said, NSDate has to pick some "name" (string representation) for the moment it represents and which name it picks is fairly arbitrary. These days it is picking the name that the moment is known by in UTC. I gather from the log output shown in your question that you are located at UTC+0100. So, the date may look like it's one day earlier but it really is the same moment you specified. In other words, "2012-06-01 23:00:00 +0000" and "2012-06-02 00:00:00 +0100" are two equivalent names for exactly the same moment in time. You just aren't used to seeing the first one and misinterpreted it.
The lesson is that you have to stop relying on NSDate's self-description to be in any particular time zone. Really, you have to not rely on anything about it, since it's not documented. In fact, the docs for -[NSDate description] state, "The representation is not guaranteed to remain constant across different releases of the operating system."
Dhruv's solution seems to help merely because it causes NSDateFormatter and -[NSDate description] to agree on the time zone. But that's unreliable. It wouldn't work on Snow Leopard, for example, because -[NSDate description] used the local time zone instead of UTC in that version of the frameworks.
More importantly, though, it alters the actual moment represented by the NSDate object you get from NSDateFormatter's interpretation of your date string. I suspect you really want that to have a specific meaning – you want the string to be interpreted as being in the local time zone – and his solution thwarts your intent.
tl;dr: you were getting the date you wanted all along; don't rely on -[NSDate description]; don't use Dhruv's solution

using NSDate to find the DATE from string

I am having problem finding date from string that is formatted using NSDateFormatter
Now, I am using this code:
NSDate *afterDate=[NSDate dateWithNaturalLanguageString:balanceDateAfter.stringValue];
This code returning date with GeorgianCalendar format but I want it in PersianCalendar.
I think if I use this code :
NSDate *afterDate=[NSDate dateWithNaturalLanguageString:balanceDateAfter.stringValue locale:];
It will return true date format but I don't know how can I use locale to set appropriate date formatter ( or my system locale ).
balanceDateAfter in above codes is an NSTextfield with NSDateFormatter.
NSDates do not have a calendar. An NSDate represents an absolute moment in time as defined by the difference between that moment and the first instant of 1st January 2001 in GMT. Basically, it's a positive or negative number of seconds, nothing more.
If you have an appropriate formatter assigned to the text field, you should get its value using -objectValue, not -stringValue. That way, you will be given the NSDate directly and you won't need to parse the string yourself.

Calculating time 90 minutes prior to due date/time in Objective C (iPhone app)

This is a completely noobish question, but I spent 2 hours yesterday trying to make it work, and I'm obviously missing something very basic.
What I need to do is take input from user of date/time and count back 90 minutes for an alert.
Could someone please post an example calculation, where you have a var that holds user input and a new var that receives the result of this computation? (all done in Objective C for use in an iPhone app) Thank you!
I suspect you could do something like:
NSDate *alertDate = [userDate dateByAddingTimeInterval:-5400.0];
I think this should work:
NSDate * alarmDate = [NSDate dateWithTimeInterval:5400 sinceDate:userDefinedDate];
NSDate * now = [NSDate date];
NSTimeInterval wait = [now timeIntervalSinceDate:alarmDate];
[self performSelector:#selector(callAlarm) withObject:nil afterDelay:fabs(wait)];
Although I do agree with Nick too, adding your work its much more productive..
Assuming you have a UIDatePicker, your target date will already be in an NSDate object. If it's coming from another source, you're probably ending up with it in an NSDate object, either from a string via an NSDateFormatter or by some other means.
From an NSDate object, you can get an NSTimeInterval relative to some absolute date. That's a C primitive type (it's a double in practice, but obviously don't code to depend on that) that you can do arithmetic directly on. So you can subtract 90 minutes directly from that. There are then various + dateWithTimeInterval... class methods on NSDate that will allow you to get a date from the result.

Unix timestamp is not getting converted correctly to NSDate

I have parsed an api which returns a unixtimestamp for last updated value. I am trying to convert it into NSDate. The code is below
NSDate *date = [NSDate dateWithTimeIntervalSince1970:[[[feedCount objectAtIndex:i] objectForKey:#"firstitemmsec"] intValue]];
NSLog(#"%#", date);
When I NSLog the date, I am getting date like this:
2038-01-19 03:14:07 +0000
The above date is obviously wrong
What is the mistake in the above code?
EDIT: my unixtimestamp is
"firstitemmsec":"1264396813500"
This value is obviously bigger for int. So how best can I handle this situation
Unix timestamps are in seconds, the value you have looks like a number of milliseconds since 1st January 1970. If you divide by 1000, you get 1264396813, which according to this converter is:
Mon, 25 Jan 2010 05:20:13 GMT
Check the value of [[[feedCount objectAtIndex:i] objectForKey:#"firstitemmsec"] intValue]--odds seem good that it's not a valid UNIX timestamp (okay, it is since any int value is on iOS, but obviously it's not the right value.)
I think there's another to do. Erase the "500" at the end of your number wich is an error code from the server and you have a right unix time ;)
There was probably an error or a bug on your server... ???