Здравствуйте, merge, Вы писали:
M>Есть фильтр, где юзер вбивает даты начала и окончания для поиска. M>Если юзер не вбил любую или обе из дат, то интервал открыт для поиска. M>Вот что по вашему лучше передавать в качестве даты в данном случае DateTime.MinValue или null?
На мой вкус — лучше null. Т.е использовать Nullable<DateTime>.
M>Есть фильтр, где юзер вбивает даты начала и окончания для поиска. M>Если юзер не вбил любую или обе из дат, то интервал открыт для поиска.
M>Вот что по вашему лучше передавать в качестве даты в данном случае DateTime.MinValue или null?
Если юзер "не вбил", то и передавать ничего не нужно.
Здравствуйте, merge, Вы писали:
M>Есть фильтр, где юзер вбивает даты начала и окончания для поиска. M>Если юзер не вбил любую или обе из дат, то интервал открыт для поиска.
M>Вот что по вашему лучше передавать в качестве даты в данном случае DateTime.MinValue или null?
В данном случае "волшебные" значения (DateTime.MinValue, DateTime.MaxValue) плохи тем, что они могут "испортиться" при преобразованиях из UTC в LocalTime или обратно:
А такое очень даже возможно в распределённых приложениях, например, клиентская программа находится в Москве в поясе UTC+3, а центральная БД, к которой идут запросы — в Лондоне с поясом UTC+0.
Резюме: как и сказали предыдущие ораторы, более надёжно будет использовать null.
Здравствуйте, andy1618, Вы писали:
A>А такое очень даже возможно в распределённых приложениях, например, клиентская программа находится в Москве в поясе UTC+3, а центральная БД, к которой идут запросы — в Лондоне с поясом UTC+0.
Это все по тому что индус который делал эти классы не удосужился подумать головой.
Единственно верный способ реализовать DateTime это зафиксировать некую точку во времени.
Например 01.01.2000 00:00:00 UTC+0
Или любую другую по вкусу.
И отсчитывать от этой точки колличество наносекунд.
Если больше 0 то дата после нашего начала времен. Если меньше то до.
А преобразование в строку и обратно должен делать объект календарь который уже будет учитывать всякие там часовые пояса, весокосные года, прыгающие секунды и что там еще есть...
В этом случае внутри программы вообще никаких преобразований времени не будет. И все локальности будут только на уровне пользовательского интерфейса.
A>Резюме: как и сказали предыдущие ораторы, более надёжно будет использовать null.
Это не более надежно.
По другому просто нельзя.
Ибо если нет значения это нужно указать явно.
Причем лучше всего отразить это дело в типе объекта. Option<DateTime> правда чтобы работать в таком стиле нужно язык поумнее чем C#.
Но на худой конец Nullable тоже сойдет.
... << RSDN@Home 1.2.0 alpha 4 rev. 1472>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Здравствуйте, WolfHound, Вы писали:
A>>А такое очень даже возможно в распределённых приложениях, например, клиентская программа находится в Москве в поясе UTC+3, а центральная БД, к которой идут запросы — в Лондоне с поясом UTC+0. WH>Это все по тому что индус который делал эти классы не удосужился подумать головой. WH>Единственно верный способ реализовать DateTime это зафиксировать некую точку во времени.
<…> WH>А преобразование в строку и обратно должен делать объект календарь который уже будет учитывать всякие там часовые пояса, весокосные года, прыгающие секунды и что там еще есть...
Так в BCL именно так и сделано?
Help will always be given at Hogwarts to those who ask for it.
Здравствуйте, andy1618, Вы писали:
M>>Есть фильтр, где юзер вбивает даты начала и окончания для поиска. M>>Если юзер не вбил любую или обе из дат, то интервал открыт для поиска. M>>Вот что по вашему лучше передавать в качестве даты в данном случае DateTime.MinValue или null?
A>В данном случае "волшебные" значения (DateTime.MinValue, DateTime.MaxValue) плохи тем, что они могут "испортиться" при преобразованиях из UTC в LocalTime или обратно: A>
A>А такое очень даже возможно в распределённых приложениях, например, клиентская программа находится в Москве в поясе UTC+3, а центральная БД, к которой идут запросы — в Лондоне с поясом UTC+0. A>Резюме: как и сказали предыдущие ораторы, более надёжно будет использовать null.
А кто-то автоматически без ведома программиста преобразованиями занимается? По сути
A>dt = dt.ToLocalTime(); // {01.01.0001 03:00:00}
есть просто изменение значения переменной aka
A>dt = dt.AddHours(hours);
и ни скакой стати теперь сравнивать
dt == DateTime.MinValue
нельзя.
Другое дело, что из-за наличия Kind в DateTime () некоторые [якобы] умные системы начинают сами преобразованиями некими заниматься. Дык это проблема систем, а не DateTime.
Help will always be given at Hogwarts to those who ask for it.
Здравствуйте, Aen Sidhe, Вы писали:
M>>Вот что по вашему лучше передавать в качестве даты в данном случае DateTime.MinValue или null?
AS>Зависит от организации и привычек. Я предпочитаю null.
Только вот в запросе, например, всё равно удобней пользоваться максимумом\минимум:
WHERE [Created] BETWEEN ISNULL(@CreatedFrom, '1753-01-01 00:00:00')
AND ISNULL(@CreatedTo, '9999-12-31 23:59:59');
Но передавать надо, конечно же, null.
Help will always be given at Hogwarts to those who ask for it.
И что бы это дало?
WH>Все остальное требует календаря и должно туда уехать.
То есть Ticks/Millisecond/Minute/Hour/Date/TimeOfDay так же "вынесем за"? Это, конечно, [технически] можно сделать, обойдясь методами-расширениями, но, ИМХО, не принципиально.
Относительно DayOfWeek/DayOfYear/Day/Month/Year — поскольку выбранный "ноль" в точности соответствует одному из [наиболее часто используемых програмистами] календарей, они тут не выглядят лишними.
Просто [ИМХО, впролне оправданно] приняли решение при проектировании сделать работу с одним из календарей несколько более удобной, чем с остальными. Что ни как не отменяет использование других календарей.
Вот Kind действительно не очень полезен и вываливается из общей схемы, тут они схалтурили.
Help will always be given at Hogwarts to those who ask for it.
Здравствуйте, _FRED_, Вы писали:
WH>>Плюс соответствующие операторы для удобства. _FR>И что бы это дало?
Понимание того что там намешано куча разного мусора.
_FR>Просто [ИМХО, впролне оправданно] приняли решение при проектировании сделать работу с одним из календарей несколько более удобной, чем с остальными. Что ни как не отменяет использование других календарей.
Так можно оправдять любой косяк.
И вот из-за кучи таких казалось бы оправданых косяков получился .НЕТ о котором я без мата говорю с большим трудом.
... << RSDN@Home 1.2.0 alpha 4 rev. 1472>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Здравствуйте, WolfHound, Вы писали:
WH>>>Плюс соответствующие операторы для удобства. _FR>>И что бы это дало? WH>Понимание того что там намешано куча разного мусора.
Почему разного? Если отбросить Kind, то весь мусор — строго имеет отношение к одному календарю. Верно?
_FR>>Просто [ИМХО, впролне оправданно] приняли решение при проектировании сделать работу с одним из календарей несколько более удобной, чем с остальными. Что ни как не отменяет использование других календарей. WH>Так можно оправдять любой косяк.
Что, впрочем, не означает, что оправдывается именно косяк. Это такая идеалогия у Майкрософта в проектировании API: не строгий минимализм SRP, а баланс вкупе с удобством использования. Они [справедливо] решили, что в большинстве случаев ничто кроме определённого календаря не нужно и внесли его в базу. Тем самым они не отменили другие календари. Они сделали простым использование наиболее частых сценариев.
WH>И вот из-за кучи таких казалось бы оправданых косяков получился .НЕТ о котором я без мата говорю с большим трудом.
ИМХО, "косяк" — это когда есть конкретный сценарий, приводящий к неожиданному поведению. В данном случае это одна из огрех API, которое нельзя сделать таким, что бы было одинаково хорошо всем разработчикам Всегда кто-то да и выматюгается
Help will always be given at Hogwarts to those who ask for it.
Здравствуйте, _FRED_, Вы писали:
_FR>Почему разного? Если отбросить Kind, то весь мусор — строго имеет отношение к одному календарю. Верно?
Если мы убираем Kind то все остальное становится весьма бессмысленным ибо Day, Hour, DayOfWeek,... и многие други свойства зависят от часового пояса.
И как следствие они будут работать только для UTC что уже весьма смешно. Или тебе придется значение в DateTime корежить что криво и ведет к ошибкам.
С календарями такой проблемы нет. Просто при создании календаря указываем часовой пояс и все.
_FR>Что, впрочем, не означает, что оправдывается именно косяк. Это такая идеалогия у Майкрософта в проектировании API: не строгий минимализм SRP, а баланс вкупе с удобством использования. Они [справедливо] решили, что в большинстве случаев ничто кроме определённого календаря не нужно и внесли его в базу. Тем самым они не отменили другие календари. Они сделали простым использование наиболее частых сценариев.
И получаем говнокод.
Сначала нам нужен один часовой пояс, а потом несколько и приехали. Переписываем все приложение нахрен.
Нарушение SRP это очень серьезный косяк который очень часто приводит к проблемам.
А нарушение SRP в стандартной библиотеке платформы это просто преступление.
_FR>ИМХО, "косяк" — это когда есть конкретный сценарий, приводящий к неожиданному поведению.
Ветку почитай.
_FR>В данном случае это одна из огрех API, которое нельзя сделать таким, что бы было одинаково хорошо всем разработчикам Всегда кто-то да и выматюгается
В таком случае надо делать правильно.
... << RSDN@Home 1.2.0 alpha 4 rev. 1472>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Здравствуйте, WolfHound, Вы писали:
_FR>>Почему разного? Если отбросить Kind, то весь мусор — строго имеет отношение к одному календарю. Верно? WH>Если мы убираем Kind то все остальное становится весьма бессмысленным ибо Day, Hour, DayOfWeek,... и многие други свойства зависят от часового пояса. WH>И как следствие они будут работать только для UTC что уже весьма смешно. Или тебе придется значение в DateTime корежить что криво и ведет к ошибкам.
Не только "только для UTC" а для какого-то неконкретного пояса.
WH>С календарями такой проблемы нет. Просто при создании календаря указываем часовой пояс и все.
_FR>>Что, впрочем, не означает, что оправдывается именно косяк. Это такая идеалогия у Майкрософта в проектировании API: не строгий минимализм SRP, а баланс вкупе с удобством использования. Они [справедливо] решили, что в большинстве случаев ничто кроме определённого календаря не нужно и внесли его в базу. Тем самым они не отменили другие календари. Они сделали простым использование наиболее частых сценариев. WH>И получаем говнокод.
В некоторых случаях — несомненно.
_FR>>ИМХО, "косяк" — это когда есть конкретный сценарий, приводящий к неожиданному поведению. WH>Ветку почитай.
"Косяком" является то, что вызов "dt.ToLocalTime();" вызвращает что-то не то, что было до этого? других косяков не заметил Или "косяк" — это появление в некоторых случаях "говнокода"? Тогда, косяк. Но если небыло бы этого косяка, во многих других случаях было бы больше… нет, не "говнокода" конечно же, но не очень нужного :о))
WH>Нарушение SRP это очень серьезный косяк который очень часто приводит к проблемам. WH>А нарушение SRP в стандартной библиотеке платформы это просто преступление.
Пожалуй, да. Они, кстати, где-то даже каялись за DateTime
_FR>>В данном случае это одна из огрех API, которое нельзя сделать таким, что бы было одинаково хорошо всем разработчикам Всегда кто-то да и выматюгается WH>В таком случае надо делать правильно.
А правильно, на мой взгляд, если тебе хочется работать с датой\временем по-взрослому, представлять дату в типе long и на DateTime забить вообще. То есть, в БД хранить как bigint, в софте [возможно] написать свой тип для представления. И проблем [больших] не будет. А мелкие не сложно решаемы.
Help will always be given at Hogwarts to those who ask for it.
Здравствуйте, _FRED_, Вы писали:
_FR>"Косяком" является то, что вызов "dt.ToLocalTime();" вызвращает что-то не то, что было до этого? других косяков не заметил Или "косяк" — это появление в некоторых случаях "говнокода"? Тогда, косяк. Но если небыло бы этого косяка, во многих других случаях было бы больше… нет, не "говнокода" конечно же, но не очень нужного :о))
Косяк в том, что DateTime.Now дает это локальное время, а не UTC. И вот теперь надо попробовать объяснить всем разработчикам что использовать Now в реальных проектах не стоит.
Здравствуйте, hardcase, Вы писали:
_FR>>"Косяком" является то, что вызов "dt.ToLocalTime();" вызвращает что-то не то, что было до этого? других косяков не заметил Или "косяк" — это появление в некоторых случаях "говнокода"? Тогда, косяк. Но если небыло бы этого косяка, во многих других случаях было бы больше… нет, не "говнокода" конечно же, но не очень нужного :о))
H>Косяк в том, что DateTime.Now дает это локальное время, а не UTC.
Это не является косяком само по себе — это опять же поведение, выбранное в свете наиболее часто используемых сценариев.
H>И вот теперь надо попробовать объяснить всем разработчикам что использовать Now в реальных проектах не стоит.
И вывод не правильный — приходится объяснять всем (и это сделано в документации, хоть и не явно), как надо использовать Now.
Help will always be given at Hogwarts to those who ask for it.
Здравствуйте, _FRED_, Вы писали:
_FR>Не только "только для UTC" а для какого-то неконкретного пояса.
Вопрос в том какого? И что делать если их у нас несколько?
Кстати с летним и зимним временем тоже веселуха получается.
Причем как с ней бороться вообще не ясно.
_FR>"Косяком" является то, что вызов "dt.ToLocalTime();" вызвращает что-то не то, что было до этого? других косяков не заметил Или "косяк" — это появление в некоторых случаях "говнокода"? Тогда, косяк.
Само наличие ToLocalTime уже косяк.
Ибо локального времени не существует.
Это понятие виртуальное.
Нужно оно только в интерфейсе пользователя.
Во всех остальных местах оно делает все намного сложнее.
_FR>Но если небыло бы этого косяка, во многих других случаях было бы больше… нет, не "говнокода" конечно же, но не очень нужного :о))
Ну да...
someDate.ToString();
и
someDate.ToString(calendar);
это просто звездец какая разница.
Причем этот код будет исключительно на уровне интерфейса пользователя.
_FR>Пожалуй, да. Они, кстати, где-то даже каялись за DateTime
Им надо за весь .НЕТ каяться.
Причем можно начинать сразу с системы типов и MSIL. На эту темя я без мата вообще говорить не могу.
_FR>А правильно, на мой взгляд, если тебе хочется работать с датой\временем по-взрослому, представлять дату в типе long и на DateTime забить вообще. То есть, в БД хранить как bigint, в софте [возможно] написать свой тип для представления. И проблем [больших] не будет. А мелкие не сложно решаемы.
Ты таки согласен что все это косяк?
Но с чем же ты тогда споришь?
... << RSDN@Home 1.2.0 alpha 4 rev. 1472>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Здравствуйте, WolfHound, Вы писали:
_FR>>Не только "только для UTC" а для какого-то неконкретного пояса. WH>Вопрос в том какого? И что делать если их у нас несколько? WH>Кстати с летним и зимним временем тоже веселуха получается. WH>Причем как с ней бороться вообще не ясно.
А не важно. Если мы работаем с DateTime не обращая внимания на Kind, то нам важно только абсолютное значение. Сложности возникают лишь при получении откуда-то / передачи куда-то значений.
_FR>>"Косяком" является то, что вызов "dt.ToLocalTime();" вызвращает что-то не то, что было до этого? других косяков не заметил Или "косяк" — это появление в некоторых случаях "говнокода"? Тогда, косяк. WH>Само наличие ToLocalTime уже косяк.
Очень может быть, такой же, как и наличие Kind.
WH>Во всех остальных местах оно делает все намного сложнее.
Для большого количества приложений — вполне достаточного.
_FR>>Но если небыло бы этого косяка, во многих других случаях было бы больше… нет, не "говнокода" конечно же, но не очень нужного :о)) WH>Ну да... WH>someDate.ToString(); WH>и WH>someDate.ToString(calendar); WH>это просто звездец какая разница. WH>Причем этот код будет исключительно на уровне интерфейса пользователя.
Методов таких было бы очень много:
var xxx = yyy.AddMonth(2, CultureInfo.InvariantCulture.Calendar);
// или, как сейчасvar xxx = CultureInfo.InvariantCulture.Calendar.AddMonth(yyy, 2);
вместо
var xxx = yyy.AddMonth(2);
И первое, что написали бы — это тип [DateTime, Calendar];
_FR>>Пожалуй, да. Они, кстати, где-то даже каялись за DateTime WH>Им надо за весь .НЕТ каяться. WH>Причем можно начинать сразу с системы типов и MSIL. На эту темя я без мата вообще говорить не могу.
А существует идеальная система типов?
_FR>>А правильно, на мой взгляд, если тебе хочется работать с датой\временем по-взрослому, представлять дату в типе long и на DateTime забить вообще. То есть, в БД хранить как bigint, в софте [возможно] написать свой тип для представления. И проблем [больших] не будет. А мелкие не сложно решаемы. WH>Ты таки согласен что все это косяк?
Я согласен, что на это можео посмотреть как на косяк с точки зрения "старого, опытного каимкадзе".
WH>Но с чем же ты тогда споришь?
С тем, что это косяк О "косячности" архитектуры имеет смысл говорить с точки зрения задач, которые эта архитектура решает и для которых предназначена.
Майкрософт [к сожеление, но сожеление риторическое] ориентируется не только на продвинутых разработчиков, которые и так с помощью вотки и какой-то матери выкрутятся, а на комерческий успех предприятия. .NET работает [и, наверное, приносит прибыль] уже восемь, что ли, лет. Если бы они вылизывали своё АПИ и прочее ("системы типов и MSIL") и требовали хорошей подготовленности от пользователей, то не знаю, какая версия была бе сейчас текущей :о))
Резюмируя — конечно, с точки зрения хорошего АПИ многие [базовые, что преумножает] вещи сделаны недодуманно Но цель-то не сделать продуманное во всех (даже "во многих") смыслах АПИ, а сделать так, что сто тыщ индусов… ну и пару пряников гикам
Плохо, конечно, но с этим _можно жить_ (не "шикарно", но "припеваючи" — вполне). А недовольства высказывать имеет смысл только в ключе:
Душа моя Павел,
Держись моих правил: Люби то-то, то-то, Не делай того-то.
Кажись, это ясно.
Прощай, мой прекрасный.
Что-то я не понимаю проблемы с которой вы боретесь и за что ненавидите DateTime.
В распределённым приложении нужно работать с UTC временем, переводя его в локальное там где нужно.
Отсутствие даты\времени это null, не MinValue.
Kind у DateTime это нормально потому что указав его я знаю как себя ведёт объект при передаче по ремоутингу, время действительно может быть Local, UTC и Unspecified.