Java 使用p:calendar相互限制开始和结束日期时间(无验证)
我们需要向用户提供两个p:calendar组件,分别表示开始日期和结束日期。两个日期时间都有日期、小时和分钟。 PrimeFaces具有完美的Java 使用p:calendar相互限制开始和结束日期时间(无验证),java,ajax,jsf,primefaces,calendar,Java,Ajax,Jsf,Primefaces,Calendar,我们需要向用户提供两个p:calendar组件,分别表示开始日期和结束日期。两个日期时间都有日期、小时和分钟。 PrimeFaces具有完美的mindate,maxdate,minHour,maxHour,MinMinMinMinute和MinMinMinMinute属性 现在的要求是: 无法将开始日期时间设置为大于或等于结束日期时间的任何值。 无法将end datetime设置为小于或等于end datetime的任何值 以下等式应该成立: begin datetime < end da
mindate
,maxdate
,minHour
,maxHour
,MinMinMinMinute
和MinMinMinMinute
属性
现在的要求是:
无法将开始日期时间设置为大于或等于结束日期时间的任何值。
无法将end datetime设置为小于或等于end datetime的任何值
以下等式应该成立:
begin datetime < end datetime
如您所见,最小结束日期是当前选择的开始日期。正确设置结束日期不允许将开始日期设置为超过结束日期
当把时间纳入方程时,问题就开始了
由于p:calendar的接口有单独的方法,因此bean必须提供以下逻辑:
public int getMinEndHour()
{
Date selectedBeginDate = this.getSelectedBeginDate();
Date selectedEndDate = this.getSelectedEndDate();
if ( selectedBeginDate != null && DateUtil.isSameDay( selectedBeginDate, selectedEndDate ) )
{
return DateUtil.getHourOf( selectedBeginDate );
}
return ComplianceConstants.DEFAULT_COMPLIANCE_CASE_MIN_END_HOUR;
}
这基本上只表示如果设置了开始日期,并且开始日期和结束日期当前相同,则将可选择的结束时间(minHour
结束日期)限制为开始时间
操作:
Set the begin datetime to 2013-04-20 12:34 (legit)
Set the end datetime to 2013-04-22 00:00 (legit)
现在结束日期的时间是00:00,只要结束时间调整到至少12:35,就应该允许选择2013-04-20日历日期
然而,p:calendar组件现在还不知道这一点
sets the end datetime to 2013-04-20 00:00 (legit, but false)
现在的问题是,当用户在日历中按下某个新的结束日期时,mindate/maxdate属性不能限制用户按与开始日期相同的日期。如果结束日期时间现在恰好在同一开始日期的时间之前我们对此无能为力(这是错误的)
接下来的问题是,用户可以关闭日历,只需按submit按钮将虚假数据插入数据库。当然,验证器可以/应该运行,但是我们必须在没有验证器的情况下以某种方式实现这一点
我们接下来尝试的是修补setSelectedBeginDate(Date selectedBeginDate)
和setSelectedEndDate(Date selectedEndDate)
方法,以调整setjava.util.Date
时间部分(如果日期在同一天)。大概是这样的:
public void adjustSelectedEndDate()
{
if ( this.selectedEndDate != null )
{
this.log.infov( "adjustSelectedEndDate: b-hour = {0}, e-hour = {1}", DateUtil.getHourOf( this.selectedBeginDate ), DateUtil.getHourOf( this.selectedEndDate ) );
if ( DateUtil.isSameDay( this.selectedBeginDate, this.selectedEndDate ) &&
( DateUtil.getHourOf( this.selectedEndDate ) < DateUtil.getHourOf( this.selectedBeginDate ) ) ||
DateUtil.getHourOf( this.selectedEndDate ) == DateUtil.getHourOf( this.selectedBeginDate ) && DateUtil.getMinuteOf( this.selectedEndDate ) <= DateUtil.getMinuteOf( this.selectedBeginDate ) )
{
this.log.info( "Adjusting selected end date!" );
this.selectedEndDate = DateUtil.addOneMinuteTo( DateUtil.copyTime( this.selectedBeginDate, this.selectedEndDate ) );
}
}
}
public void adjustSelectedEndDate()
{
如果(this.selectedededDate!=null)
{
this.log.infov(“adjustSelectedEndDate:b-hour={0},e-hour={1}”、DateUtil.getHourOf(this.selectedBeginDate)、DateUtil.getHourOf(this.selectedEndDate));
if(DateUtil.isSameDay(this.selectedBeginDate,this.selectedEndDate)&&
(DateUtil.getHourOf(this.selectedEndDate) DateUtil.getHourOf(this.selectedEndDate)=DateUtil.getHourOf(this.selectedBeginDate)和&DateUtil.getMinuteOf(this.selectedEndDate)前言:
我不使用JSF,但有几件事可能会引导您回到您想要的位置:
a,考虑使用:
someCalendar.set(Calendar.MILLISECOND, 0)
b)考虑使用,因为它在标准库中经常被推荐(,和)在许多情况下的正确性、性能和易用性。
c) 确保您的bean作用域在每次ajax调用(不重定向,只发送标准回发等)中都能存活,并且每个事件处理程序都能获取faces上下文(例如,
FacesContext FacesContext=FacesContext.getCurrentInstance();
)
d) mindate
之类的东西可能不会像你期望的那样工作,我也不期望自动行为能如此容易地被打断
当这些选项不可用时,您必须自己使用您所拥有的一切:
非利士语/UX:
我要做的第一件事是从这对日期中删除对安排或透视的期望。不要将这对日期视为一个向量,暴露或期望在时间线上有一个方向
- 换句话说,
start
或from
日期是否总是小于或早于end
或to
日期?否,如查询历史数据或对尚未发生或已经发生的事件应用更正所示
这一内涵很容易让用户混淆他们是“返回”还是“向前”(也很容易让自己混淆)。相反,我会将一对日期(它们之间有一个时间段)视为一对日期(它们之间有一个时间段),或者一个范围(它们之间有一个时间段),或者一个时间段(它们之间有一个时间段)来声明一个时间间隔,并根据所选的值推断它们在时间线上的相对位置。这样,您就可以尊重相应的和这里要求日期永远不相等,左边总是左边,右边总是右边
我们无法推断“开始”或“开始”的含义,但我们可以推断出一些含义和相对关系:按时间顺序排列的时间线上的右、左和中间。注意:在进行任何计算或比较之前,始终将日期解析为UTC。
long oneDateValue = oneDate.toUtc().toMilliseconds();
long anotherDateValue = anotherDate.toUtc().toMilliseconds();
long right = max (oneDateValue, anotherDateValue);
long left = min (oneDateValue, anotherDateValue);
评估精度:
在任何语言中处理日期范围时,我要看的第二件事类似于处理浮点数的方式。对于比较,不要比较是否相等,而是将增量与“可接受的错误级别”进行比较。换句话说,应用程序实际上只关注一定程度的精度,因此请确保仅捕获并考虑该精度:
const int dateTimeResolutionInMs = 86400000; // milliseconds per day
public bool areEssentiallySame(long left, long right) {
// the difference between right and left is less than our precision
// requires, thus dates are effectively the same
return (right - left < dateTimeResolutionInMs);
}
const int dateTimeResolutionInMs=86400000;//毫秒/天
公共布尔基本上是一个名称(左长、右长){
//左右之间的差异小于我们的精度
//需要,因此日期有效
long oneDateValue = oneDate.toUtc().toMilliseconds();
long anotherDateValue = anotherDate.toUtc().toMilliseconds();
long right = max (oneDateValue, anotherDateValue);
long left = min (oneDateValue, anotherDateValue);
const int dateTimeResolutionInMs = 86400000; // milliseconds per day
public bool areEssentiallySame(long left, long right) {
// the difference between right and left is less than our precision
// requires, thus dates are effectively the same
return (right - left < dateTimeResolutionInMs);
}