/* package whatever; // don't place package name! */

import java.util.*;
import java.lang.*;
import java.io.*;

    import java.time.ZoneId;
    import java.time.ZonedDateTime;
    import java.time.format.DateTimeFormatter;
    import java.time.format.FormatStyle;
    import java.util.Locale;
    import java.util.concurrent.Executors;
    import java.util.concurrent.ScheduledExecutorService;
    import java.util.concurrent.ScheduledFuture;
    import java.util.concurrent.TimeUnit;

/* Name of the class has to be "Main" only if the class is public. */
class Ideone
{


 public static void main ( String[] args ) {
            Ideone app = new Ideone ();
            app.doIt ();
        }

        private void doIt () {
            System.out.println ( "INFO - Ideone::doIt - Running." );
            BeeperControl bc = new BeeperControl ();
            bc.beepRegularly ();  // Ask that object to launch the background thread to tell time repeatedly.
            try {
                Thread.sleep ( TimeUnit.MINUTES.toMillis ( 5 ) ); // Run for five minutes and then shutdown this main thread and the background thread too.
                bc.halt ();  // Ask that object to stop the background thread.
            } catch ( InterruptedException ex ) { // This main thread is either being woken-from-sleep or stopped.
                System.out.println ( "INFO - Ideone::doIt - main thread of Ideone app interrupted." );
                bc.halt ();  // Ask that object to stop the background thread.
            }
        }

        class BeeperControl {

            private final ScheduledExecutorService scheduler = Executors.newScheduledThreadPool ( 1 );
            private final ZoneId zoneId = ZoneId.of ( "America/Montreal" );
            private final Locale locale = Locale.CANADA_FRENCH;
            //private final DateTimeFormatter formatter = DateTimeFormatter.ofLocalizedDateTime ( FormatStyle.MEDIUM ).withLocale ( this.locale );
            private final DateTimeFormatter formatter = DateTimeFormatter.ofPattern ( "hh:mm:ss a" , this.locale );

            public void beepRegularly () {
                // Define task to be performed.
                final Runnable beeper = new Runnable () {
                    public void run () {
                        try {
                            ZonedDateTime zdt = ZonedDateTime.now ( zoneId );
                            System.out.println ( "Now: " + zdt.format ( formatter ) );
                        } catch ( Exception e ) {
                            // Always surround your task code with a try-catch, as any uncaught exception causes the scheduler to cease silently.
                            System.out.println ( "Exception unexpectedly reached 'run' method. " + e.getLocalizedMessage () );
                        }
                    }
                };
                // Start performing that task every so often.
                System.out.println ( "INFO - BeeperControl::beepRegularly - Scheduling the executor service to run now. Runs indefinitely." );
                final ScheduledFuture<?> beeperHandle = scheduler.scheduleAtFixedRate ( beeper , 0 , 5 , TimeUnit.SECONDS ); // (Runnable command, long initialDelay, long period, TimeUnit unit)
            }

            public void halt () {
                System.out.println ( "INFO - BeeperControl::halt - shutting down the ScheduledExecutorService." );
                scheduler.shutdown ();  // Initiates an orderly shutdown in which previously submitted tasks are executed, but no new tasks will be accepted.
                // scheduler.shutdownNow(); // Attempts to stop all actively executing tasks, halts the processing of waiting tasks, and returns a list of the tasks that were awaiting execution.
            }
        }

}