NSDateFormatter zeroing minutes - ios

When converting a date string for the server into a NSDate - which is in this format
2012-09-07T11:57:44+10:00
we're using this dateFormat in NSDateFormatter
yyyy-MM-dd'T'HH:mm:ssZZZ':'mm
but the minutes are always zero minutes.

The second "mm" overwrites the result of the first and sets minutes to zero, having parsed the "00" on the end of the timezone.
In order to parse that format of timestamp you must first somehow remove the last : character, as NSDateFormater cannot handle that.

Related

Format date with 7 fractional seconds

I have the need of parsing a date that looks like this:
"2018-03-08T17:37:09.2694781-00:00"
Notice the fractional seconds, I need to keep all 7 digits because then I need to send back to my server exactly the same date.
So, I need to be able to convert that string to Date, do some stuff and then send it back to another server thus converting that Date back to String again and keeping the same format and fractional seconds, keeping the original date as String is not an option here.
I already tried this but it does not work because the original Date/Time gets modified for some unknown reason
let formatter = DateFormatter()
formatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss.Axxx"
let dateObj = formatter.date(from:("2018-03-08T17:37:09.2694781-00:00"))
//This produces: "2018-03-08 00:44:54 UTC", nothing to do with the original date, it would be fine if converted to UTC, though
I also tried a formatter like
formatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss.SSSSSSSZZZZZ"
But that truncates my fractional seconds to 3 digits.

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...

NSDate fixing timezones

I know that NSDate doesn't have timezone information.
However, I'm trying to understand how to manipulate them properly.
At the moment I'm passing a date into an object. That date is the user selected date at time 00:00:00.
i.e. if the user hits October 21st then the NSDate passed in should be. 21/10/2013 00:00:00.
However, it isn't it's 20/10/2013 23:00:00. (One hour before).
Now, this is nothing about formatting them or displaying them. I'm just using the NSDates.
I'm creating the date using NSDateComponents and NSCalendar.
I guess my question is...
How can I tell what date an NSDate is actually referring to in my local time zone?
I need to send a UNIX time stamp for 00:00:00 and 23:59:59 for a given date. However, at the moment when I set the hour, minute and second to 0, 0 and 0 then I'm not getting midnight in the current time zone I'm getting midnight in GMT.
This isn't what I want.
Fixed?
OK, I've fixed it... I think. At least, it's doing what I want it to do.
The trick is...
NSTimeZone *timeZone = [NSTimeZone localTimeZone];
[dateComponents setSecond:timeZone.secondsFromGMT];
I've been confused by this many times. When you NSLog an NSDate, you'll always get the output in GMT. So the 20/10/2013 23:00:00 (GMT) you're seeing is the same as your expected 21/10/2013 00:00:00 (BST). The UNIX timestamp for both of these dates would be the same because it doesn't take into account timezone - it's always UTC.
If you want to output in a user-readable format, an NSDateFormatter will format the date using your current timezone and locale.

MagicalRecord date parsing

I've got a date in the following format:
2013-05-04T05:07:09+00:00
I'm using MagicalRecord to map the NSDate automatically. As far as I can see the above date format should comply with MagicalRecord's default date format: yyyy-MM-dd'T'HH:mm:ss'Z'.
I have tried with a custom dateFormat entry in the attribute's user info (see this article):
yyyy-MM-ddTHH:mm:ss+Z, yyyy-MM-dd T HH:mm:ss Z, yyyy-MM-dd'T'HH:mm:ss'+'Z
but none of them work in order to have it parse the date properly and it always returns nil regardless of setting a custom dateFormat or using MagicalRecord's default format.
Let's look at your string:
2013-05-04T05:07:09+00:00
This is:
four digit year
hyphen
zero-padded month
hyphen
zero-padded day of month
'T' character
zero-padded hour
':' character
zero-padded minute
':' character
zero-padded second
timezone (with direction from GMT and a separating colon)
Thus, according to the date format specifiers documentation, the pattern you'd want is:
yyyy-MM-dd'T'HH:mm:ssZZZZZ
Also, be sure to use the en_US_POSIX locale with the NSDateFormatter.

Resources