相互限制使用对开始和结束日期,时间:日历(没有验证) [英] Mutually restricting begin and end date-times using p:calendar (no validation)

查看:458
本文介绍了相互限制使用对开始和结束日期,时间:日历(没有验证)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我们有一个条件,present两个p:日历组件的用户,再presenting开始和结束每日期。这两个日期时间有日期,小时和分钟。 PrimeFaces拥有完善为MinDate 的maxDate minHour maxHour minMinute minMinute 属性可用。

We have a requirement to present two p:calendar components to the user, representing a start and end date each. Both datetimes have dates, hours and minutes. PrimeFaces has perfect mindate, maxdate, minHour, maxHour, minMinute, and minMinute attributes available.

要求现在是:

这是不可能的开始日期时间设定为任何大于或等于结束日期时间。 这是不可能的结束日期时间设定为任何小于或等于结束日期时间。

It is impossible to set the start datetime to anything greater than or equal to the end datetime. It is impossible to set the end datetime to anything less than or equal to the end datetime.

下面的公式应持有正确的:

The following equation should hold true:

begin datetime < end datetime

现在,我们尝试了以下JSF:

Now we tried the following JSF:

<p:calendar id="begin-date"
            value="#{debugManager.selectedBeginDate}"
            mindate="#{debugManager.minBeginDate}"
            maxdate="#{debugManager.maxBeginDate}"
            maxHour="#{debugManager.maxBeginHour}"
            maxMinute="#{debugManager.maxBeginMinute}"
            pattern="yyyy-MM-dd HH:mm"
            showButtonPanel="true"
            readonlyInput="true"
            navigator="true"
            showOn="button"
            required="true">
    <p:ajax event="dateSelect" update="end-date" />
</p:calendar>

<p:calendar id="end-date"
            value="#{debugManager.selectedEndDate}"
            mindate="#{debugManager.minEndDate}"
            minHour="#{debugManager.minEndHour}"
            minMinute="#{debugManager.minEndMinute}"
            pattern="yyyy-MM-dd HH:mm"
            showButtonPanel="true"
            readonlyInput="true"
            navigator="true"
            showOn="button">
    <p:ajax event="dateSelect" update="begin-date" />
</p:calendar>

下面是一个示例性最小/最大方法(的结束日期为MinDate):

Here's an examplary min/max method (mindate of end-date):

public Date getMinEndDate()
{
    return this.getSelectedBeginDate();
}

正如你所看到的,最小的结束日期是当前AJAX选择的开始日期。正确设定结束日期不允许设定开始日期过去的结束日期。

As you can see, the minimum end date is the currently AJAX-selected begin date. Setting an end date correctly disallows setting the begin date past the end date.

该问题涉及到时间的公式时开始...

The problems start when involving the time into the equation...

由于P接口:日历有不同的方法,这个bean必须提供的逻辑:

Since the interface of p:calendar has separate methods, the bean has to provide the logic:

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 )的开始小时。

This basically only says if a begin date has been set and it the begin and end dates are currently the same, restrict the selectable end hour (minHour of end-date) to the begin hour.

操作:

Set the begin datetime to 2013-04-20 12:34 (legit)
Set the end   datetime to 2013-04-22 00:00 (legit)

现在的时间结束日期坐在00:00选择日历日期2013年4月20日,应只要结束时间以某种方式调整为至少12时35允许

Now the time for end date sits on 00:00 and selecting a calendar date 2013-04-20 should be allowed as long as the end time is somehow adjusted to at least 12:35.

该号码:日历组件但是不知道这一点,现在

The p:calendar component however cannot know this and now

sets the end datetime to 2013-04-20 00:00 (legit, but false)

...

现在的问题是,当用户presses日历中的某个新的结束日期,为MinDate /的maxDate属性无法限制用户打一样的开始日期。如果结束日期的时间现在恰好是在相同的开始日期的时间之前还有,我们可以做些什么(这是错误的)。

The problem now is that when the user presses a certain new end date in the calendar, the mindate/maxdate attributes cannot restrict the user to hit the the same as the begin date. If the end date time now happens to be before the same begin date's time there's nothing we can do about it (which is wrong).

后续任务现在的问题是,用户能够关闭日历,只是preSS提交按钮插入虚假数据进入数据库。当然,一个验证器可以/应该运行,但我们必须以某种方式实现这一目标没有验证

The followup problem now is that the user is able to close the calendar and just press the submit button to insert false data into the DB. Of course, a validator could/should be run, but we have to somehow achieve this without a validator.

什么我们接下来想是修补 setSelectedBeginDate(日期selectedBeginDate) setSelectedEndDate(日期selectedEndDate)方法调整设定 java.util.Date 时间部分,如果日期是在同一天。事情是这样的:

What we were trying next was to patch the setSelectedBeginDate( Date selectedBeginDate ) and setSelectedEndDate( Date selectedEndDate ) methods to adjust the set java.util.Date time portions if the dates were on the same day. Something like this:

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 ) );
        }
    }
}

这需要我们添加的每个的p @this 更新属性:日历使得各个吸气剂( getSelectedBeginDate() getSelectedEndDate +最小/最大限制器)将更新期间被调用。

This required us to add @this to the update attribute of each p:calendar so that the respective getters (getSelectedBeginDate() and getSelectedEndDate + the min/max limiters) will be called during update.

上的更新放置一个 @this 然而,混淆了号码:日历组件,使时间滑块滑动的唯一一次。随后滑块事件被简单地忽略,表现打破了。

Placing an @this on the update however confuses the p:calendar components, making the time sliders only slidable once. Subsequent slider events are simply ignored, behaving broken.

问的

  • 你怎么通常解决办法吗?
  • 是使用号码:?remoteCommand 来达到我们想要的方式
  • How do you generally approach solving this?
  • Is using p:remoteCommand the way to achieve what we want?

可选性Q

  • 为什么没有在PrimeFaces号码:?日历得到实施,以提供单一minDateTime和maxDateTime,这有可能解决这些问题,在手

我敢打赌,这种情况下,我描述已经被解决。我将十分AP preciate如果你能描述的方法,你设法解决这个问题(甚至共享一部分的解决方案)。

I bet this scenario I described has already been solved before. I'd very much appreciate if you could describe the approach you managed to solve this (or even share a partly solution).

推荐答案

preface:

我不和JSF工作,但也有几件事情,可能引导你回到你想成为:

I don't work with JSF, but there are a couple of things that might steer you back to where you want to be:

一)时,<一个href="http://stackoverflow.com/questions/13198609/java-calendar-getting-difference-between-two-dates-times-off-by-one">working以日期时间的标准日历只是日期部分,可以考虑使用:

a) when working with just the date portion of a dateTime in a standard calendar, consider using:

someCalendar.set(Calendar.MILLISECOND, 0)

b)考虑使用乔达时间的,因为它似乎经常推荐(<一href="http://stackoverflow.com/questions/589870/should-i-use-java-date-and-time-classes-or-go-with-a-3rd-party-library-like-joda/589940#589940">here, <一href="http://stackoverflow.com/questions/589870/should-i-use-java-date-and-time-classes-or-go-with-a-3rd-party-library-like-joda">here和许多其他地方)以上的正确性,性能和易用性在很多情况下使用的标准库。

b) consider using joda-time, as it seems to be frequently recommended (here, here , and many other places) over the standard library for correctness, performance, and ease of use in many situations.

三)确保你的bean范围存活的每一个AJAX调用(而不是重定向,只能发送标准的后背上,等),每个事件处理程序越来越faces上下文(如 FacesContext中的FacesContext = FacesContext中.getCurrentInstance();

c) Make sure your bean scope is surviving each ajax call (not redirecting, only sending standard post-backs, etc) and each event handler is getting the faces context (eg. FacesContext facesContext = FacesContext.getCurrentInstance();)

D)为MinDate 之类的可能不工作像你期望的那样,我不指望自动行为可以说是相当这么容易插话。

d) mindate and the like probably don't work like you expect , and I don't expect that automatic behavior can be quite so easily interjected.

当这些选项不可用,你必须做这一切你自己与你有什么:

Philisophical / UX:的 我会做的第一件事就是从日期对去除安排或透视的期望。不要把两人的暴露或预计在时间轴上的方向的矢量。

Philisophical / UX: The first thing I would do is remove the expectation of arrangement or perspective from the pair of dates. Don't treat the pair as a vector that exposes or expects a direction on the timeline.

  • 在换句话说,是一个启动日期总是比小于或更早版本的结束日期?没有,可以看出对于历史数据的查询,或用于施加校正到已经或者尚未发生或事件已经发生了什么?

  • In other words, is a start or from date always less than or earlier than an end or to date? No, as can be seen for a query of historical data, or for applying corrections to events that have either yet to happen or have already happened?

这内涵很容易混淆用户是否它们是从正向'走出'回'或(和容易混淆自己)。相反,我会像对待日期对他们之间的时间,期间只是简单地说日期对范围声明的间隔,并推断其根据任何因此选择的值在时间轴上的相对位置。通过这种方式,你可以兑现各自的和内在要求的日期永远是平等的,左边是一直到左边,总是要的权利。

This connotation can easily confuse a user as to whether they are going 'back to' or 'forward from' (and can easily confuse yourself). Instead I would treat a pair of dates with a time-period between them as just and simply that a pair of dates or a range or a period that declares an interval, and infer their relative position on the timeline depending on the any consequently chosen values. In this way you can honor the respective and inherent requirements that the dates never be equal, and the left is always to the left, the right always to the right.

我们不能'从'手段推断出'开始'和,但我们可以推断出一些意义和相对关系:按时间顺序排列在时间轴上的一个右,左,和一个。 注意:始终做任何计算或比较之前解决日期UTC

We can't infer what 'start' or 'from' means, but we can infer some meaning and relative relationship: a right, a left, and a between on a chronological timeline. Note: Always resolve dates to UTC before doing any calculation or comparison.

long oneDateValue = oneDate.toUtc().toMilliseconds();
long anotherDateValue = anotherDate.toUtc().toMilliseconds();

long right = max (oneDateValue, anotherDateValue);
long left = min (oneDateValue, anotherDateValue);

评估precision:的 第二件事我会找一个日期范围在任何语言中工作时,在类似于您可能如何处理浮点数。为了比较,不比较平等,而是增量比较可接受误差水平。换句话说,该应用程序是真的只关心有一定程度的precision,所以要确保只有precision被捕获并认为:

Evaluating Precision: The second thing I would look at when working with a range of dates in any language is similar to how you might deal with floating point numbers. For comparisons, do not compare for equality, but instead compare the delta to an "acceptable error level". In other words, the application is really only concerned with a certain degree of precision, so make sure that only that precision is captured and considered:

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);
}

强制转换precision:的 第三,我们怎么解决,即使该决议的范围内的值差异? (出申请被赋予了更多的precision比它可以处理或期待或需要)。

Coercing Precision: Thirdly, how do we resolve the difference in values even if within the range of the resolution? (Out application was given more precision than it can handle or expect or needs).

长差异=值%dateTimeResolutionInMs;

  1. 截断:返回值 - 差异;

最近的(W /偏置):返回值+(DIFF&LT; dateTimeResolutionInMs / 2)? -1 *差异:dateTimeResolutionInMs - 差异;

Nearest (w/bias): return value + (diff < dateTimeResolutionInMs/ 2) ? -1 * diff : dateTimeResolutionInMs - diff;

其他:还有很多其他的策略,无论是收缩或扩张的值到preferred分辨率或precision

Others: there are lots of other strategies for either shrinking or expanding a value to a preferred resolution or precision

附录:的 至于获得后背上/ Ajax调用返回与你期望的由日历元素触发的事件中值的视图,你可能要分开这一关切关闭以一个新的问题,如果在preface该说明并没有得到你的任何地方,你know对于某些bean的正确注册和认可。你可能有利于不需要的行为,象别的,有问题的一些浏览器/浏览器版本的具体问题,已知和未知的。

Addendum: As far as getting post-backs/Ajax calls to return a view with the values you expect for the events fired by a calendar element, you may want to separate that concern off to a new question if the note in the preface didn't get you anywhere, and you know for certain your bean is properly registered and recognized. You may have some browser/browser-version specific issues that contribute to the undesired behavior, and like anything else, there are issues, both known and unknown.

这篇关于相互限制使用对开始和结束日期,时间:日历(没有验证)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆