java - पी:कैलेंडर(कोई सत्यापन नहीं)का उपयोग करके प्रारंभिक और प्रारंभ तिथि-समय पर प्रतिबंध लगाएं




ajax jsf primefaces calendar (2)

प्रस्तावना:

मैं जेएसएफ के साथ काम नहीं करता, लेकिन कुछ ऐसी चीजें हैं जो आपको वापस ले जा सकती हैं जहां आप बनना चाहते हैं:

ए) एक मानक कैलेंडर में दिनांक दिनांक के दिनांक भाग के साथ काम करते समय , उपयोग करने पर विचार करें:

someCalendar.set(Calendar.MILLISECOND, 0)

बी) joda-time का उपयोग करने पर विचार करें, क्योंकि यह कई स्थितियों में शुद्धता, प्रदर्शन और उपयोग में आसानी के लिए मानक पुस्तकालय पर अक्सर अनुशंसित ( here , here , और कई अन्य स्थानों ) की सिफारिश की जाती है।

सी) सुनिश्चित करें कि आपका बीन स्कोप प्रत्येक AJAX कॉल (रीडायरेक्ट नहीं कर रहा है, केवल मानक पोस्ट-बैक भेज रहा है, आदि) और प्रत्येक इवेंट हैंडलर चेहरे का संदर्भ प्राप्त कर रहा है (उदाहरण के लिए। FacesContext facesContext = FacesContext.getCurrentInstance(); )

डी) mindate और संभवतः आप की तरह काम नहीं करते हैं, और मुझे उम्मीद नहीं है कि स्वचालित व्यवहार को आसानी से mindate जा सकता है।

जब वे विकल्प उपलब्ध नहीं होते हैं, और आपको अपने पास यह सब कुछ करना है जो आपके पास है:

फिलिसॉफिकल / यूएक्स: पहली चीज जो मैं करूँगा वह तारीखों की जोड़ी से व्यवस्था या परिप्रेक्ष्य की अपेक्षा को हटा देती है। जोड़ी को एक वेक्टर के रूप में न करें जो टाइमलाइन पर एक दिशा का खुलासा करता है या उम्मीद करता है।

  • दूसरे शब्दों में, start या तिथि से पहले या उससे पहले की तारीख से पहले या उससे पहले की तारीख है? नहीं, जैसा कि ऐतिहासिक डेटा की एक क्वेरी के लिए देखा जा सकता है, या उन घटनाओं में सुधार लागू करने के लिए जो अभी तक हो चुके हैं या पहले ही हो चुके हैं?

    यह अर्थ आसानी से उपयोगकर्ता को भ्रमित कर सकता है कि वे 'वापस' या 'आगे से' जा रहे हैं (और आसानी से स्वयं को भ्रमित कर सकते हैं)। इसके बजाय मैं तारीखों की एक जोड़ी के साथ उनके बीच की अवधि के साथ व्यवहार करता हूं, बस a pair of dates या range या एक period जो एक अंतराल घोषित करता है, और किसी भी परिणामी चुने हुए मूल्यों के आधार पर समय रेखा पर उनकी सापेक्ष स्थिति का अनुमान लगाता है । इस तरह आप संबंधित और अंतर्निहित आवश्यकताओं का सम्मान कर सकते हैं कि तिथियां कभी बराबर नहीं होतीं, और बाएं हमेशा बाईं ओर होती है, दाईं ओर दाईं ओर सही होती है।

हम अनुमान लगा सकते हैं कि 'शुरू' या 'से' का अर्थ क्या है, लेकिन हम कुछ अर्थ और सापेक्ष रिश्ते का अनुमान लगा सकते हैं: एक दाएं, बाएं, और एक कालक्रम संबंधी समय रेखा के बीच। नोट: किसी भी गणना या तुलना करने से पहले हमेशा यूटीसी की तारीखों को हल करें।

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

कोयरिंग प्रेसिजन: तीसरा, संकल्प की सीमा के भीतर भी हम मूल्यों में अंतर को कैसे हल कर सकते हैं? (आउट एप्लिकेशन को संभालने या अपेक्षा करने या जरूरतों की तुलना में अधिक सटीकता दी गई थी)।

long diff = value % dateTimeResolutionInMs;

  1. छंटनी: return value - diff;

  2. निकटतम (डब्ल्यू / पूर्वाग्रह): return value + (diff < dateTimeResolutionInMs/ 2) ? -1 * diff : dateTimeResolutionInMs - diff; return value + (diff < dateTimeResolutionInMs/ 2) ? -1 * diff : dateTimeResolutionInMs - diff;

  3. अन्य: किसी भी मूल्य को किसी भी संकल्प या परिशुद्धता में कम करने या विस्तार करने के लिए कई अन्य रणनीतियां हैं

अनुपूरक: जहां तक ​​पोस्ट-बैक / अजाक्स कॉल को calendar तत्व द्वारा निकाली गई घटनाओं के लिए आपके द्वारा अपेक्षित मानों के साथ एक दृश्य वापस करने के लिए कॉल किया जाता है, तो आप उस चिंता को एक नए प्रश्न पर अलग करना चाहेंगे यदि प्रस्तावना में नोट ' आपको कहीं भी नहीं मिलते हैं, और आप निश्चित रूप से जानते हैं कि आपकी बीन ठीक से पंजीकृत और मान्यता प्राप्त है। आपके पास कुछ ब्राउज़र / ब्राउज़र-संस्करण विशिष्ट समस्याएं हो सकती हैं जो अवांछित व्यवहार में योगदान देती हैं, और किसी और चीज की तरह, ज्ञात और अज्ञात दोनों मुद्दे हैं।

हमारे पास उपयोगकर्ता को दो पी: कैलेंडर घटक प्रस्तुत करने की आवश्यकता है, जो प्रत्येक की शुरुआत और समाप्ति तिथि का प्रतिनिधित्व करती है। दोनों डेटाटाइम में तिथियां, घंटे और मिनट होते हैं। प्राइमफेस में पूर्ण mindate , maxdate , minHour , maxHour , minMinute , और minMinute विशेषताएँ उपलब्ध हैं।

अब आवश्यकता है:

शुरुआत डेटाटाइम को अंतराल के बराबर या उसके बराबर कुछ भी सेट करना असंभव है। अंत डेटाटाइम को अंत समय के बराबर या उसके बराबर कुछ भी सेट करना असंभव है।

निम्नलिखित समीकरण सही होना चाहिए:

begin datetime < end datetime

अब हमने निम्नलिखित जेएसएफ की कोशिश की:

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

यहां एक परीक्षा न्यूनतम / अधिकतम विधि (समाप्ति तिथि का दिमाग) है:

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

जैसा कि आप देख सकते हैं, न्यूनतम समाप्ति तिथि वर्तमान में AJAX- चयनित प्रारंभ तिथि है। समाप्ति तिथि को सही तिथि से पहले की आरंभ तिथि को सही ढंग से सेट करने से मना कर दिया जाता है।

समीकरण में समय शामिल करते समय समस्याएं शुरू होती हैं ...

चूंकि पी के इंटरफेस के बाद: कैलेंडर में अलग-अलग तरीके हैं, बीन को तर्क प्रदान करना है:

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 बजे बैठता है और कैलेंडर तिथि 2013-04-20 का चयन तब तक किया जाना चाहिए जब तक कि अंत समय कम से कम 12:35 तक समायोजित नहीं किया जाता है।

पी: कैलेंडर घटक हालांकि यह अब और अब नहीं जान सकता है

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

...

समस्या यह है कि जब उपयोगकर्ता कैलेंडर में एक निश्चित नई समाप्ति तिथि दबाता है, तो दिमागी / maxdate विशेषताएँ उपयोगकर्ता को प्रारंभ तिथि के समान हिट करने के लिए प्रतिबंधित नहीं कर सकती हैं। यदि समाप्ति तिथि का समय अब शुरू होने की तारीख से पहले होता है तो कुछ भी नहीं है जो हम इसके बारे में कर सकते हैं (जो गलत है)।

फॉलोअप समस्या अब यह है कि उपयोगकर्ता कैलेंडर बंद करने में सक्षम है और डीबी में झूठा डेटा डालने के लिए बस सबमिट बटन दबाएं। बेशक, एक वैधकर्ता चलाया जा सकता है / चाहिए, लेकिन हमें किसी भी तरह वैधकर्ता के बिना इसे प्राप्त करना होगा

हम आगे क्या कोशिश कर रहे थे सेट सेट किए setSelectedEndDate( Date selectedEndDate ) को सेट करना था और सेट java.util.Date समय भाग को समायोजित करने के लिए सेट setSelectedEndDate( Date selectedEndDate ) विधियों को उसी दिन था। कुछ इस तरह:

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:calendar की update विशेषता में @this जोड़ने की आवश्यकता है ताकि संबंधित getSelectedBeginDate() और getSelectedEndDate + न्यूनतम / अधिकतम सीमाएं) अपडेट के दौरान कॉल किए जाएंगे।

अपडेट पर @this पर हालांकि पी: कैलेंडर घटकों को भ्रमित कर दिया जाता है, जिससे समय स्लाइडर्स केवल एक बार स्लिम हो जाते हैं। बाद में स्लाइडर घटनाओं को तोड़ दिया जाता है, टूटा व्यवहार करते हैं।

क्यू के

  • आप आम तौर पर इसे हल करने के लिए कैसे जाते हैं?
  • p:remoteCommand का उपयोग कर रहा है p:remoteCommand हम जो चाहते हैं उसे हासिल करने का तरीका?

वैकल्पिक क्यू :

  • प्राइमफेस पी क्यों नहीं किया गया है: कैलेंडर को एक मिनीडेट टाइम और मैक्सडेट टाइम प्रदान करने के लिए लागू किया गया है, जो संभावित रूप से समस्याओं को हल कर सकता है?

मैं शर्त लगाता हूं कि मैंने इस परिदृश्य को पहले ही हल कर लिया है। यदि आप इस दृष्टिकोण को हल करने के लिए प्रबंधित दृष्टिकोण का वर्णन कर सकते हैं (या आंशिक समाधान भी साझा करते हैं) तो मैं बहुत सराहना करता हूं।


जेडीके 9 से शुरू होने वाले javac में यह एक बग है (जिसने स्ट्रिंग कॉन्सटेनेशन के संबंध में कुछ बदलाव किए हैं, जो मुझे संदेह है कि समस्या का हिस्सा है), JDK-8204322 । यदि आप लाइन के लिए संबंधित बाइटकोड देखते हैं:

array[i++%size] += i + " ";

यह है:

  21: aload_2
  22: iload_3
  23: iinc          3, 1
  26: iload_1
  27: irem
  28: aload_2
  29: iload_3
  30: iinc          3, 1
  33: iload_1
  34: irem
  35: aaload
  36: iload_3
  37: invokedynamic #5,  0 // makeConcatWithConstants:(Ljava/lang/String;I)Ljava/lang/String;
  42: aastore

जहां अंतिम aaload सरणी से वास्तविक भार है। हालांकि, हिस्सा

  21: aload_2             // load the array reference
  22: iload_3             // load 'i'
  23: iinc          3, 1  // increment 'i' (doesn't affect the loaded value)
  26: iload_1             // load 'size'
  27: irem                // compute the remainder

जो लगभग अभिव्यक्ति array[i++%size] (वास्तविक भार और स्टोर से कम) से मेल खाता है, वहां दो बार है। यह गलत है, क्योंकि spec jls-15.26.2 में कहता है:

फॉर्म E1 op= E2 की एक यौगिक असाइनमेंट अभिव्यक्ति E1 op= E2 E1 = (T) ((E1) op (E2)) बराबर है, जहां T E1 का प्रकार है, सिवाय इसके कि E1 का मूल्यांकन केवल एक बार किया जाता है।

तो, अभिव्यक्ति array[i++%size] += i + " "; , भाग array[i++%size] मूल्यांकन केवल एक बार किया जाना चाहिए। लेकिन इसका मूल्यांकन दो बार (लोड के लिए एक बार, और दुकान के लिए एक बार) किया जाता है।

तो हाँ, यह एक बग है।

कुछ अपडेट:

बग जेडीके 11 में तय किया गया है और जेडीके 10 में बैक-पोर्ट होगा (लेकिन जेडीके 9 नहीं, क्योंकि अब इसे सार्वजनिक अपडेट नहीं मिलते हैं )।

Aleksey Shipilev जेबीएस पेज पर उल्लेख करता है (और यहां टिप्पणियों में @DidierL):

वर्कअराउंड: -XDstringConcat=inline साथ संकलित करें

यह StringBuilder करने के लिए StringBuilder का उपयोग करने के लिए वापस आ जाएगा, और बग नहीं है।





java ajax jsf primefaces calendar