我维护的网站的功能之一是创建/更新即将发生的事件。用户需要能够选择事件的日期和时间,但是我发现,如果选择的日期是在一年的最后一周内,并且该周中的某天是明年,那么年将自动设置为下一年。
例如,如果选择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代码输出的屏幕截图:
日期时间错误:
我应该如何解决此问题的任何想法?维护此网站在过去两年中已不是问题,尽管现在显然对用户来说不是问题,但它将在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
});
答案 0 :(得分:3)
您在这里谈论了许多不同的事情:您正在使用Bootstrap模板中的Javascript,ColdFusion变量和数据库。所有这三个因素都会影响您看到的最终日期,并且您看到的不是日期对象(就像数据库最终需要的那样),而是日期对象的字符串表示形式。
当您查看日期时,它可能看起来像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
,因此记住应用掩码所用的语言仍然非常重要。而且,如果您不需要查看日期值并且可以继续使用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”后,它将按预期工作。