Как получить столбец datetime в SQLite с Objective C - PullRequest
4 голосов
/ 11 ноября 2009

Как получить столбец datetime в SQLite с Objective C?

У меня есть таблица с 4 полями: pk, datetime, value1 и value2. pk (первичный ключ), value1 и value2 являются целыми числами, поэтому я использую:

   int value1 = sqlite3_column_int(statement, 2);
   int value1 = sqlite3_column_int(statement, 3);

Но что я должен использовать для datetime?

Ответы [ 5 ]

13 голосов
/ 11 ноября 2009

В SQLite тип столбца даты / времени сам по себе отсутствует, поэтому в конечном итоге даты представляются в виде значений юлианских дат (реальные столбцы) или в виде строк (текстовые столбцы). SQLite также очень внимательно относится к тому, как даты представлены в строках: гггг-мм-дд чч: мм: сс (только).

Это некоторые методы, которые я написал для работы с датами SQLite из Objective-C. Эти методы реализованы в категории на NSDate.

Обязательно ознакомьтесь с функциональностью, которую SQLite предлагает для работы с юлианскими датами. Я обнаружил, что они весьма полезны (http://www.sqlite.org/lang_datefunc.html). Функция для получения julianDay NSDate включена в пример кода.

Похоже, эта тема также была здесь освещена. Сохранение дат до SQLite3 в приложении iPhone

+ (NSDate *) dateWithSQLiteRepresentation: (NSString *) myString;
{
    NSAssert3(myString, @"%s: %d; %s; Invalid argument. myString == nil",  __FILE__, __LINE__, __PRETTY_FUNCTION__);

    return [[self sqlLiteDateFormatter] dateFromString: myString];
}

+ (NSDate *) dateWithSQLiteRepresentation: (NSString *) myString timeZone: (NSString *) myTimeZone;
{
    NSString * dateWithTimezone = nil;
    NSDate * result = nil;

    NSAssert3(myString, @"%s: %d; %s; Invalid argument. myString == nil",  __FILE__, __LINE__, __PRETTY_FUNCTION__);
    NSAssert3(myTimeZone, @"%s: %d; %s; Invalid argument. myTimeZone == nil",  __FILE__, __LINE__, __PRETTY_FUNCTION__);

    dateWithTimezone = [[NSString alloc] initWithFormat: @"%@ %@", myString, myTimeZone];
    result = [[self sqlLiteDateFormatterWithTimezone] dateFromString: dateWithTimezone];
    [dateWithTimezone release];

    return result;
}

+ (NSString *) sqlLiteDateFormat;
{
    return @"yyyy-MM-dd HH:mm:ss";    
}

+ (NSString *) sqlLiteDateFormatWithTimeZone;
{
    static NSString * result = nil;

    if (!result) {
        result = [[NSString alloc] initWithFormat: @"%@ zzz", [self sqlLiteDateFormat]];
    }

    return result;    
}

+ (NSDateFormatter *) sqlLiteDateFormatter;
{
    static NSDateFormatter * _result = nil;

    if (!_result) {
        _result = [[NSDateFormatter alloc] init];
        [_result setDateFormat: [self sqlLiteDateFormat]];
    }

    return _result;
}

+ (NSDateFormatter *) sqlLiteDateFormatterWithTimezone;
{
    static NSDateFormatter * _result = nil;

    if (!_result) {
        _result = [[NSDateFormatter alloc] init];
        [_result setDateFormat: [self sqlLiteDateFormatWithTimeZone]];
    }

    return _result;
}


- (NSString *) sqlLiteDateRepresentation;
{
    NSString * result = nil;

    result = [[NSDate sqlLiteDateFormatter] stringFromDate: self];

    return result;
}

- (NSTimeInterval) unixTime;
{
    NSTimeInterval result = [self timeIntervalSince1970];

    return result;
}

#define SECONDS_PER_DAY 86400
#define JULIAN_DAY_OF_ZERO_UNIX_TIME 2440587.5
- (NSTimeInterval) julianDay;
{
    return [self unixTime]/SECONDS_PER_DAY + JULIAN_DAY_OF_ZERO_UNIX_TIME;
}

+ (NSDate *) dateWithJulianDay: (NSTimeInterval) myTimeInterval
{
    NSDate *result = [self dateWithTimeIntervalSince1970: (myTimeInterval - JULIAN_DAY_OF_ZERO_UNIX_TIME) * SECONDS_PER_DAY];

    return result;
}
3 голосов
/ 11 ноября 2009

Если вы можете определить базу данных, то вы также можете использовать REAL (тип данных SQLite) в качестве типа для даты и времени, а затем загрузить ее с sqlite3_column_double(). Это вернет переменную типа double.

Затем вы можете использовать [NSDate dateWithTimeIntervalSince1970:double_value], чтобы получить NSDate объект.

0 голосов
/ 13 мая 2012

Если вы просто хотите получить NSDate из поля даты и времени SQLite, где dateTime - это поле, возвращаемое из базы данных:

NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:@"yyyy-MM-dd HH:mm:ss"];
NSDate *date = [dateFormatter dateFromString:dateTime];
0 голосов
/ 06 апреля 2010

Обратите внимание, что решение категории выше имеет проблему в том, что оно зависит от региональных настроек на устройстве пользователя. Например, в полночь 5 апреля 2010 г. вышеприведенное sqlLiteDateRepresentation вернет 2010/04/05 00:00:00 для компьютеров большинства людей, однако я столкнулся со сценарием, в котором из-за пользовательских настроек языка одна и та же функция вызывала "2010/04/05 12:00:00 который при использовании в моем запросе не возвращает никаких строк. Кажется, это следует из документации NSDateFormatter: «В общем, вам рекомендуется использовать стили форматирования (см. TimeStyle, dateStyle и NSDateFormatterStyle) вместо использования пользовательских строк формата, поскольку формат для данного стиля отражает предпочтения пользователя. Формат стили также отражают настройку локали. " Хотя я не видел хорошего способа использовать timeStyle / dateStyle, чтобы получить тот же формат, что и yyyy / MM / dd HH: mm: ss, который, кажется, нужен SQLite. Боюсь, ваша лучшая ставка - это, скорее всего, нестандартное решение, в котором вы гарантированно записываете время в формате 24H, не позволяя настройкам локали вызывать ошибки.

0 голосов
/ 11 ноября 2009

Сейчас работаем!

NSString *dateValueS = [[NSString alloc] 
     initWithUTF8String:(char*) sqlite3_column_text(statement,2)];
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...