2010-04-26 10 views
6

में क्रॉन अभिव्यक्ति का उपयोग करके अंतिम निकाल दिया गया समय ढूंढना क्या क्रॉन अभिव्यक्ति से "अंतिम निकाल दिया गया समय" ढूंढने के लिए जावा में कोई तरीका है।जावा

उदा। यदि अब = 25-अप्रैल-2010 10 बजे, क्रॉन अभिव्यक्ति "0 15 10? * *" (क्वार्ट्ज) मुझे 25-अप्रैल-2010 10:15 पूर्वाह्न

नोट: 1) मुझे परवाह नहीं है कि हम उपयोग करते हैं मानक क्रॉन एक्सप्रेशन (यूनिक्स और क्वार्ट्ज की तरह) या कम लोकप्रिय वाले अगर वे मुझे सही "अंतिम निकाल दिया गया समय" 2 प्राप्त कर सकते हैं) यह भी सचमुच "अंतिम फायर टाइम" नहीं है क्योंकि ट्रिगर को निकाल दिया नहीं जा सकता है, लेकिन तर्कसंगत रूप से वहां होना चाहिए यह कहने का एक तरीका बनें जब यह आखिरी बार निकाल दिया गया था।

उत्तर

2

सबसे पहले, मुझे मौजूदा पुस्तकालय से अवगत नहीं है जो इसका समर्थन करता है। क्वार्ट्ज हो सकता है, लेकिन मानक जावा क्लास पुस्तकालय निश्चित रूप से नहीं करते हैं।

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

+0

हाय स्टीफन, आपकी प्रतिक्रिया के लिए धन्यवाद। मैंने अपनी समस्या को दूर करने के लिए अपने प्रश्न के नोट्स में थोड़ी अधिक जानकारी जोड़ दी है। –

1

क्वार्ट्ज क्रॉन अभिव्यक्तियों के लिए कुछ लाइब्रेरी समर्थन प्रतीत होता है।

the Javadoc for the CronExpression class देखें, जिसमें getTimeBefore नामक एक विधि है। आईई,

CronExpression cron = new CronExpression("0 15 10 ? * *"); 
Date today = new Date(); 
Date previousExecution = cron.getTimeBefore(today); 

यह क्वार्ट्ज संस्करण पर निर्भर करता है चाहे यह काम करता हो।

नवीनतम स्रोत (लेखन के समय संस्करण 2.1.0) को देखते हुए इस विधि को लागू नहीं किया गया है और हमेशा शून्य हो जाता है।

2

क्वार्ट्ज के साथ मैंने जो समाधान पाया है, वह ट्रिगर के लिए एक बार अंतराल वापस जाना है और अगले फायरिंग समय की गणना करना है। सभी ट्रिगरों के माध्यम से पुनरावृत्ति करके सबसे हालिया समय जब अतीत में एक ट्रिगर को निकाल दिया जाना चाहिए, तो निर्धारित किया जा सकता है।


प्रत्येक फायरिंग के बीच अंतराल की गणना करें:

Date nextFireTime = trigger.getNextFireTime(); 
Date subsequentFireTime = trigger.getFireTimeAfter(nextFireTime); 
long interval = subsequentFireTime.getTime() - nextFireTime.getTime(); 

अतीत में अंतराल जब तक कि एक समय के लिए अगले फायरिंग समय खोजें:

Date previousPeriodTime = new Date(System.currentTimeMillis() - interval); 
Date previousFireTime = trigger.getFireTimeAfter(previousPeriodTime); 

मैं ने पाया है कि यदि आप उपयोग कर रहे हैं एक CronTrigger यह आपको अतीत में आग का समय बचाने के लिए रोकता है। ट्रिगर के सभी के माध्यम से

Date originalStartTime = trigger.getStartTime(); // save the start time 
Date previousPeriodTime = new Date(originalStartTime.getTime() - interval); 
trigger.setStartTime(previousPeriodTime); 
Date previousFireTime = trigger.getFireTimeAfter(previousPeriodTime); 
trigger.setStartTime(originalStartTime); // reset the start time to be nice 

दोहराएं और एक है कि सबसे हाल ही में अतीत में मिल: इस हल करने के लिए मैं शुरू करने का समय संशोधित है, इसलिए ऊपर टुकड़ा हो जाता है

for (String groupName : scheduler.getTriggerGroupNames()) { 
    for (String triggerName : scheduler.getTriggerNames(groupName)) { 
     Trigger trigger = scheduler.getTrigger(triggerName, groupName); 
     // code as detailed above... 
     interval = ... 
     previousFireTime = ... 
    } 
} 

मैं इसे हेलर विधियों या कक्षाओं में पुन: सक्रिय करने के लिए पाठक को एक अभ्यास के रूप में छोड़ देंगे। मैं वास्तव में उप-वर्गीकृत प्रतिनिधि ट्रिगर में उपर्युक्त एल्गोरिदम का उपयोग करता हूं जिसे मैं पिछले फायरिंग समय द्वारा क्रमबद्ध सेट में रखता हूं।https://github.com/devbhuwan/cron-micro-utils

+2

बाद की आग के बीच का अंतर हमेशा समान नहीं होगा। – Ahamed

0
public class CronMircoUtils { 

    /** 
    * Use this method to calculate previous valid date for cron 
    * @param ce CronExpression object with cron expression 
    * @param date Date for find previous valid date 
    * @return 
    */ 
    public static Date getPreviousValidDate(CronExpression ce, Date date) { 
     try { 
      Date nextValidTime = ce.getNextValidTimeAfter(date); 
      Date subsequentNextValidTime = ce.getNextValidTimeAfter(nextValidTime); 
      long interval = subsequentNextValidTime.getTime() - nextValidTime.getTime(); 
      return new Date(nextValidTime.getTime() - interval); 
     } catch (Exception e) { 
      throw new IllegalArgumentException("Unsupported cron or date", e); 
     } 
    } 
} 

स्रोत कोड, पार्स को मान्य, crons कि आपरेशन की जरूरत का समर्थन करता है स्थानांतरित करने के लिए एक खुला स्रोत जावा पुस्तकालय है। मन अपनी वर्तमान स्थिति में यह थोड़ा त्रुटिपूर्ण है और अधिक जटिल क्रॉन भाव के लिए सही ढंग से गणना नहीं हो सकता है कि में

//Get date for last execution 
DateTime now = DateTime.now(); 
ExecutionTime executionTime = ExecutionTime.forCron(parser.parse("* * * * * * *")); 
DateTime lastExecution = executionTime.lastExecution(now)); 

भालू: एक निश्चित समय बस से पहले एक क्रॉन से पिछली तिथि पाने के लिए।

public class TestJob implements Job { 

    @Override 
    public void execute(JobExecutionContext context) throws JobExecutionException { 

     context.getPreviousFireTime(); 
    } 
} 

आप context.getTrigger().getPreviousFireTime() उपयोग कर रहे हैं, तो आप उस पर चल रहा है नौकरी की ट्रिगर समय होगा:

+0

यह केवल आवधिक फायरिंग के लिए काम करेगा। क्या होता है जब कोई 'बाद में अगला ValidTime' या जब फायरिंग अनियमित होते हैं (उदाहरण के लिए मिनट 10, 12, 11, 17, 37) पर आग लगती है? –

2

cron-utils में

+0

हाय जोओ, यह काम करता है भले ही नौकरी न चलें (उदाहरण: ऑफ़लाइन सर्वर)? – Marin

+1

@NunoMarinho हां, यह केवल एक क्रॉन अभिव्यक्ति से पिछली तारीख की गणना करता है। पुस्तकालय स्वयं क्रॉन अभिव्यक्ति के साथ क्या कर रहा है उसके बारे में कुछ भी नहीं जानता है। यह लाइब्रेरी क्रियाओं या नौकरियों को निष्पादित करने के लिए शेड्यूल नहीं करती है, यह केवल क्रॉन अभिव्यक्तियों के आधार पर तिथियों की गणना करता है। मैंने लंबे समय से इस पुस्तकालय का उपयोग नहीं किया है, सुनिश्चित करें कि यह आपकी आवश्यकताओं के अनुरूप है और इसका उपयोग करने के बाद अपने आवेदन का पूरी तरह से परीक्षण करें। –

+0

ओब्रिगाडो जोओ: डी – Marin

0

मामले में आप org.quartz उपयोग कर रहे हैं, का उपयोग करने के context.getPreviousFireTime();

उदाहरण के लिए संभव है क्षण।