Как я могу получить Bootstrap DateTimePicker для отображения правильного года? - PullRequest
4 голосов
/ 26 марта 2019

Одной из функций веб-сайта, который я поддерживаю, является создание / обновление предстоящего события.Пользователи должны иметь возможность выбирать дату и время события, но я обнаружил, что если выбранная дата относится к последней неделе года, и в этой неделе есть дни, которые относятся к следующему году, тогод автоматически устанавливается на следующий год.

Например, если выбрано 29 декабря 2019 года, то дата, вставленная в базу данных, будет 29 декабря 2020 года. Далее, если я открою модульс данными о событиях в нем будет отображаться дата 29 декабря 2021 года, даже если в базе данных она записана в 2020 году.

С 28 декабря 2019 года суббота и не являетсяна той же неделе, что и в дни 2020 года, он будет вставлен в базу данных, как 28 декабря 2019 года.

Ниже приведен код ColdFusion для модуля событий:

<div class="form-group">
    <cfdump var="#event.event_date_time#" expand="yes"></cfdump>
    <label>Event Date and Time:</label>
    <div class='input-group date' id='updateEventDateTime'>
        <input required type='text' name="updateEventDateTime" class="form-control" 
               placeholder="Select event date and time" 
               value="#DateTimeFormat(event.event_date_time,'MM/dd/YYYY H:nn tt')#"/>
        <span class="input-group-addon">
            <span class="glyphicon glyphicon-calendar"></span>
        </span>
    </div>
    <cfdump var="#event.event_date_time#" expand="yes"></cfdump>
</div>

Вотjavascript для DateTimePicker:

<script>
    $(document).ready(function(e) {

        // Create the Bootstrap Datetimepicker for the event
        // date and time
        $('#updateEventDateTime').datetimepicker({
            format: 'MM/DD/YYYY H:mm A',
            sideBySide: true
        });

    });
</script>

Вот скриншот того, что выводит приведенный выше код ColdFusion:

Неправильный год в DateTime:

enter image description here

Любые идеи о том, чтоЯ должен сделать, чтобы это исправить?За последние 2 года я не поддерживал этот сайт, и хотя он, очевидно, не является проблемой для пользователей сейчас, это будет в ноябре / декабре, и я бы лучше решил его сейчас.

РЕДАКТИРОВАТЬ: есть две основные операции, которые обе должны быть исправлены.Пользователи должны иметь возможность добавлять событие и обновлять событие.Приведенный выше код ColdFusion находится в модуле updateEvent, а часть кода для модуля addEvent приведена ниже:

<div class="form-group">
    <label>Event Date and Time:</label>
    <div class='input-group date' id='addEventDateTime'>
        <input required type='text' name="addEventDateTime" class="form-control" 
               placeholder="Select event date and time" />
        <span class="input-group-addon">
            <span class="glyphicon glyphicon-calendar"></span>
        </span>
    </div>
</div>

Код JavaScript в этом модуле содержит следующее:

<script>
$(document).ready(function(e) {

    // Create the Bootstrap Datetimepicker for the event
    // date and time
    $('#addEventDateTime').datetimepicker({
        format: 'MM/DD/YYYY H:mm A',
        sideBySide: true
    });

Ответы [ 2 ]

3 голосов
/ 27 марта 2019

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

Когда вы смотрите на дату, она, вероятно, выглядит как March 27, 2019 12:00:00 pm или 03/27/2019 12:00:00 pm или 27/03/2019 12:00:00.000 или что-то в этом роде.Когда база данных или язык программирования воспринимают эту строку как объект даты, она выглядит как 123465789.123465798, что обычно составляет конкретное значение в секундах с той эпохи, которую использует системный компонент.Epoch - это совершенно другая тема.

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

Вы хотите иметь в виду, какой фрагмент кода вы используете для маскировки.Обычно маскировка предназначена для отображения, но вам также может понадобиться преобразовать строку в объект с возможностью считывания даты в вашей базе данных, прежде чем он вставит ее.Итак, вы захотите убедиться, что ваш Javascript ничего не делает со значением в вашей форме, что ColdFusion ничего не делает с этой строкой Javascript, и что ваша база данных больше не изменяет эту строку ColdFusion.

Я не уверен, что Bootstrap datapicker использует для интерпретации строк даты или, если он в конечном итоге отправляет нечетную строку в ColdFusion, но я знаю, что CF11 использует различную маскировку в зависимости от используемой вами функции,DateFormat() не волнует, в каком случае вы используете, но DateTimeFormat() делает.Он опирается на определение маскировки своей базовой Java SimpleDateFormat, которая интерпретирует y и Y как разные маски, означающие разные вещи.

Большая боль в том, что, как вы видели, он будет виден только через несколько дней в конце года, поскольку год никогда не будет составлять ровно 52 недели.Таким образом, у нас есть другой тип даты, называемый WeekYear или Y в SimpleDateFormat маскировании.По сути, это год, на котором она основана на Неделе (W или w).Таким образом, в течение нескольких дней в начале и конце года календарный год не будет равняться году недели.В остальные 358 дней года они будут такими же.А поскольку новогодние и новогодние праздники часто являются нерабочими праздниками, это ОЧЕНЬ ПРОСТО .Так что, по сути, ваш код не работал правильно последние пару лет;у тебя просто не было причин замечатьЗабавно, правда?

Для простого примера смотрите: https://trycf.com/gist/5cb651559e28e5cbdecdb57b959c3c18/acf11?theme=monokai

И если вы заметите, и dateFormat(), и timeFormat() будут маскироваться за пределы того, что они "технически" предполагаютсясделать.Вы можете получить timeFormat(), чтобы применить маску и к date части строки.Они не должны работать таким образом.

Как я уже говорил в нескольких местах, обработка дат (почти на любом языке) - моя любимая мозоль.Это тема, которая заставит вас захотеть вырвать свои волосы.И, возможно, волосы любого, кто сидит рядом с вами.И ОПРЕДЕЛЕННО волосы того, кто написал код обработки даты, который вы отлаживаете.Это полностью тема, вызывающая ярость кода.

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

https://codefumonkey.blogspot.com/2016/02/date-masking-inconsistency.html https://codefumonkey.blogspot.com/2016/10/more-date-masking.html

ПРИМЕЧАНИЕ: Более поздние версии CF изменили поведение маскирования в некоторых функциях даты. Они не чувствительны к регистру в CF2018, поэтому не имеет значения, используете ли вы yyyy или YYYY. Но сделайте себе одолжение и используйте yyyy, поскольку вы знаете, что CF по-прежнему построен на Java. Однако есть некоторые другие фреймворки, которые ожидают YYYY вместо yyyy, поэтому очень важно помнить, какой язык вы используете для применения маски. И если вам не нужно видеть значение даты и вы можете продолжать работать с объектом даты, оставьте его таким, а не делайте его читабельной строкой.

0 голосов
/ 27 марта 2019

Я разобрался в своей проблеме.Когда нажата кнопка «Сохранить», данные помещаются в структуру, которая передается в следующую функцию:

<cffunction name="addEvent" access="public" returntype="any">
<cfargument name="eventStruct" type="struct" required="yes">
<!--- Verify the structure is formated correctly --->

<!--- Checks if all the required elements of the struct are there --->

<!--- Verify the date object is correct --->
<cfif NOT isDate(ARGUMENTS.eventStruct.eventDateTime)>
    <cfset errorCode = "INVALID_VARIABLE_TYPE">
    <cflog file="chapter-reports" type="error" 
        text="#errorCode#: variable must be a coldfusion date object">
    <cfreturn errorCode />
</cfif>
<!--- Format the date --->
<cfset ARGUMENTS.eventStruct.eventDateTime = DateTimeFormat(ARGUMENTS.eventStruct.eventDateTime,"yyyy-MM-dd HH:nn:ss")>
<!--- Insert the event into the table --->
<cftry>
    <cfquery datasource="#VARIABLES.datasource#" name="insertEvent" result="newEvent">
        INSERT INTO #VARIABLES.tablePrefix#events
        (/*column names*/,event_date_time,/*more column names*/)
        VALUES(
            /*data*/,
            '#ARGUMENTS.eventStruct.eventDateTime#',
            /*more data*/
        )
    </cfquery>

    <!--- Send an error message if there is a database error --->

</cftry>
<cfreturn newEvent.generated_key />

Первоначально она будет форматировать дату с помощью «ГГГГ», но после изменения его на «гггг» он работает как задумано.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...