如何使Bootstrap DateTimePicker显示正确的年份?

时间:2019-03-26 20:06:34

标签: javascript html twitter-bootstrap coldfusion

我维护的网站的功能之一是创建/更新即将发生的事件。用户需要能够选择事件的日期和时间,但是我发现,如果选择的日期是在一年的最后一周内,并且该周中的某天是明年,那么年将自动设置为下一年。

例如,如果选择2019年12月29日,则插入数据库的日期为2020年12月29日。 此外,如果我打开一个包含事件数据的模块,即使数据库记录为2020年,该日期也将显示为2021年12月29日。

由于2019年12月28日是星期六,并且不在2020年的同一天,因此它将在2019年12月28日插入数据库中。

以下是事件模块的一些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>

以下是DateTimePicker的javascript:

<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代码输出的屏幕截图:

日期时间错误:

enter image description here

我应该如何解决此问题的任何想法?维护此网站在过去两年中已不是问题,尽管现在显然对用户来说不是问题,但它将在11月/ 12月,我现在想修复它。< / p>

编辑:有两个主要操作都需要修复。用户需要能够添加事件和更新事件。上面的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 个答案:

答案 0 :(得分:3)

您在这里谈论了许多不同的事情:您正在使用Bootstrap模板中的Javascript,ColdFusion变量和数据库。所有这三个因素都会影响您看到的最终日期,并且您看到的不是日期对象(就像数据库最终需要的那样),而是日期对象的字符串表示形式。

当您查看日期时,它可能看起来像March 27, 2019 12:00:00 pm03/27/2019 12:00:00 pm27/03/2019 12:00:00.000或类似的东西。当数据库或编程语言将该字符串视为日期对象时,它看起来像123465789.123465798,通常是自系统组件使用任何时期以来的秒数的特定值。 Epoch完全是一个完全不同的主题。

由于长十进制实际上不是人类可读的日期,因此您的语言必须执行屏蔽操作才能在两种表示形式之间来回转换。

您要记住要使用掩码的哪一部分代码。通常,掩码是用于显示的,但是在插入字符串之前,可能还需要使用它来将字符串转换为数据库上的日期可读对象。因此,您将要检查Javascript是否对表单中的值没有执行任何操作,ColdFusion对Javascript字符串没有执行任何操作以及数据库是否不会进一步更改ColdFusion字符串。

我不确定Bootstrap的datapicker用什么来解释日期字符串,或者它最终是否会向您的ColdFusion发送一个奇数字符串,但是我确实知道CF11根据您使用的功能使用不同的掩码。 DateFormat()不在乎您使用哪种情况,但是DateTimeFormat()不管。它依赖于其底层Java SimpleDateFormat的屏蔽定义,该定义将yY解释为不同的掩码,表示不同的含义。

最大的麻烦是,正如您所看到的,它在一年末只能看到几天,因为一年永远不会完全由52周组成。因此,我们还有另一种日期类型,称为WeekYearY遮罩中的SimpleDateFormat。本质上,它是基于周(Ww)的年份。因此,在年初和结束的几天内,“日历年”将不等于“周年”。在一年的其他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中不区分大小写,因此使用yyyyYYYY都无关紧要。但是请帮自己一个忙,并使用yyyy,因为您知道CF仍基于Java构建。但是,还有其他一些框架期望使用YYYY而不是yyyy,因此记住应用掩码所用的语言仍然非常重要。而且,如果您不需要查看日期值并且可以继续使用date对象,请以这种方式保留它,而不要使其成为可读的字符串。

答案 1 :(得分:0)

我知道了我的问题。当按下“保存”按钮时,数据被放入一个结构中,该结构将传递给以下函数:

<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 />

最初,它会使用“ YYYY”格式化日期,但将其更改为“ yyyy”后,它将按预期工作。