Pull to refresh

Comments 12

Не легче.

На самом деле, нет разницы как хранить даты. Проблема заключалась в том, что SQLite не учитывает локаль при работе с Week Based Calendar

В самой статье я кратко описывал выгоды используемого подхода. Остановлюсь на них более подробно.
Выгоды такого решения очевидны:
  • мы остаемся в рамках SQL --> более краткий и понятный код в декларативном стиле
  • не нужно писать лишние циклы на Objective-C --> меньше кода — меньше багов
  • мы получим потенциально более быстрое исполнение запросов --> форматирование дат в коде означает еще один проход по полученному DataSet
  • И самое главное — это решение рассчитано на повторное использование --> не нужно вставлять подобные циклы после каждого запроса, требующего Calendar Computations

Не могу с вами согалситься про то что нет разницы, хранить данные как строки и каждый раз их парсить добавляет дополнительные накладные рассходы. Если хранить данные в INTEGER то стандартные ф-ии работы с временем будут отлично работать. Я не специалист в разработке под iphone, но я уверен что есть стандартные объекты для этого. После этого можно пользоваться стандартными методамаи вывода времени с учетом локальных особенностей.
NSDate который вы используете:
– timeIntervalSince1970
– initWithTimeIntervalSince1970
как раз для этих целей.
Насколько я понял, ваша идея сводится к
SELECT Date, Value, Visits,
FROM Usage
WHERE Date BETWEEN @startDate AND @endDate;


* This source code was highlighted with Source Code Highlighter.


С последующей ручной обработкой дат и агрегацией в ObjectiveC коде. Я считаю данный подход в корне неверным. «Как раз для этих целей» — это SQL.

Свои аргументы я привел уже дважды — в самой статье и предыдущем комментарии. У меня складывается впечатление, что вы не потрудились с ними ознакомиться.
Нет, я не предлагаю делать это в ручную, я говорю о том что в SQLite есть 3 метода хранения дат и использование строк для представления дат не лучший выбор. Куда лучше REAL или INTEGER. Если вам надо сгруппировать что-то по неделям то нет ничего проще, так же можно высчитать какая неделя у даты, если вам надо в зависимости от того в какой Locale используется приложение то можно получить первый день недели и использовать это как adjustment
SELECT ((Date — @FirstDayaOfWeek00hours00minute00seconds) / SecondsInWeek) as Week GROUP BY week ORDER by Week
Спасибо. Я наконец-то понял вашу идею.
При необходимости учту при дальнейших оптимизациях.

Кроме того, колонку дат можно проиндексировать. Это также должно несколько ускорить выборки.

P.S. опять-таки, лучше не работать напрямую с ticks, а с датами
strftime( '%Y-%W', Date, '-@FirstDayaOfWeek day' ) AS Week


Больше вероятность того что авторы SQLite/Foundation.framework учли хитрости week based calendar за вас (см. следующий комментарий)
Работа с интервалами дат напрямую — очень трудная задача. Самостоятельно этим заниматься не стоит если имеется такая возможность.

Если у вас есть знакомые «специалисты в разработке под iphone» — посмотрите с ними
WWDC 2011 — 117performing_calendar_calculations.
Там очень хорошо описаны нюансы работы с датами и локализациями.
работа с интервалами сложная задача если есть временные зоны и високосные года. Номер недели никак не зависит от этого, храните всё в UTC, FirstDayaOfWeek00hours00minute00seconds будет adjustment который будет всё учитывать.
Номер недели никак не зависит от этого


Принадлежность недели к тому или иному году определяется законодательно для каждой страны. И посему зависит от локали. Правила порой бывают гораздо хитрее, нежели вычитание одного дня.

Подробнее можно прочитать на excel.blox.ua либо www.cpearson.com
1. Имелось в виду что способ хранения дат не критичен для данной задачи. Стандартные функции SQLite все равно не смогут обработать их с учетом заданной локали.
Если вам известен способ задавать локаль SQLite — пожалуйста, опишите его.

2. Вопросы оптимизации остались за пределами данной статьи. К ним относятся построение индексов, выбор способа хранения дат, детали реализации ObjcFormatAnsiDateUsingLocale.

3. Извольте показать правильный с вашей точки зрения запрос «CREATE TABLE»
1. я не говорю что ваше решение не будет работать, я просто говорю что можно всё проще сделать без использования callbacks которые будут вызываться каждый раз для каждой записи и работать со строками.

2. я это понял

3.
CREATE TABLE [Usage]
(
[FacetId] VARCHAR, — «исполнитель»
[Value ] INTEGER, — полезная «работа»
[Visits ] INTEGER, — затраченная «работа»
[Date ] INTEGER — дата
);
или

CREATE TABLE [Usage]
(
[FacetId] VARCHAR, — «исполнитель»
[Value ] INTEGER, — полезная «работа»
[Visits ] INTEGER, — затраченная «работа»
[Date ] REAL — дата
);
Sign up to leave a comment.

Articles