using NSDate to find the DATE from string - objective-c

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.

Related

How to return "UTC+XX:XX" or "UTC-XX:XX" format from NSDate

I would like to know if there is standard method that could return current timezone of the devise in format "UTC+XX:XX" or "UTC-XX:XX"?
Based on formatting NSDate i know that it is possible to get current time zone with help of "ZZZZ", that gives "GMT-08:00".
The question is if there is special formatting for NSDate that will give "UTC-08:00" ?
You could use yyyy-MM-dd'T'HH:mm:ss'UTC'ZZZZZ, i.e. a literal string UTC followed by ZZZZZ (-08:00).
Use NSDateFormatter, and set the time zone as part of configuring the formatter.

Formatting NSDate

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;

IOS6 Incorrect TimeZone while converting date from string to NSDate

My date is in the format
2013-07-16T07:40:36.939-04:00
When I convert it into a NSDate
the date is in the format IST or GMT +5:30 as I am in India. How should I make it use -4:00 as the timezone and display EST or PDT as per the number. if I use zzz, it returns GTM+5:30 and zzzz returns Indian Standard Time. This is my way
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:#"yyyy-MM-dd'T'HH:mm:ss.SSSzzz"];
NSDate *date = [dateFormatter dateFromString:strDate];
You need to set the formatted locale to en_US_POSIX to force it to use the supplied timezone instead of the system timezone:
[dateFormatter setLocale:[[NSLocale alloc] initWithLocaleIdentifier:#"en_US_POSIX"]];
You're parsing the date string correctly (in iOS 6 and later; this is not date format recognized in iOS 5 which recognizes -0400 or GMT-04:00, but not -04:00). Unfortunately, NSDate objects do not have a "time zone", so that information is not captured by the NSDateFormatter.
If you really want to capture the original timezone, I think you may have to manually parse the string for those last few characters (the -04:00), determine the timezone offset from that, and store this in a separate field and when outputting the date, use this separate time zone offset to set the timeZone property of your date formatter accordingly. Or if you really want to represent the original date, you could reformat this ISO8601 date string as human-friendly string and keep this pretty string (as well as the NSDate object, presumably).
BTW, splitting hairs, but you might want to be wary about assuming that -04:00 will represent EDT because (a) it depends upon the time of the year; and (b) there are other timezones that are also -04:00 (e.g. there are a bunch of South American timezones that are also -04:00).
Generally apps avoid this problem altogether by (a) converting the date strings to NSDate objects; and (b) output these NSDate objects using the timezone and locale of the device that the app is running on.

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.

nil result from NSDateFormatter with 0's in format string

I'm getting a date from a webservice back in the form MM00yyyy -- it is just the two-digit month, followed by two 0's, and then the four-digit year. When I do this:
NSString *expDate = #"12001975";
NSDateFormatter *dateFormat = [[NSDateFormatter alloc] init];
[dateFormat setDateFormat:#"MM00yyyy"];
NSDate postDate = [dateFormat dateFromString:expDate];
[dateFormat dateFromString] returns nil for some reason. I have also tried MMddyyyy, and MM'0''0'yyyy, with no success either way. I am converting a similar date, except the 0's are actually the day with no problem using the same method.
To get this working, I would just use the following pattern MMHHyyyy. Since you need only the date and not neccessarily the hour, the HH will use the 00 to set the time as zeroth hour and hence you will get the date that you are looking for. Again this is just a hack and a workaround only to solve your current problem.
Have a look at the Date Formatting Guide from Apple. The section "Use Format Strings to Specify Custom Formats" lists all the different standards the are supported by various iOS versions for specifying a format string. I would say that "00" is not allowed, so that is the reason why "MM00yyyy" is failing. Similarly, "MMddyyyy" is also failing because no day can be "00".
I don't know if you can have more luck with UNIX functions, as the Apple doc suggests:
For date and times in a fixed, unlocalized format, that are always guaranteed to use the same calendar, it may sometimes be easier and more efficient to use the standard C library functions strptime_l and strftime_l.
Be aware that the C library also has the idea of a current locale. To guarantee a fixed date format, you should pass NULL as the loc parameter of these routines. This causes them to use the POSIX locale (also known as the C locale), which is equivalent to Cocoa's en_US_POSIX locale, as illustrated in this example.
struct tm sometime;
const char *formatString = "%Y-%m-%d %H:%M:%S %z";
(void) strptime_l("2005-07-01 12:00:00 -0700", formatString, &sometime, NULL);
NSLog(#"NSDate is %#", [NSDate dateWithTimeIntervalSince1970: mktime(&sometime)]);
// Output: NSDate is 2005-07-01 12:00:00 -0700
Getting the format strings right seems much more like art than science. I suggest you make a new string without the 00 in it and then have your DateFromatter process that with "MMyyyy".
While this might not be the "correct" way to do it, it should solve your problem pretty quickly.
The zeros are unsupported symbols. Apple supports the following characters for date formatting: http://unicode.org/reports/tr35/tr35-10.html#Date_Format_Patterns See the day section.