Re[3]: DateTime.MinValue или null?
От: Ocelot  
Дата: 24.11.10 02:24
Оценка:
Здравствуйте, WolfHound, Вы писали:

WH>Единственно верный способ реализовать DateTime это зафиксировать некую точку во времени.

WH>Например 01.01.2000 00:00:00 UTC+0
WH>Или любую другую по вкусу.
WH>И отсчитывать от этой точки колличество наносекунд.
WH>Если больше 0 то дата после нашего начала времен. Если меньше то до.
WH>А преобразование в строку и обратно должен делать объект календарь который уже будет учитывать всякие там часовые пояса, весокосные года, прыгающие секунды и что там еще есть...

Ну тогда уж хотя бы так: "Зафиксировать некоторый момент времени и пространстве, выраженный в фиксированном календарном представлении" Потому что UTC+0 в вашей записи это отсылка именно к определенному часовому поясу (а это все-таки по смыслу пространственная характеристика http://en.wikipedia.org/wiki/Time_zone), а сама дата задана вполне определенным образом (рискну предположить, что по Григорианскому календарю ).
Вам не кажется, что это само по себе может быть проблемой — пытаться сделать календарь надстройкой над более абстрактным понятием "дата", уже используя некий календарь для ее определения?
Ну и самое главное, осталось договориться, что же наша дата будет отсчитывать, какое время. Астрономическое? Атомное? Или еще какое-нибудь?
Оно, конечно, в подавляющем большинстве случаев GMT==UTC. Но не всегда, отнюдь не всегда. Отсюда и детали, а в них, как известно, дьявол.
Re[2]: DateTime.MinValue или null?
От: Ocelot  
Дата: 24.11.10 02:57
Оценка:
Здравствуйте, alexzz, Вы писали:

M>>Есть фильтр, где юзер вбивает даты начала и окончания для поиска.

M>>Если юзер не вбил любую или обе из дат, то интервал открыт для поиска.

M>>Вот что по вашему лучше передавать в качестве даты в данном случае DateTime.MinValue или null?


A>1. Пользователь хочет искать что-то от начала времён до дня Д.


Ну извините, это совершенно разные вещи.
В начальном условии ("интервал открыт для поиска") подразумевается наличие только верхней границы (date < end_date). Если использовать DateTime.MinValue, то поиск будет идти по верхней и нижней границе (date < end_date && date > DateTime.MinValue), что, как вам уже показали, далеко не одно и то же.
Но так хоть нижняя граница задана явно, а вот ваше "от начала времён" подразумевает поиск по нижней границе, определяемой из контекста. То есть вообще не ведомо какой. Потому что "начало времен" это не какая-нибудь конкретная дата, в нее любой смысл можно вложить. У вас одно "начало времен", у кого-то совсем другое.

Но это уже так, мелочи Главное, что поиск по одному условию вы предлагаете заменить на поиск по двум. Ну хорошо, допустим, "начало времен" это начало нашей эры, 1 января 1 года, 00:00. Угадайте, что посчитает ваш запрос, если, скажем, задать день Д = 00:00 1 января 1 года до нашей эры?
Re[3]: DateTime.MinValue или null?
От: Sinclair Россия https://github.com/evilguest/
Дата: 02.12.10 13:31
Оценка:
Здравствуйте, _FRED_, Вы писали:

_FR>Только вот в запросе, например, всё равно удобней пользоваться максимумом\минимум:

_FR>
_FR>WHERE [Created] BETWEEN ISNULL(@CreatedFrom, '1753-01-01 00:00:00')
_FR>                    AND ISNULL(@CreatedTo, '9999-12-31 23:59:59');
_FR>


_FR> Но передавать надо, конечно же, null.

Не уверен, что это хорошая идея.
1. Не всякий оптимизатор догадается выполнить IsNull единожды. Так что есть риск внезапно отказаться от использования индекса.
2. Даже если оптимизатор догадается выполнить constant propagation до начала выполнения, крайне маловероятно, что он сможет верно оценить селективность. То есть, если бы мы совсем выкинули этот оператор сравнения, то оптимизатор мог рассмотреть какие-нибудь более удачные индексы. Я имею в виду — в случае чуть более сложного запроса, конечно же.
В плохом случае у нас есть некий view, построенный при помощи star-join из кучи таблиц. И возможность пользователя фильтровать по произвольному количеству из этих полей. Если в реальности как правило в каждом поиске используется всего лишь пара полей, то значительно эффективнее строить запрос только с их участием. Запрос с where ((x = @x) or (@x is null)) AND ... AND ... AND ... с очень большой вероятностью свалится в table scan при любом наборе входных аргументов.

Поэтому настоящие джыдаи, конечно же, строят запрос динамически.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[8]: DateTime.MinValue или null?
От: Sinclair Россия https://github.com/evilguest/
Дата: 02.12.10 13:47
Оценка:
Здравствуйте, vdimas, Вы писали:
V>Это просто флаг, семантика использования которого зависит от добросовестности программиста.
Боюсь, что его вообще невозможно использовать корректно — независимо от добросовестности.
Вот я зарегистрировал момент входа пользователя в программу — DateTime1.
Вот пользователь перевёл часовой пояс.
Вот я пытаюсь вычислить длительность сессии через Now() — DateTime1. Упс! Оказывается, что смысл Local для этих дат совершенно различен. Рекомендую посмотреть на реакцию хистори в Скайпе при переключениях часового пояса — на предмет понимания того, как делать не надо.

V>Локально — это означает локальный ввод-вывод, и вычисления, привязанные к локальным моментам времени, не более того. В этом плане Wolfhound прав (с поправками от оппонентов).

V>Никакому пользователю не нужен UTC, разумеется, вот и используйте DateTime только для локального ввода-вывода.
Современному пользователю нужна возможность оперировать глобальными датами. Пример со скайпом я только что привёл. И это ещё одно из наиболее осведомлённых о часовых поясах приложениями.
S>>Вот это мне кажется, мягко говоря, преувеличением. Календарь — это математическая абстракция. Ничего блокировать ему не надо. А часовой пояс на чтение не должен как-то очень сильно напрягать систему.
V>Как это не должен? Из любой другой программы тебе поменяют часовой пояс, и он у тебя должен тут же "подхватиться" в твоей программе. Никаких кеширований для доступа только по чтению календаря и часового пояса быть не может.
Не вижу никакой проблемы. Во-первых, часовой пояс в такой архитектуре начинает играть роль только, грубо говоря, в момент преобразования даты в строку. Сами даты внутри представляются в UTC, что позволяет игнорировать все прыжки часового пояса. Это раз.
Далее, мы имеем, к примеру, похожую ситуацию с числами. Вот я меняю себе десятичный разделитель, и все 143 запущенных программы мгновенно на это реагируют. Хотя никто из них не занимается ерундой типа хранения чисел с признаком "IsLocal". Надо полагать, блокировки интернационализации не так дорого обходятся.

V>Если бы вся ОС была управляемой с GC, то для доступа по чтению действительно блокировки были бы не нужны, при условии атомарного чтения ссылки на объект и принятом соглашении, что при изменении . А т.к. ось нативная, то равнозначно блокируются операции чтения и записи ресурса.

Этот пассаж мне вообще непонятен. Ось есть ось. Методы доступа к TimeZoneInfo существуют; реализовать эффективный ReaderWriterLock там ничего не стоит. В дотнете есть вполне себе эффективная инфраструктура работы с интернационализацией. То, что при каждом вызове int.ToString(), неявно подхватывается информация о текущей локали, никого не останавливает.

V>Ну так я ключевое и показал — это implicit операторы приведения типа.

Не понимаю. Как будет выглядеть op_implicit для DateTime -> SensibleDateTime? В обратную-то сторону всё и так понятно. А как мне угадать, в каком часовом поясе была получена "локальная" дата?
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[8]: DateTime.MinValue или null?
От: Sinclair Россия https://github.com/evilguest/
Дата: 02.12.10 13:50
Оценка:
Здравствуйте, chocho, Вы писали:

C>Да, я прочитал по диагонали, сорри. Это ещё хуже, я без календаря не смогу даже залогировать дату.

Насколько я понимаю, тот факт, что без формата ты не можешь залогировать флоат, тебя не смущает. Ведь какой-то магией флоаты всё же логгируются, так?

Никто не мешает приклеить к DateTime екстеншн-методы, которые сами возьмут дефолтный календарь.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[4]: DateTime.MinValue или null?
От: _FRED_ Черногория
Дата: 02.12.10 15:37
Оценка:
Здравствуйте, Sinclair, Вы писали:

_FR>>Только вот в запросе, например, всё равно удобней пользоваться максимумом\минимум:

_FR>>
_FR>>WHERE [Created] BETWEEN ISNULL(@CreatedFrom, '1753-01-01 00:00:00')
_FR>>                    AND ISNULL(@CreatedTo, '9999-12-31 23:59:59');
_FR>>


_FR>> Но передавать надо, конечно же, null.

S>Не уверен, что это хорошая идея.

Да, с динамикой, конечно же, джедайнее. А если это код хранимки? На SQL-е составлять другой SQL то ещё развлечение Хотя, и хранимки, пожалуй, уже удел старых, опытных, мастеров, а юные падаваны имеют средства обходиться без них

А вот лучше ли "BETWEEN ISNULL" чем, например,
WHERE (@CreatedFrom IS NULL OR [Created] >= @CreatedFrom)
  AND (@CreatedTo IS NULL OR [Created] < @CreatedTo)


Вообще и, конкретно, для MSSQL?
Help will always be given at Hogwarts to those who ask for it.
Re[5]: DateTime.MinValue или null?
От: Sinclair Россия https://github.com/evilguest/
Дата: 03.12.10 13:49
Оценка:
Здравствуйте, _FRED_, Вы писали:


_FR>Да, с динамикой, конечно же, джедайнее. А если это код хранимки? На SQL-е составлять другой SQL то ещё развлечение

Ну, мы же это делали
_FR>Хотя, и хранимки, пожалуй, уже удел старых, опытных, мастеров, а юные падаваны имеют средства обходиться без них

_FR>А вот лучше ли "BETWEEN ISNULL" чем, например,

_FR>
_FR>WHERE (@CreatedFrom IS NULL OR [Created] >= @CreatedFrom)
_FR>  AND (@CreatedTo IS NULL OR [Created] < @CreatedTo)
_FR>


_FR>Вообще и, конкретно, для MSSQL?

Вообще сильно зависит от оптимизатора. Для MSSQL — надо запускать и смотреть план запроса. Я слишком давно играл с ним, чтобы судить о современном состоянии его оптимизатора.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[6]: DateTime.MinValue или null?
От: _FRED_ Черногория
Дата: 03.12.10 15:29
Оценка:
Здравствуйте, Sinclair, Вы писали:

_FR>>Да, с динамикой, конечно же, джедайнее. А если это код хранимки? На SQL-е составлять другой SQL то ещё развлечение

S>Ну, мы же это делали

А что за техники можно применять, что бы облегчить? Или только конкатенация строк?
Help will always be given at Hogwarts to those who ask for it.
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.