NSDate formatting for some date is not the valid date - ios

currently I have a piece of code that is converting a set of string (eg. 900130) keyed in by user to a date using yyMMdd(Malaysia IC) format. My code for converting the string as follows:
NSDateFormatter *dateFormat = [[NSDateFormatter alloc] init];
[dateFormat setDateFormat:#"yyMMdd"];
date = [dateFormat dateFromString:temp]; // temp = string key in by user
The problem didn't occur to me when I was running some test, but when I gave it to someone else to test it, the problem occur where the string 490130 which should be converted to 30/1/1949 was converting it to 30/1/2049.
How do I convert 490130 to 30/1/1949 instead of 30/1/2049

NSDateFormatter assumes 20xx for a 2-digit year if the year is less than 50 and 19xx for a 2-digit year if the year is greater than 50. I forget which it assumes when the year is 50.
It seems you want a cutoff different from 50. There is no built-in support for using a different cutoff.
One option is to look at the first two characters and see if it is below or after your cutoff. Then prepend either 19 or 20 to the start of the string as needed. Then parse the string using yyyyMMdd.

Related

Conversion: NSString to NSDate

This is a really common question, but mine might be unique since I have long decimal places for the seconds.
NSString *timestamp = #"2015-11-06 15:27:34.0000000";
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:#"yyyy-MM-dd'T'HH:mm:ss zzz"];
NSDate *capturedStartDate = [dateFormatter dateFromString: timestamp];
My capturedStartDate is null.
For the date format, I've tried replacing zzz with Z, a, and removing it completely. I've also tried with and without the 'T'. Does someone know the correct format to retrieve this date from the string?
Your date string doesn't have a time zone in it, so you should remove that Z. Also, you have fractions of a second, too. And there's no T in the date string. So you want
yyyy-MM-dd HH:mm:ss.SSSSSS
This does beg the question as to what time zone that string represents. If it is UTC, you'll want to set the time zone of the formatter, accordingly.
Likewise, you might want to be careful about users with non-Gregorian calendars. See Apple Technical Q&A 1480 regarding setting the locale to en_US_POSIX.

Long Date (UNIX Date) issues

The problem is as follows :
Quick details of the app : Sorting of data (ascending) according to the date.
The UNIX date / long date from the web service in form of JSON (is of 13 digits). When the long date is parsed, I get an invalid value of the date.
Long date : 1428498595000
Converted date : Sun, 26 Apr 47237 13:16:40 (After parsing)
[Notice the year]
When the online converter is used (example) : http://www.onlineconversion.com/unix_time.htm , the same output is reproduced.
My purpose is to get the dates sorted in ascending order, but unfortunately, as the year is shown irrelevant, it makes sorting impossible.
Long date 1428498595 (After manually removing three zeros to test it on the website) : Wed, 08 Apr 2015 13:09:55 GMT (This is the correct date that needs to be shown)
Can anyone help me understand what can be done so that we could manually remove the last three zeros?
[Storing the parsed data in SQLite and then producing the stored data in UITableView]
This is in AppDelegate
+(NSString * )convertUnixTime_to_SytemTime :(NSTimeInterval )timeInterval
{
NSDate * convertedDate = [NSDate dateWithTimeIntervalSince1970:timeInterval];
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
dateFormatter.dateFormat = #"YYYY-MM-DD";
NSTimeZone *localTime = [NSTimeZone systemTimeZone];
[dateFormatter setTimeZone:localTime];
NSString *timeStamp = [dateFormatter stringFromDate:convertedDate];
return timeStamp;
}
This is in the code
data.News_LastModifiedDate = [AppDelegate convertUnixTime_to_SytemTime:[[subcomponents objectAtIndex:2] doubleValue]];
Thanks much in advance.
The date/time is in milliseconds since UNIX epoch, instead of seconds. You can divide by 1000.0 in order to keep the fractional seconds (if they ever appear):
NSTimeInterval seconds = (NSTimeInterval)1428498595000 / 1000.0;
EDIT. To address other aspects of your question:
Storing the parsed data in SQLite and then producing the stored data
in UITableView
Store it as is; as a 64-bit int.
+(NSString * )convertUnixTime_to_SytemTime :(NSTimeInterval )timeInterval
This method doesn't convert the UNIX time to system time; it formats the date into a string (wrongly by the look of it). Forget it and use just the first line of code only:
NSDate * convertedDate = [NSDate dateWithTimeIntervalSince1970:timeInterval];
Where timeInterval is the original number converted to seconds as above. The only time you want the date as a string is during presentation, not during processing.
Your timestamp is in Milliseconds. Simply divide it by 1000 to get the correct date/time.
data.News_LastModifiedDate = [AppDelegate convertUnixTime_to_SytemTime:[[subcomponents objectAtIndex:2] doubleValue]/1000];
Should work for you.
Whenever you read JSON data, there should be an API description that tells you what data is delivered in which form. You would read the API description and do whatever needs doing. If there is no API description, you do whatever you can.
When you read a date from JSON data, you should as the first step convert whatever you find to an NSDate*. JSON has no built-in date type. It has a standard format for dates, using RFC3339, but your JSON doesn't do that. Apparently it uses UTC in milliseconds since 1970, stored as an integer. The JSON parser would return this as an NSNumber. That's fortunately quite easy to handle:
NSNumber* dateAsNumber = "whatever is needed to extract the integer";
NSTimeInterval dateAsInterval = [dateAsNumber doubleValue] / 1000;
NSDate* dateAsDate = [NSDate dateWithTimeIntervalSince1970: dateAsInterval];
You shouldn't convert NSDate to anything else. NSDate is the standard type for handling dates on iOS. CoreData will handle it. If you use SQL directly, convert it just before storing to the database and after loading from the database and use NSDate everywhere else.
BTW. What is SystemTime? If you use a method name like convertUnixTime_to_SytemTime, I get very worried, because no two people will ever agree what system time is. And your method doesn't return a system time, it returns something converted to a string.

DateFormatter to convert date

I am getting date in millisecond from server:
dob = 1344364200000;
I am converting it into date and I got :
2012-08-07 18:29:20 +0000
When I set this date to date picker It is showing me August-7-2012
This is my dateformater:
df = [[NSDateFormatter alloc] init];
[df setDateFormat:#"MMMM-dd-yyyy"];
And server side date is August-8-2012...
If your server and the client are located in different time zones, there will be time difference which could result in the server and client showing different dates. Convert all date times to UTC before communication (from server to client as well as client to server) and adjust according to local timezone before displaying the date time.
I got solution. There was logical mistake to convert millisecond into date. To convert millisecond to second I have taken float variable to store second and taken double variable to store millisecond from server that's why it was giving me difference of 40 second in actual date and converted date. Then I took both variable in double and problem solved...

NSDateFormatter: stringFromDate and dateFromString not reversible?

I'm having problems using a custom date formatter with NSDateFormatter to convert a string into a date. Here's a short example that creates a string from today's date but fails to convert this back to an NSDate:
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:#"Mdyyyy"];
NSString *example = [dateFormatter stringFromDate:now]; // e.g., 10292013
NSDate *reverse = [dateFormatter dateFromString:example]; // nil?
So basically it seems that NSDateFormatter is creating a date string that it itself can't turn back into a NSDate using the same format that created the string.
Using MMddyyyy as the date string works, although I can't see from the documentation (which conveniently only goes up to iOS 6.0) why it would matter:
month M 1..2 09 Month - Use one or two for the numerical month, ....
...
day d 1..2 1 Date - Day of the month
The reason why I'm trying to use Mdyyyy instead of MMddyyyy is because it's closer to what NSDateFormatterShortStyle returns for my current NSLocale (M/d/yy).
Perhaps someone might have some insight here as two what I'm doing wrong, or if I'm wrong in my understanding of how this should work. (I know there are a lot of questions here regarding NSDateFormatter, but I didn't find one that fits my problem.)
Mdyyyy is ambiguous as a string ->date mapping. One cannot tell if "1112013" is Jan 11 or November 1. Hence NSDateFormatter will not allow it for string ->date.

SQLIte compare datetime

What is the easiest way in ios app to compare datetime string in sqlite3.
I store the datetime string in following way.
NSDateFormatter* df=[[NSDateFormatter alloc] init];
[df setDateFormat:#"yyyy-MM-dd HH:mm"];
NSString* dtString=[df stringFromDate:[NSDate date]];
then I'm inserting dtString into the table. So after i want to retrieve all rows for example only for last two days.
sqlite3 doesn't contain a DATETIME type so you need to think of ways of encoding it.
If you want to use the date column in a WHERE clause then you could store the time_t returned from gmtime(time(NULL)) (i.e. the time now, since UNIX epoch) and then use some simple clause to get those rows:
... WHERE date >= ?
And binding that ? to gmtime(time(NULL)) - 60**60*24*2
EDIT: If you want to stay completely in Objective-C, then the same date value can be determined from an NSDate object using:
(time_t)[date timeIntervalSince1970]

Resources