quartz cron trigger first fire time - quartz-scheduler

Is there any way setting crontrigger to begin after a specific date .That is crontrigger going to fire after a specific date using its cron expression.I try using crontrigger starttime and firstfire time but not worked.I can do this with using another trigger but i think there should be another way.
this is cron expression
0 0/5 * * * ?
i.e. at minutes (5,10,15,...00) not at now+5
this is log program writes
Trigger should start at Fri May 27 21:03:31 EEST 2011 // i expect it run on this time
Job start at Fri May 27 20:55:00 EEST 2011 //it ignore start time
Job start at Fri May 27 21:00:00 EEST 2011
Job start at Fri May 27 21:05:00 EEST 2011
public CronTrigger scheduleJob(RemoteJob job, String cronExpression,Date firstFireTime) throws SchedulerException, ParseException {
JobDetail jobDetail = new JobDetail(job.getDescription(), job.getName(), job.getClass());
CronTrigger crTrigger = new CronTrigger(
"cronTrigger", job.getName(), cronExpression);
scheduler.scheduleJob(jobDetail, crTrigger);
try{
Calendar c=Calendar.getInstance();
c.add(Calendar.MINUTE, 10);
firstFireTime=c.getTime();
FileWriter writer=new FileWriter("/opt/scheduler.cron",true);
writer.write("Trigger should start at " +c.getTime().toString()+"\n\n");
writer.close();
}catch(Exception e){
}
crTrigger.setStartTime(firstFireTime);
crTrigger.setMisfireInstruction(CronTrigger.MISFIRE_INSTRUCTION_DO_NOTHING);
return crTrigger;
}
this is job executed by trigger .
public class ExternalJob extends RemoteJob {
private static final Logger _logger = Logger.getLogger(ExternalJob.class.getName());
private static ExternalStorageProcessor processor = new ExternalStorageProcessor();
private ExternalTask task;
private static final String tempPath = "/opt/itaptemp/";
private String name;
private String description;
private static final long MARK=1L;
public ExternalJob(String name, String description) {
public void execute(JobExecutionContext context) throws JobExecutionException {
try{
Calendar c=Calendar.getInstance();
FileWriter writer=new FileWriter("/opt/scheduler.cron",true);
writer.write("Job start at " +c.getTime().toString()+"\n");
writer.close();
}catch(Exception e){
}

The problem is that you are using a cron which fires a every even minute beginng a 0 minute (0 0/5 * * * ? ).
You should set the start date alse to even minutes. Therefore you can use DateBuilder.EvenMinuteDateBefore(StartTime).
So if your startime was... Fri May 27 20:55:31 ... the method DateBuilder.EvenMinuteDateBefore(StartTime) will convert it to ...
Fri May 27 20:55:00.
Then your schedule will look like:
Job start at Fri May 27 20:55:00 EEST 2011
Job start at Fri May 27 21:00:00 EEST 2011
Job start at Fri May 27 21:05:00 EEST 2011

Set the startTime property to the future Date at which you want the schedule (expression) to start applying.
I see you say that you tried that and it didn't work, but it certainly should, so please try again.
CronTrigger ct = new CronTrigger("foo", "goo", "0 0/10 * * * ?"); // fire every ten minutes, all day every day
// construct a date of March 17, 2012 10:03:00
Calendar futureDate = Calendar.getInstance();
futureDate.set(Calendar.YEAR, 2012);
futureDate.set(Calendar.MONTH, GregorianCalendar.MARCH);
futureDate.set(Calendar.DAY_OF_MONTH, 17);
futureDate.set(Calendar.HOUR_OF_DAY, 10);
futureDate.set(Calendar.MINUTE, 3);
futureDate.set(Calendar.SECOND, 0);
futureDate.set(Calendar.MILLISECOND, 0);
// use the date as the startTime
ct.setStartTime(futureDate.getTime());
// check what time the trigger will first fire
List fireTimes = TriggerUtils.computeFireTimes(ct, null, 1);
Date firstFireTime = (Date) fireTimes.iterator().next();
System.out.println("First fire time: " + firstFireTime);
This results in:
First fire time: Sat Mar 17 10:10:00 MDT 2012

Related

Spring batch - Can we read items from database using date column in a loop

I want to read data for last 30 days from database for each day..
ItemReader - Read data for each day
ItemProcessor - Process data for each day
ItemWriter - Write the processed data into database.
I want to repeat this process till date..
public boolean processTicketStatistics() {
LocalDate startDate = LocalDate.now().minus(Period.ofDays(30));
LocalDate endDate = LocalDate.now().plus(Period.ofDays(1));
for (LocalDate d = startDate; d.isBefore(endDate); d = d.plusDays(1)) {
TicketStatistics statistics = new TicketStatistics();
statistics.setDate(localDateTimeToDate(d.atStartOfDay()));
statistics.setTickets(ticketRepository.count(TicketSpecification.ticketHasDateRange(
localDateTimeToDate(d.atStartOfDay()),
localDateTimeToDate(d.atTime(LocalTime.MAX)))));
ticketStatisticsRepository.save(statistics);
}
return true;
}
Can you please help me how to achieve this in Spring batch?
I would create a job that processes the data of a given day (ie the day is an identifying job parameter) and launch a job instance per day, for example:
LocalDate startDate = LocalDate.now().minus(Period.ofDays(30));
LocalDate endDate = LocalDate.now().plus(Period.ofDays(1));
for (LocalDate d = startDate; d.isBefore(endDate); d = d.plusDays(1)) {
JobParameters jobParameters = new JobParametersBuilder()
.addDate("date", toDate(d)) // TODO implement toDate to convert LocalDate to Date
.toJobParameters();
jobLauncher.run(job, jobParameters);
}
If the processing of each day is independent from other days (which I guess is the case), you can launch all job instances in parallel by configuring an asynchronous TaskExecutor (like a ThreadPoolTaskExecutor with a pool of 30 threads) in your JobLauncher.

offset time (time with time zone) in jdbc PostgreSQL

I am trying to save and retrieve java.time.OffsetTime into PostgreSQL version 10.5, JDBC driver latest (v 42.2.5).
The Offset time is saved but with an invalid offset (it takes app server offset instead of the passed offset).
According to: https://jdbc.postgresql.org/documentation/head/8-date-time.html TIME WITH TIMEZONE is not supported (yet?).
Note that ZonedDateTime, Instant and OffsetTime / TIME [ WITHOUT
TIMEZONE ] are not supported
My question, is I want to save offset time into Postgres, so what are alternatives?
Note, I only care about time (it is actually a timetable) but I need to know the offset as well for comparing reasons with current_time.
My Example:
public class Customer {
#Id
#GeneratedValue
private Long id;
private String name;
#Column(columnDefinition = "time with time zone")
private OffsetTime serviceTime;
#Column(columnDefinition = "timestamp with time zone")
private OffsetDateTime serviceDateTime;
private Instant createdDate = Instant.now();
}
The main:
{
OffsetTime serviceTime = OffsetTime.parse("10:00+02:00");
OffsetDateTime serviceDateTime = OffsetDateTime.now().with(serviceTime);
System.out.println(serviceTime);
System.out.println(serviceDateTime);
Customer customer = new Customer().withName("wael")
.withServiceTime(serviceTime)
.withServiceDateTime(serviceDateTime);
System.out.println("customer: " + customer);
customerRepository.save(customer);
}
{
Customer dbCustomer = customerRepository.findById(1L).get();
OffsetTime dbServiceTime = dbCustomer.getServiceTime();
OffsetDateTime dbServiceDateTime = dbCustomer.getServiceDateTime();
System.out.println(dbServiceTime);
System.out.println(dbServiceDateTime);
System.out.println("from db customer: " + dbCustomer);
}
Database:
id created_date name service_date_time service_time
1 2018-10-15 10:38:27.814000 wael 2018-10-15 08:00:00.000000 10:00:00 +03:00
Output:
10:00+02:00
2018-10-15T10:00+02:00
customer: Customer(id=null, name=wael, serviceTime=10:00+02:00, serviceDateTime=2018-10-15T10:00+02:00, createdDate=2018-10-15T07:10:59.900Z)
10:00+03:00
2018-10-15T11:00+03:00
from db customer: Customer(id=1, name=wael, serviceTime=10:00+03:00, serviceDateTime=2018-10-15T11:00+03:00, createdDate=2018-10-15T07:10:59.900Z)
Note, my machine timezone is +3 (hence the printed information from db is +3), and my database server is a docker image with UTC datetime settings.
Observations:
The OffsetDatetime is saved correctly (as UTC) and retrieved correctly.
The OffsetTime is saved incorrect (it should be 10:00:00 +02:00 or 11:00:00 +03:00 or even 08:00:00 +00:00 not 10:00:00 +03:00, and retrieved incorrect!)
With JPA 2.2, you can also use OffsetTime in Postgresql.
#Column(name = "offset_time", columnDefinition = "TIME WITH TIME ZONE")
private OffsetTime offsetTime;
That's how it is stored in my database: 22:00:00.000000 +02:00

How to subtract Hijrah year from a Hijrah Date in Java 8 Date API

I want to display the Ramadan 2017 start and end dates. I tried writing code using the HijrahChronology built into Java 8 and later, with HijrahDate class.
import java.time.LocalDate;
import java.time.chrono.HijrahDate;
import java.time.temporal.ChronoField;
import java.time.temporal.TemporalAdjusters;
public class Ramdan {
public static void main(String[] args) {
HijrahDate ramdanDate = HijrahDate.now().with(ChronoField.DAY_OF_MONTH, 1).with(ChronoField.MONTH_OF_YEAR, 9);
LocalDate ramdanStart = LocalDate.from(ramdanDate);
LocalDate ramdanEnd = LocalDate.from(ramdanDate.with(TemporalAdjusters.lastDayOfMonth()));
System.out.println("Ramdan 2017");
System.out.println(ramdanStart);
System.out.println(ramdanEnd);
}
}
But it obviously prints out the dates for current year, i.e., 2018.
Output
Ramdan 2017
2018-05-16
2018-06-14
I tried many things like minus years, or doing temporal adjustments but nothing helped. Can someone suggest a cool way of achieving it?
I’m not sure it’s the perfect way to do it, but this works for me and doesn’t seem all too complicated:
ramdanDate = ramdanDate.with(ChronoField.YEAR, ramdanDate.get(ChronoField.YEAR) - 1);
With this line inserted before you convert to LocalDate your code now prints:
Ramdan 2017
2017-05-27
2017-06-24
Edit:
Suppose even if (in case you got a Gregorian year that overlaps with
two instances of Ramadan, finding both) is desired...I cannot think of
a way of achieving it. Can you suggest?
Keep your tongue straight in your mouth:
public static void printRamdanDates(int gregorianYear) {
LocalDate gregDate = LocalDate.ofYearDay(gregorianYear, 1);
HijrahDate ramdanDate = HijrahDate.from(gregDate)
.with(ChronoField.DAY_OF_MONTH, 1)
.with(ChronoField.MONTH_OF_YEAR, 9);
LocalDate ramdanStart = LocalDate.from(ramdanDate);
LocalDate ramdanEnd = LocalDate.from(ramdanDate.with(TemporalAdjusters.lastDayOfMonth()));
// if in previous Gregorian year, skip
while (ramdanEnd.getYear() < gregorianYear) {
ramdanDate = ramdanDate.with(ChronoField.YEAR, ramdanDate.get(ChronoField.YEAR) + 1);
ramdanStart = LocalDate.from(ramdanEnd);
ramdanEnd = LocalDate.from(ramdanDate.with(TemporalAdjusters.lastDayOfMonth()));
}
if (ramdanStart.getYear() > gregorianYear) { // in following Gregorian year
System.out.println("No Ramdan in " + gregorianYear);
} else {
System.out.println("Ramdan " + gregorianYear);
do {
System.out.println(ramdanStart);
System.out.println(ramdanEnd);
ramdanDate = ramdanDate.with(ChronoField.YEAR, ramdanDate.get(ChronoField.YEAR) + 1);
ramdanStart = LocalDate.from(ramdanDate);
ramdanEnd = LocalDate.from(ramdanDate.with(TemporalAdjusters.lastDayOfMonth()));
} while (ramdanStart.getYear() == gregorianYear);
}
}
If I feed 2017 to the above method, it gives the same result as before:
printRamdanDates(2017);
Output:
Ramdan 2017
2017-05-27
2017-06-24
But try, for example, 2000 or 2030 when Ramadan happens twice in the Gregorian/ISO year.
printRamdanDates(2000);
printRamdanDates(2030);
Output:
Ramdan 2000
1999-12-09
2000-01-07
2000-11-27
2000-12-26
Ramdan 2030
2030-01-05
2030-02-03
2030-12-26
2031-01-23

Showing the Date in correct format in a Smartgwt project

I am getting a date from JSON in the following format 22 07 2014 12:04:12.
This is the code I have written:
field.setCellFormatter(new CellFormatter() {
#Override
public String format(Object arg0, ListGridRecord arg1, int arg2, int arg3) {
final DateTimeFormat fmt = DateTimeFormat.getFormat("dd MM yyyy hh:mm");
final Date date = (Date) arg0;
arg1.setAttribute(name, date);
return fmt.format(date);
});
where field is the Date field in ListGrid.
But this displays a blank field in the ListGrid. I can't figure out a way to show it in the following format:
22 Jul 2014 00:04
According to the documentation, the server must send dates with the following format:
dateField: "2007-04-22"
timeField: "11:07:13"
dateTimeField: "2007-04-22T11:07:13"
dateTimeField: "2007-04-22T11:07:13.582"
You can achieve that with this snippet:
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");
sdf.format(myDate);
Then, in the client side, you can format the date with SmartGWT:
myListGridField.setDateFormatter(DateDisplayFormat.TOEUROPEANSHORTDATETIME);

Quartz with couple of jobs but only one running

I have quartz schedule with couple of jobs but only one (1st one) is running. Even if I try to force the second job to run it doesn't.
// The Quartz Scheduler
Scheduler scheduler = StdSchedulerFactory.getDefaultScheduler();
JobDetailImpl jobDetail = new JobDetailImpl();
jobDetail.setJobClass(SchedulerJob.class);
jobDetail.setName("4HR");
jobDetail.setGroup("G");
// Initiate CronTrigger with its name and group name
CronTriggerImpl cronTrigger = new CronTriggerImpl();
cronTrigger.setName("4HR");
cronTrigger.setGroup("G");
// setup CronExpression
String CRON_EXPRESSION = "0 0 0/4 * * ?"; // fire every 4 hours
CronExpression cexp = new CronExpression(CRON_EXPRESSION);
// Assign the CronExpression to CronTrigger
cronTrigger.setCronExpression(cexp);
// schedule a job with JobDetail and Trigger
scheduler.scheduleJob(jobDetail, cronTrigger);
JobDetailImpl oneHRJob = new JobDetailImpl();
oneHRJob.setJobClass(Run1HRSchdule.class);
oneHRJob.setName("Job1HR");
oneHRJob.setGroup("G");
CronTriggerImpl oneHRTrigger = new CronTriggerImpl();
oneHRTrigger.setName("Trigger1HR");
oneHRTrigger.setGroup("G");
// Assign the CronExpression to CronTrigger
String CRON_EXPRESSION_1HR = "0 0 0/1 * * ?"; // fire every 1 hour
oneHRTrigger.setCronExpression( new CronExpression(CRON_EXPRESSION_1HR) );
// schedule a job with JobDetail and Trigger
scheduler.scheduleJob(oneHRJob, oneHRTrigger);
// start the scheduler
System.out.println ("Starting Scheduler");
scheduler.start();
System.out.println ("Scheduler started:" + scheduler.isStarted() );
scheduler.triggerJob( oneHRJob.getKey() );
I have tried changing the cron expression but hasn't helped.
What could I be doing wrong?