Search code examples
ntpscheduledexecutorservicesystem-administrationweblistener

How to get same value for current time in milliseconds on localhost and server?


I have created a web listener which contains a ScheduledExecutorService to run a job on a specific date and time and after that at regular fixed time interval. This scheduler checks for a specific date and time to do the job. The scheduler works with UTC time.

The problem is when I run it on my localhost it works perfectly but when I put it on remote server (server and my localhost are not in same TimeZone) it fails to work properly( they produce different value of System.currentTimeMillis() . With the help of a logger I have checked the value of System.currentTimeMillis() both on localhost and server and they are different.

Here is my Scheduler.

private static ScheduledExecutorService execService = Executors.newScheduledThreadPool(1, namedThreadFactory);
final Calendar date = new GregorianCalendar();
date.setTimeZone(TimeZone.getTimeZone("UTC"));
    execService.scheduleAtFixedRate(new Runnable() {
                @Override
        public void run() {

                    logger.info("Scheduler ran");

                    try {


                        if (date.get(Calendar.DAY_OF_MONTH) == 1) {
                            if (!(System.currentTimeMillis() - getStartTime().getTime() > 300000)) {
                                logger.info("Doing the job");
                                myJob();
                            }
                            else{
                                logger.info("Too late after scheduled time");
                            }
                        } else {

                            logger.info("Current Day of Month: " + date.get(Calendar.DAY_OF_MONTH) + ". Job will be done on  1st Day of the month");
                        }
                    } catch (Exception ex) {

                        logger.info(ex);
                    }

                }

            }, getInitialDelay(), (2*60000), TimeUnit.MILLISECONDS);

        }

        private static long getOffsetTime() {
            Calendar dateForOffset = new GregorianCalendar();
            dateForOffset.setTimeZone(TimeZone.getTimeZone("UTC"));
            int days = dateForOffset.getActualMaximum(Calendar.DAY_OF_MONTH);

            switch (days) {
                case 31:
                    offsetTimeInMilli = PERIOD;
                    break;
                case 29:
                    offsetTimeInMilli = (-1) * PERIOD;
                    break;
                case 28:
                    offsetTimeInMilli = (-2) * PERIOD;
                    break;
                default:
                    break;
            }
            return offsetTimeInMilli;
        }

        private static long getInitialDelay() {
            long currentTime = System.currentTimeMillis();
            logger.info( "Current Time " + currentTime);
            logger.info("Set Time to do the job   -->" + getStartTime().getTime() + " Milliseconds");
            initialDelay = getStartTime().getTime() - currentTime;
            logger.info("Initial Delay Found : " + initialDelay + " Milliseconds");
            return initialDelay;

        }

        private static Date getStartTime() {
            Calendar d10am = Calendar.getInstance();
            d10am.setTimeZone(TimeZone.getTimeZone("UTC"));
            //logger.info("Day of Month  ----- >" + d10am.get(Calendar.DAY_OF_MONTH));
            //d10am.set(Calendar.DAY_OF_MONTH, 1);
            d10am.set(Calendar.HOUR_OF_DAY, 5);
            d10am.set(Calendar.MINUTE, 55);
            d10am.set(Calendar.SECOND, 0);
            d10am.set(Calendar.MILLISECOND, 0);
            d10am.get(Calendar.DAY_OF_MONTH);
            //logger.info("Day of Month  ----- >" + Calendar.DAY_OF_MONTH);

            return d10am.getTime();
        }

Solution

  • One or both of them must be wrong. The value System.currentTimeMillis() is independent of time zones. Really, the proper way to synchronize times on these servers is for each server to synchronize with a time server using NTP (Network Time Protocol).

    This is more of a systems administration problem than a Java programming problem.