Create a gist now

Instantly share code, notes, and snippets.

What would you like to do?
Compare the date parsing performance of NSDateFormatter against SQLite's date parser for parsing an iOS 8601 date.
#import <Foundation/Foundation.h>
#import "sqlite3.h"
typedef int64_t timestamp;
NSUInteger randomNumberInRange(NSUInteger start, NSUInteger end);
// Create a sample date using the ISO-8601 format.
// 2013-04-23T16:29:05Z
NSString* generateSampleDate();
// Create an array of <count> dates in the ISO-8601 format.
NSArray* generateSampleDates(NSUInteger count);
// Parse all given dates using SQLite's strftime function
void parseDatesUsingSQLite(NSArray *dates);
// Parse all given dates using NSDateFormatter
void parseDatesUsingNSDateFormatter(NSArray *dates);
static NSDateFormatter *dateFormatter = nil;
int main()
{
@autoreleasepool
{
const NSUInteger count = 1000000;
NSArray *dates = generateSampleDates(count);
NSDate *start = nil;
NSDate *end = nil;
start = [NSDate date];
parseDatesUsingNSDateFormatter(dates);
end = [NSDate date];
printf("NSDateFormatter took %4.3f seconds\n", [end timeIntervalSinceDate:start]);
start = [NSDate date];
parseDatesUsingSQLite(dates);
end = [NSDate date];
printf("sqlite3 took %4.3f seconds\n", [end timeIntervalSinceDate:start]);
}
return 0;
}
NSArray* generateSampleDates(NSUInteger count)
{
NSMutableArray *dates = [NSMutableArray array];
for (int i = 0; i < count; i++)
{
[dates addObject:generateSampleDate()];
}
return dates;
}
NSString* generateSampleDate()
{
NSUInteger year = randomNumberInRange(1980, 2013);
NSUInteger month = randomNumberInRange(1, 12);
NSUInteger date = randomNumberInRange(1, 28);
NSUInteger hour = randomNumberInRange(0, 23);
NSUInteger minute = randomNumberInRange(0, 59);
NSUInteger second = randomNumberInRange(0, 59);
NSString *dateString = [NSString stringWithFormat:@"%lu-%02lu-%02luT%02lu:%02lu:%02luZ",
year,
month,
date,
hour,
minute,
second
];
return dateString;
}
void parseDatesUsingSQLite(NSArray *dates)
{
sqlite3 *db = NULL;
sqlite3_open(":memory:", &db);
sqlite3_stmt *statement = NULL;
sqlite3_prepare_v2(db, "SELECT strftime('%s', ?);", -1, &statement, NULL);
for (NSString *dateString in dates)
{
sqlite3_bind_text(statement, 1, [dateString UTF8String], -1, SQLITE_STATIC);
sqlite3_step(statement);
timestamp value = sqlite3_column_int64(statement, 0);
NSDate *date = [NSDate dateWithTimeIntervalSince1970:value];
sqlite3_clear_bindings(statement);
sqlite3_reset(statement);
}
}
void parseDatesUsingNSDateFormatter(NSArray *dates)
{
if (dateFormatter == nil)
{
dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:@"yyyy-MM-dd'T'HH:mm:ss'Z'"];
[dateFormatter setTimeZone:[NSTimeZone timeZoneForSecondsFromGMT:0]];
}
for (NSString *dateString in dates)
{
NSDate *date = [dateFormatter dateFromString:dateString];
}
}
NSUInteger randomNumberInRange(NSUInteger start, NSUInteger end)
{
NSUInteger span = end - start;
return start + arc4random_uniform(span);
}
@shankartshinde

This comment has been minimized.

Show comment Hide comment
@shankartshinde

shankartshinde Jun 26, 2015

Hi Anurag,
I have gone through your demo example code,
With few veriation i have made changes but it now working some how this return "SQL Date:1970-01-01 00:00:00 +0000"
Problem1
date:2015-06-26 06:43:41 +0000 dateFormat:MMM dd, yyyy hh:mm a
Result date:Jun 26, 2015 12:13 PM

i have made changes in the code

void parseDatesUsingSQLite()
{

    NSString *dateString = @"2015-06-26 06:43:41 +0000";
    sqlite3 *db = NULL;
    sqlite3_open(":memory:", &db);

    sqlite3_stmt *statement = NULL;
    sqlite3_prepare_v2(db, "SELECT strftime('%b %d, %Y %r %Z');", -1, &statement, NULL);

//    for (NSString *dateString in dates)
//    {
        sqlite3_bind_text(statement, 1, [dateString UTF8String], -1, SQLITE_STATIC);
        sqlite3_step(statement);
        timestamp value = sqlite3_column_int64(statement, 0);
        NSDate *date = [NSDate dateWithTimeIntervalSince1970:value];
        NSLog(@"SQL Date:%@",date); // return as "1970-01-01 00:00:00 +0000"
        sqlite3_clear_bindings(statement);
        sqlite3_reset(statement);
//    }
}

Problem2
timeZone:GMT date:2015-06-26 06:45:19 +0000 dateFormat:yyyy-MM-dd HH:mm:ss
Result date:2015-06-26 06:45:19

How to pass timezone to SQLite API and convert input time string to resultant date?
Please help

Hi Anurag,
I have gone through your demo example code,
With few veriation i have made changes but it now working some how this return "SQL Date:1970-01-01 00:00:00 +0000"
Problem1
date:2015-06-26 06:43:41 +0000 dateFormat:MMM dd, yyyy hh:mm a
Result date:Jun 26, 2015 12:13 PM

i have made changes in the code

void parseDatesUsingSQLite()
{

    NSString *dateString = @"2015-06-26 06:43:41 +0000";
    sqlite3 *db = NULL;
    sqlite3_open(":memory:", &db);

    sqlite3_stmt *statement = NULL;
    sqlite3_prepare_v2(db, "SELECT strftime('%b %d, %Y %r %Z');", -1, &statement, NULL);

//    for (NSString *dateString in dates)
//    {
        sqlite3_bind_text(statement, 1, [dateString UTF8String], -1, SQLITE_STATIC);
        sqlite3_step(statement);
        timestamp value = sqlite3_column_int64(statement, 0);
        NSDate *date = [NSDate dateWithTimeIntervalSince1970:value];
        NSLog(@"SQL Date:%@",date); // return as "1970-01-01 00:00:00 +0000"
        sqlite3_clear_bindings(statement);
        sqlite3_reset(statement);
//    }
}

Problem2
timeZone:GMT date:2015-06-26 06:45:19 +0000 dateFormat:yyyy-MM-dd HH:mm:ss
Result date:2015-06-26 06:45:19

How to pass timezone to SQLite API and convert input time string to resultant date?
Please help

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment