0

I have a java program which is gonna be manually run every day. Now I want to create an excel file per wek to write in it all tasks of the week

I know how to create a file every day like this:

if(!IoUtils.fileExist("indicators-" + IoUtils.getCurrentDate() + ".xls")){
    IoUtils.createIndicFile("indicators-" + IoUtils.getCurrentDate() + ".xls");
}
else IoUtils.INDIC_FILEPATH = "indicators-" + IoUtils.getCurrentDate() + ".xls";

Here is the function which give me the current date in a specific format:

// IoUtils class
public static String getCurrentDate(){
    LocalDateTime ldt = LocalDateTime.now();
    return DateTimeFormatter.ofPattern("dd-MM-yyyy", Locale.ENGLISH).format(ldt);
}

So how can I change this to only create a file per week ?

I would also like to have the month and the number of the week in the filename like this:

// first monday of january 2018
name = "indicators-week1-01-2018"

// second monday of january 2018
name = "indicators-week2-01-2018"

Thank you

Amadou Beye
  • 2,538
  • 3
  • 16
  • 37

6 Answers6

1

Java provides java.util.concurrent.ScheduledThreadPoolExecutor that can additionally schedule commands to run after a given delay, or to execute periodically.

Scheduler.scheduleWithFixedDelay(task, StartDelay, repeatInterval, TimeUnit.MINUTES);
Vebbie
  • 1,669
  • 2
  • 12
  • 18
  • Please note that if this will be running on multiple instances, a report will be generated for every instance separately. – Sofo Gial Nov 28 '18 at 09:57
  • @SofoGial In the `Runnable` run by the scheduled executor service, it is the job of the programmer to check for the correct date and to check if the file has been written yet for that week. So the executor repeating is a feature, not a problem. – Basil Bourque Nov 28 '18 at 21:18
  • @BasilBourque Absolutely! I have just pointed this out, since I have seen people forgetting this quite often in the last 5 years :) – Sofo Gial Nov 29 '18 at 08:46
1

Executor

Old-school way used the Timer class.

New-school way uses the Executors framework that handle the nitty-gritty details of scheduling tasks on background threads.

Set up an executor to run a Runnable every few hours. That task checks the current moment. If the day-of-week of the current date is a Monday, and if your file is not yet written, write it. If not, then let the Runnable expire. The scheduled executor service will run again in a few hours, and repeat again and again.

The first step is to get the current date.

A time zone is crucial in determining a date. For any given moment, the date varies around the globe by zone. For example, a few minutes after midnight in Paris France is a new day while still “yesterday” in Montréal Québec.

If no time zone is specified, the JVM implicitly applies its current default time zone. That default may change at any moment during runtime(!), so your results may vary. Better to specify your desired/expected time zone explicitly as an argument.

Specify a proper time zone name in the format of continent/region, such as America/Montreal, Africa/Casablanca, or Pacific/Auckland. Never use the 2-4 letter abbreviation such as EST or IST as they are not true time zones, not standardized, and not even unique(!).

ZoneId z = ZoneId.of( "America/Montreal" ) ;
LocalDate today = LocalDate.now( z );

from that get the current day of the week.

DayOfWeek dow = today.getDayOfWeek() ;

If today is a Monday, then see if file has yet been written. If not, write it.

if( dow.equals( DayOfWeek.MONDAY ) ) {
    if( file not written ) { write file }
}

Put that all together into a named method.

private void writeFileOnMonday ( ) {
    ZoneId z = ZoneId.of( "America/Montreal" );
    LocalDate today = LocalDate.now( z );
    DayOfWeek dow = today.getDayOfWeek();
    if ( dow.equals( DayOfWeek.MONDAY ) ) {
        if ( file not written ){ write file }
    }
}

Harness that workload in a scheduled executor service. Specify how many hours to wait between runs. If we specify to run our task every 3 hours, then, logic dictates, our weekly file will be written sometime between midnight and 3 AM on each Monday.

One big catch with a scheduled executor service: The repeating task execution comes silently to a halt if on any run a Throwable (Exception or Error) is thrown by your task, and reaches the executor. So always wrap your task in a try-catch. See this Question.

ScheduledExecutorService scheduledExecutorService = Executors.newSingleThreadScheduledExecutor();  // Convenience method to produce an executor service.

ScheduledFuture scheduledFuture =          // A handle to check the status of your task. May or may not be useful to you.
        scheduledExecutorService
                .scheduleWithFixedDelay( new Runnable() {  // Implement the `Runnable` interface as your task. 
                                             @Override
                                             public void run ( ) {
                                                 try {
                                                     writeFileOnMonday();
                                                 } catch (Exception e ) {
                                                     … handle unexected exception
                                                 }
                                             }
                                         } ,
                        0 ,                 // Initial delay
                        3 ,                 // Delay between runs.
                        TimeUnit.HOURS );   // Unit of time meant for the pair of delay numbers above.

Search Stack Overflow for more info, as all this has been covered many many times already.


About java.time

The java.time framework is built into Java 8 and later. These classes supplant the troublesome old legacy date-time classes such as java.util.Date, Calendar, & SimpleDateFormat.

The Joda-Time project, now in maintenance mode, advises migration to the java.time classes.

To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310.

You may exchange java.time objects directly with your database. Use a JDBC driver compliant with JDBC 4.2 or later. No need for strings, no need for java.sql.* classes.

Where to obtain the java.time classes?

The ThreeTen-Extra project extends java.time with additional classes. This project is a proving ground for possible future additions to java.time. You may find some useful classes here such as Interval, YearWeek, YearQuarter, and more.

Basil Bourque
  • 303,325
  • 100
  • 852
  • 1,154
0

Create a quartz cron job scheduler 0 0 12 ? * MON. This will schedule job on every Monday at 12.00 PM.

salz
  • 81
  • 12
0

Since you're using LocalDateTime, you can do a check using getDayOfWeek method.

A example such as

if(LocalDateTime.now().getDayOfWeek() == DayOfWeek.MONDAY){
  // File Creation Logic ...
}    
Samuel Kok
  • 585
  • 8
  • 16
0

use calender API, calendar.get(Calendar.DAY_OF_WEEK) will return int 2 for Monday.

import java.util.Calendar;

if(calendar.get(Calendar.DAY_OF_WEEK) == 2)
  if(!IoUtils.fileExist("indicators-" + IoUtils.getCurrentDate() + ".xls")){
      IoUtils.createIndicFile("indicators-" + IoUtils.getCurrentDate() + ".xls");
  }
  else IoUtils.INDIC_FILEPATH = "indicators-" + IoUtils.getCurrentDate() + ".xls";
  • FYI, the terribly troublesome old date-time classes such as [`java.util.Date`](https://docs.oracle.com/javase/10/docs/api/java/util/Date.html), [`java.util.Calendar`](https://docs.oracle.com/javase/10/docs/api/java/util/Calendar.html), and `java.text.SimpleDateFormat` are now [legacy](https://en.wikipedia.org/wiki/Legacy_system), supplanted by the [*java.time*](https://docs.oracle.com/javase/10/docs/api/java/time/package-summary.html) classes built into Java 8 and later. See [*Tutorial* by Oracle](https://docs.oracle.com/javase/tutorial/datetime/TOC.html). – Basil Bourque Nov 28 '18 at 20:04
0
Calendar cal = Calendar.getInstance();
cal.setFirstDayOfWeek(Calendar.MONDAY);
int week = cal.get(Calendar.WEEK_OF_YEAR);

String expectedFileName = "indicators-week"+week+"-whateveryouwant-"+cal.get(Calendar.YEAR);

Then you can check and if the file exists , write to the same file, if file does not exist you will create a new file with the expect file name and write to that new file.but based on the requirement year break should be handled properly

hunter
  • 3,963
  • 1
  • 16
  • 19
  • FYI, the terribly troublesome old date-time classes such as [`java.util.Date`](https://docs.oracle.com/javase/10/docs/api/java/util/Date.html), [`java.util.Calendar`](https://docs.oracle.com/javase/10/docs/api/java/util/Calendar.html), and `java.text.SimpleDateFormat` are now [legacy](https://en.wikipedia.org/wiki/Legacy_system), supplanted by the [*java.time*](https://docs.oracle.com/javase/10/docs/api/java/time/package-summary.html) classes built into Java 8 and later. See [*Tutorial* by Oracle](https://docs.oracle.com/javase/tutorial/datetime/TOC.html). – Basil Bourque Nov 28 '18 at 20:04