Ibrahim Azhar Armar
Ibrahim Azhar Armar

Reputation: 25745

Format RFC3339 dates

I am receiving the following date in string format from the API

2015-04-18 06:08:28.000000

I want the date to be in the format of d/M/yyyy

I tried the following

NSString *datevalue = (NSString*)value;
NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
[formatter setDateFormat:@"d/M/yyyy"];
NSDate *date =  [formatter dateFromString:datevalue];
NSString *currentDate = [formatter stringFromDate:date];

This returns NIL, what could be the possible issue, or how do i format such dates in objective-c?

Thanks.

Upvotes: 1

Views: 2791

Answers (3)

Rob
Rob

Reputation: 437482

You should use the yyyy-MM-dd HH:mm:ss.SSSSSSS format string for the date formatter converting the API date into a NSDate object, as discussed by the others. But, you also want to consider the timeZone and locale properties of this formatter.

  • Usually RFC 3339 dates are exchanged in GMT. Confirm this with your API, but it's generally GMT/UTC/Zulu. If so, you will probably also want to explicitly set the timezone:

    formatter.timeZone = [NSTimeZone timeZoneForSecondsFromGMT:0];
    

    But confirm what timezone the API expects.

  • A more subtle issue is the handling users with non-Gregorian calendars

    formatter.locale = [[NSLocale alloc] initWithLocaleIdentifier:@"en_US_POSIX"];
    

For more information, see Apple Technical Q&A 1480.

Clearly, these dateFormat, timeZone, and locale properties are simply for converting the API date string into a NSDate object. When then outputting the date for the end user, you would use a separate formatter, defaulting to the standard timeZone and locale properties and use whatever dateFormat string you want for the output. (Frankly, I wouldn't generally advise using dateFormat string for user output formatters, but rather just use the appropriate values for the dateStyle and timeStyle properties.)

Upvotes: 1

Black Frog
Black Frog

Reputation: 11713

You cannot use the same formatter for read and writing the date string because they are the different. The format for your input date is incorrect.

// input string date: 2015-04-18 06:08:28.000000
// [formatter setDateFormat:@"d/M/yyyy"]; // incorrect
[formatter setDateFormat:@"yyyy-MM-dd HH:mm:ss.SSSSSS"]; 

Below is sample code

//
//  main.m
//  so29732496
//
//  Created on 4/19/15.
//

#import <Foundation/Foundation.h>

int main(int argc, const char * argv[]) {
    @autoreleasepool {
        NSLog(@"Hello, World!");

        NSString *dateStringFromAPI = @"2015-04-18 06:08:28.000000";
        NSString * const kAPIDateFormat = @"yyyy-MM-dd HH:mm:ss.SSSSSS";

        // convert API date string
        NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
        [formatter setDateFormat:kAPIDateFormat];
        NSDate *apiDate =  [formatter dateFromString:dateStringFromAPI];


        // now if I was output the api date to another format
        // I have to change the formatter
        [formatter setDateFormat:@"dd/M/yyyy"];
        NSString *currentDate = [formatter stringFromDate:apiDate];

        NSLog(@"Current Date: %@", currentDate);
    }
    return 0;
}

Upvotes: 1

dehlen
dehlen

Reputation: 7389

Just want to add to Black Frog's answer: As he stated you need different formatters for reading/writing.

However the right format should be :

[formatter setDateFormat:@"yyyy-MM-dd HH:mm:ss.SSSSSS"];

According to the apple documentation fractional seconds should be formatted with 'S'.

See here: NSDateFormat

Also here is an example to accomplish your task:

    NSString *datevalue = @"2015-04-18 06:08:28.000000";
    NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
    [formatter setDateFormat:@"yyyy-MM-dd HH:mm:ss.SSSSSS"];
    NSDate *date =  [formatter dateFromString:datevalue];
    [formatter setDateFormat:@"dd/MM/yyyy"];
    NSString *currentDate = [formatter stringFromDate:date];

    NSLog(@"%@",date);
    NSLog(@"%@",currentDate);

Upvotes: 1

Related Questions