Показать сообщение отдельно
  #35 (permalink)  
Старый 06.03.2019, 02:59
Профессор
Отправить личное сообщение для laimas Посмотреть профиль Найти все сообщения от laimas
 
Регистрация: 14.01.2015
Сообщений: 12,990

Я уже говорил - поступайте как считаете нужным. А это мой последний комментарий в этой теме, и сейчас есть немного времени, и если это будет полезно, то можно и пояснить что.

Хорошо, примем понятие "логика" как понятие философское, ну или по вкусу, как кому нравится. Но сначала давайте вообще о понятии дата/время.

Вы в своей программе вы вряд ли даже станете задумываться над тем, что это такое вообще. Да, вы держите в уме два календаря, но только лишь всего. А между тем, дата/время это особенный тип данных, имеет множество представлений и может возвращаться в разных языках программирования величиной соответствующей контексту запроса. Время измеряется в количестве секунд прошедших с полуночи 1 января 1970 года по UTC (начало эпохи Unix). В Javascript это значение измеряется в миллисекундах, то есть помноженное на 1000.

Есть одна особенность объекта Date, его можно вызвать как функцию, без оператора new, и это всегда будет возвращать строку о текущей дате и времени:
alert(Date())


Но вызов объекта и как конструктора таким же образом выведет тоже самое:

1)
alert(new Date())


А теперь фокус:

2)
alert(new Date()*2)


А вот так будет неудача:

3)
alert(Date()*2)


А вот так добавим 30 дней:

4)
alert(new Date() + 1000 * 60 * 60 * 24 * 30)


Причем это будет работать даже если мы вызовем объекта как функцию, в отличии от 3):

5)
alert(Date() + 1000 * 60 * 60 * 24 * 30)


Интересно да? Все потому, что "внутри" объект понимает и знает этот тип данных во всех его деталях, и соответственно реагирует на запросы. То есть ему не составит труда исправить "ошибку". Но нужно все-таки оговорится - если вы привыкните к этому и будет думать, что это закономерность, то вас вполне может ожидать неприятный сюрприз.

Коли вы уж впряглись в веб программирование, то вполне можете оказаться и по другую сторону баррикады - на сервере. В зависимости от языка программирования на сервере, функций для работы с этим типом данных может быть различное множество, например их масса в РНР, есть готовые функции календаря для перевода дат из одного формата в другой. Основой этого календаря является исчисление с Юлианского дня.

А вот работая с базой данных, которая конечно же, также должна уметь работать с датой временем, вы столкнетесь с различным ее представлением в базе - типом. В контексте что вас "может ожидать сюрприз" возьмем тип TIMESTAMP. Этот тип есть временная метка в секундах, то есть тоже что и возвращает объект Date(), но в секундах. То есть внутренне представление этого типа, это число от 00000000000000 до макс. значения с которым может оперировать системное время (была когда-то острая проблема - начало нового тысячилетия).

И также как в JS, просто выборка даты из поля этого формата вернет строковое представление даты. Но мы то знаем, что внутреннем представление, это число. Но тем не менее, чтобы получить эту дату как метку времени, нужно явно указать в запросе это функцией UNIX_TIMESTAM(). В тоже время, SQL как и многие языки, в том числе и Javascript могут налету преобразовать один тип данных в другой. А кроме этого, SQL имеет и иные типы данных, которые являясь строковыми, во внутреннем представлении являются числами. Это типы ENUM и SET, которые по аналогии можно для простоты сравнить со списками, где первый тип, это список с одиночным выбором или связанная группа радиокнопок, а второй список с множественным выбором или набор флажков. Если тот и второй тип равен "первый,второй,третий", то запрос значения как есть вернет строковое значение - для первого одно из трех, что установлено, а для второго набор который установлен. Но если при запросе к полю имени прибавлять 0, то для первого вернет значение от 1 до 3, соответствующее установленному значению, а для второго битовый набор. И при вставке/выборке можно оперировать числами, а SQL все корректно сделает.

А как же с TIMESTAMP, о котором мы знаем, что внутренне представление этого типа тоже число? А вот так. Допустим есть в SQL функция BETWEEN, она позволяет описать проще выборку по условию A >= N AND B <= M. Если в запросе написать - BETWEEN N AND M, даже если в качестве N и M, мы укажем корректные метки времени, то запрос ничего не вернет. Казалось бы, все соответствует и должно, но тем не менее и тут нужно указывать явно что мы хотим, то есть BETWEEN FROM_UNIXTIME(N) AND FROM_UNIXTIME(M). Казусы могут быть и в JS, тут еще и браузеры различные свою лепту вносить в раздрай будут.

А теперь еще об одном касающегося типа дата/время, которое представлено строкой, хотя это не связано с тем, что это именно дата/время. Тем не менее - нельзя сравнивать даты как строковые значения, если дата не представлена в европейском формате, то есть "YYYY-MM-DD". Результат сравнения будет неверным, это следствие сравнения строк, содержащих в себе как цифровые, так и не цифровые символы. Что нужно отметить в этом случае, при сравнении строковых значений дат, то что возвращение верного результата сравнения дат при европейском формате обуславливается тем, что дата записана ее элементами от старшего (года) до младшего (дня). Это мы пока держим в уме.

В общем тип данных дата/время многогранен, вам как разработчику и нужно, и полезно знать такие вещи. Но только вам, пользователю они и не нужны, да и неинтересны. Их может заинтересовать только история этого типа данных, которая очень богата - почему в месяцах по 30 и 31 день, а в августе и сентябре по 31, а в феврале вообще то 28, то 29, календари и т.д. Вся кухня программная скрыта от пользователя, но...

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

Обычный календарь можно тоже представить в виде блок схемы и она будет довольно таки внушительной. Но в такой блок схеме явно будут определенные области, описывающие ту или иную частную задачу как часть общей.

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

Вот приложение календарь:

<input type="date" />


Его интерфейс при своей простоте удобен для пользователя, интуитивно понятен, выбор элементов управления есть предсказуемый результат, не позволяет ошибок при управлении через элементы управления. А ручной ввод не позволяет выбрать в нем введенную некорректную дату. Попробуйте найти в нем в текущем месяце день 31 марта чтобы выбрать его. Этого нет, ибо это нелогично, а значит и интерфейс приложения автоматически предоставляет пользователю дни только текущего месяца. Для выбора диапазона дат служат сдвоенные календари или календари имеющие такую функцию.

А теперь извлечем из памяти европейское строковое представление даты. Как уже говорилось, корректность сравнения дат в строковом представлении европейского формата в представлении ее от старшинства элементов даты. Так и в календаре, если нужно выбрать март 31, то сначала нужно выбрать месяц март, и это вполне естественное действие к которому все привыкли. Это естественное и заложено в логику приложения, которое обеспечивает подобающий этой логике интерфейс. Разработчики этого приложения как раз ориентировались на предсказуемость поведения пользователя, а единственная возможная непредсказуемость, которая может возникнуть при ручном вводе даты, блокируется приложением. И заметьте, без сообщений, просто отмечая окно ввода красным, что уже дает понять о наличии ошибки, а при вводе корректной даты она будет выбрана в календаре.

Последний раз редактировалось laimas, 06.03.2019 в 03:54.
Ответить с цитированием