Обновление ежедневного счетчика даты с определенного времени - PullRequest
0 голосов
/ 27 января 2019

У меня есть две даты: «Дата начала 2018-01-01» и «Дата окончания 2018-01-31»

Я хочу сделать свою логику таким образом, чтобы каждый день мой стартдата будет увеличиваться до достижения 2018-02-28.Ниже приведен фрагмент кода, который я пробовал.Как это можно исправить, так как Дата начала должна меняться ежедневно.

public class myclass {
    public static void main(String a[]) {
        try {
            String dt = "2008-01-01";  // Start date
            String dt1 = "2008-01-31";  // End date
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
            Calendar c = Calendar.getInstance();
            c.setTime(sdf.parse(dt));
            c.add(Calendar.DATE, 1);  // number of days to add
            dt = sdf.format(c.getTime());  //
            System.out.println(dt);
        }catch (Exception ex) {
            ex.printStackTrace();
        }
    }
}

PS: это выполнение в реальном времени, в планировщике, который выполняется ежедневно и проверяет дату окончания с указанной даты.Сколько дней осталось.

Спасибо

Ответы [ 3 ]

0 голосов
/ 27 января 2019

Для этого вы можете использовать java.util.Timer класс.

В приведенной ниже программе я выбрал другой подход.Я НЕ использую дату начала.Я просто получаю текущую дату каждый день и сравниваю ее с контрольной датой (в данном примере это «2019-02-10»).Посмотрите, работает ли это по вашему требованию.

(используйте FIVE_SECONDS_IN_MILLISECONDS для проверки программы.)

import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Timer;
import java.util.TimerTask;

public class Scheduler {
  private static final long ONE_DAY_IN_MILLISECONDS = 1000 * 60 * 60 * 24;
  private static final long FIVE_SECONDS_IN_MILLISECONDS = 1000 * 5;

  public static void main(String[] args) {
    SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");

    TimerTask timerTask = new TimerTask() {
      @Override
      public void run() {
        Calendar c = Calendar.getInstance();
        String dateString = sdf.format(c.getTime());
        System.out.println(dateString);
        if (dateString.equals("2019-02-10")) {
          System.out.println("Date reached!");
        }
      }
    };

    Timer timer = new Timer();
    timer.schedule(timerTask, 0, ONE_DAY_IN_MILLISECONDS/*FIVE_SECONDS_IN_MILLISECONDS*/);
  }
}
0 голосов
/ 29 января 2019

Runnable

Определите работу, которую вам нужно сделать, как Runnable.

Затем используйте Scheduled ExecutorService для запуска каждую минуту или около того, сверяя текущую дату с целевой датой.Если обратный отсчет увеличился, обновите отображение в графическом интерфейсе.Если нет, ничего не делайте, пусть Runnable снова запустится через минуту.

См. Руководство по Oracle для исполнителей .

ScheduledExecutorService ses = Executors.newSingleThreadScheduledExecutor();  // Use a single thread, as we need this to run sequentially, not in parallel.
ses.scheduleWithFixedDelay( r , 0L , 1L , TimeUnit.MINUTES ); // Pass the `Runnable`, an initial delay, a count to wait between runs, and the unit of time for those two other number arguments.

Было бы более эффективно планировать новый Runnable каждый раз, чем автоматическое повторение, поэтомуВ качестве задержки установите расчетное количество времени до следующей полуночи.Таким образом, исполнитель будет спать весь день, а не бегать каждую минуту.Но такой подход может потерпеть неудачу, если часы пользователя обновляются до существенно отличающегося текущего времени или если текущий часовой пояс пользователя меняется (если вы используете настройку по умолчанию, а не устанавливаете ее явно).Учитывая, как мало нужно сделать Runnable (просто проверьте текущую дату и рассчитайте оставшиеся дни), нет никаких практических причин не просто запускать его каждую минуту или две (как бы долго вы ни были минимально терпимы к свежему обновлению для пользователя - бизнеса)политика управления вашим приложением).

LocalDate

Класс LocalDate представляет значение только для даты без времени суток и без часовой пояс или смещение от UTC .

Часовой пояс имеет решающее значение при определении даты.В любой момент времени дата меняется по всему земному шару в зависимости от зоны.Например, через несколько минут после полуночи в Париж Франция - это новый день, в то время как "вчера" в Монреаль Квебек .

Если часовой пояс не указан,JVM неявно применяет свой текущий часовой пояс по умолчанию.Это значение по умолчанию может измениться в любой момент во время выполнения (!), Поэтому ваши результаты могут отличаться.Лучше явно указать желаемый / ожидаемый часовой пояс в качестве аргумента.

Укажите правильное имя часового пояса в формате Continent/Region, например America/Montreal, Africa/Casablanca,или Pacific/Auckland.Никогда не используйте 2-4 буквенные сокращения, такие как EST или IST, так как они не истинные часовые пояса, не стандартизированы и даже не уникальны (!).

ZoneId z = ZoneId.of( "Asia/Kolkata" );  // Or ZoneId.systemDefault() to rely on the JVM’s current default time zone.
LocalDate today = LocalDate.now( z );

Пример

Вот полный пример.Для получения дополнительной информации, поиск переполнения стека.Использование ScheduledExecutorService уже много раз охватывалось.

package work.basil.example;

import java.time.Instant;
import java.time.LocalDate;
import java.time.Month;
import java.time.ZoneId;
import java.time.temporal.ChronoUnit;
import java.util.Objects;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

public class DailyCountdown implements Runnable {
    private LocalDate dueDate;
    private Long daysRemaining;

    public DailyCountdown ( LocalDate dueDate ) {
        this.dueDate = dueDate;
    }

    @Override
    public void run () {
        try {
            System.out.println( "DEBUG - Running the DailyCountdown::run method at " + Instant.now() );
            ZoneId z = ZoneId.of( "America/Montreal" );  // Or ZoneId.systemDefault() to rely on the JVM’s current default time zone.
            LocalDate today = LocalDate.now( z );
            Long count = ChronoUnit.DAYS.between( today , this.dueDate );
            if ( Objects.isNull( this.daysRemaining ) ) {
                this.daysRemaining = ( count - 1 );
            }
            if ( this.daysRemaining.equals( count ) ) {
                // Do nothing.
            } else {
                // … Schedule on another thread for the GUI to update with the new number.
                this.daysRemaining = count;
            }
        } catch ( Exception e ) {
            // Log this unexpected exception, and notify sysadmin.
            // Any uncaught exception reaching the scheduled executor service would have caused it to silently halt any further scheduling.
        }
    }

    public static void main ( String[] args ) {
        // Put this code where ever appropriate, when setting up your GUI after the app launches.
        Runnable r = new DailyCountdown( LocalDate.of( 2018 , Month.FEBRUARY , 15 ) );
        ScheduledExecutorService ses = Executors.newSingleThreadScheduledExecutor();
        ses.scheduleWithFixedDelay( r , 0L , 1L , TimeUnit.MINUTES );

        // Be sure to gracefully shutdown the ScheduledExecutorService when your program is stopping. Otherwise, the executor may continue running indefinitely on the background thread.
        try {
            Thread.sleep( TimeUnit.MINUTES.toMillis( 7 ) ); // Sleep 7 minutes to let the background thread do its thing.
        } catch ( InterruptedException e ) {
            System.out.println( "The `main` thread was woken early from sleep." );
        }
        ses.shutdown();
        System.out.println( "App is exiting at " + Instant.now() ) ;
    }
}
0 голосов
/ 27 января 2019

API времени Java 8, вы можете легко достичь.

for (LocalDate date = startDate; date.isBefore(endDate); date = date.plusDays(1))
{
    ...
}
...