From 306f169d085f339a7b01536a757bf0fde713e291 Mon Sep 17 00:00:00 2001 From: Nathan McRae Date: Wed, 21 May 2025 22:48:39 -0700 Subject: [PATCH] Combine schedule start date/time fields into a single time-zoned field --- .../numbersstation/LinuxScheduler.java | 12 ++-- .../numbersstation/StationSettings.java | 62 ++++++++----------- .../StationSettingsController.java | 12 ++-- .../numbersstation/WindowsScheduler.java | 7 ++- 4 files changed, 48 insertions(+), 45 deletions(-) diff --git a/src/main/java/name/nathanmcrae/numbersstation/LinuxScheduler.java b/src/main/java/name/nathanmcrae/numbersstation/LinuxScheduler.java index 8f791c2..bb657da 100644 --- a/src/main/java/name/nathanmcrae/numbersstation/LinuxScheduler.java +++ b/src/main/java/name/nathanmcrae/numbersstation/LinuxScheduler.java @@ -11,6 +11,8 @@ import java.nio.charset.StandardCharsets; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; +import java.time.LocalDateTime; +import java.time.ZoneId; import java.util.concurrent.TimeUnit; import java.util.logging.Level; import java.util.logging.Logger; @@ -122,10 +124,12 @@ public class LinuxScheduler { * minute (0–59) */ public static String cronExpression(StationSettings settings) throws CronExpressionException { - String minute = Integer.toString(settings.getScheduleStartTime().getMinute()); - String hour = Integer.toString(settings.getScheduleStartTime().getHour()); - String dayOfMonth = Integer.toString(settings.getScheduleStartDate().getDayOfMonth()); - String dayOfWeek = Integer.toString(settings.getScheduleStartDate().getDayOfMonth()); + LocalDateTime scheduleDateTime = settings.getScheduleStart().withZoneSameInstant(ZoneId.systemDefault()).toLocalDateTime(); + + String minute = Integer.toString(scheduleDateTime.getMinute()); + String hour = Integer.toString(scheduleDateTime.getHour()); + String dayOfMonth = Integer.toString(scheduleDateTime.getDayOfMonth()); + String dayOfWeek = Integer.toString(scheduleDateTime.getDayOfMonth()); String scheduleString = ""; switch(settings.getMessagePeriod()) { diff --git a/src/main/java/name/nathanmcrae/numbersstation/StationSettings.java b/src/main/java/name/nathanmcrae/numbersstation/StationSettings.java index 57482a8..e4db6b3 100644 --- a/src/main/java/name/nathanmcrae/numbersstation/StationSettings.java +++ b/src/main/java/name/nathanmcrae/numbersstation/StationSettings.java @@ -12,6 +12,8 @@ import java.nio.file.SimpleFileVisitor; import java.security.SecureRandom; import java.time.LocalDate; import java.time.LocalDateTime; +import java.time.ZonedDateTime; +import java.time.ZoneId; import java.time.LocalTime; import java.time.Period; import java.util.ArrayList; @@ -32,8 +34,7 @@ public class StationSettings { private String name; private String password; private ArrayList prefixes; - private LocalDate scheduleStartDate; - private LocalTime scheduleStartTime; + private ZonedDateTime scheduleStart; private String username; public enum MessageMethod { @@ -54,8 +55,7 @@ public class StationSettings { messageLength = 100; messageMethod = MessageMethod.SFTP; messagePeriod = MessagePeriod.DAILY; - scheduleStartDate = LocalDate.now(); - scheduleStartTime = LocalTime.now(); + scheduleStart = ZonedDateTime.now(); } public StationSettings(String newName) { @@ -65,8 +65,7 @@ public class StationSettings { messageLength = 100; messageMethod = MessageMethod.SFTP; messagePeriod = MessagePeriod.DAILY; - scheduleStartDate = LocalDate.now(); - scheduleStartTime = LocalTime.now(); + scheduleStart = ZonedDateTime.now(); } public static void deleteStationData(String stationName) throws IOException { @@ -184,42 +183,43 @@ public class StationSettings { } public LocalDateTime nextSendTime() throws StationSettingsException { - Period sinceScheduleStart = Period.between(scheduleStartDate , LocalDate.now()); + LocalDate startDate = scheduleStart.withZoneSameInstant(ZoneId.systemDefault()).toLocalDate(); + LocalTime startTime = scheduleStart.withZoneSameInstant(ZoneId.systemDefault()).toLocalTime(); + Period sinceScheduleStart = Period.between(startDate, LocalDate.now()); // If this period's time has not yet passed, then show that time. // Otherwise, show the next period's time. switch (messagePeriod) { case DAILY: - if (LocalTime.now().isBefore(scheduleStartTime)) { - return LocalDate.now().atTime(scheduleStartTime); + if (LocalTime.now().isBefore(startTime)) { + return LocalDate.now().atTime(startTime); } else { - return LocalDate.now().plusDays(1).atTime(scheduleStartTime); + return LocalDate.now().plusDays(1).atTime(startTime); } case WEEKLY: - int weekdayDifference = scheduleStartDate.getDayOfWeek().getValue() - LocalDate.now().getDayOfWeek().getValue(); - System.out.println("weekdayDifference: " + weekdayDifference); + int weekdayDifference = startDate.getDayOfWeek().getValue() - LocalDate.now().getDayOfWeek().getValue(); if (weekdayDifference > 0) { - return LocalDate.now().plusDays(weekdayDifference).atTime(scheduleStartTime); + return LocalDate.now().plusDays(weekdayDifference).atTime(startTime); } else if (weekdayDifference == 0){ - if (LocalTime.now().isBefore(scheduleStartTime)) { - return LocalDate.now().atTime(scheduleStartTime); + if (LocalTime.now().isBefore(startTime)) { + return LocalDate.now().atTime(startTime); } else { - return LocalDate.now().plusWeeks(1).atTime(scheduleStartTime); + return LocalDate.now().plusWeeks(1).atTime(startTime); } } else { - return LocalDate.now().plusDays(7 + weekdayDifference).atTime(scheduleStartTime); + return LocalDate.now().plusDays(7 + weekdayDifference).atTime(startTime); } case MONTHLY: - int monthdayDifference = scheduleStartDate.getDayOfMonth() - LocalDate.now().getDayOfMonth(); + int monthdayDifference = startDate.getDayOfMonth() - LocalDate.now().getDayOfMonth(); if (monthdayDifference > 0) { - return LocalDate.now().plusDays(monthdayDifference).atTime(scheduleStartTime); + return LocalDate.now().plusDays(monthdayDifference).atTime(startTime); } else if (monthdayDifference == 0) { - if (LocalTime.now().isBefore(scheduleStartTime)) { - return LocalDate.now().atTime(scheduleStartTime); + if (LocalTime.now().isBefore(startTime)) { + return LocalDate.now().atTime(startTime); } else { - return LocalDate.now().plusMonths(1).atTime(scheduleStartTime); + return LocalDate.now().plusMonths(1).atTime(startTime); } } else { - return LocalDate.now().plusMonths(1).plusDays(monthdayDifference).atTime(scheduleStartTime); + return LocalDate.now().plusMonths(1).plusDays(monthdayDifference).atTime(startTime); } default: throw new StationSettingsException("Invalid period value: " + messagePeriod); @@ -305,20 +305,12 @@ public class StationSettings { return prefixes; } - public LocalDate getScheduleStartDate() { - return scheduleStartDate; + public ZonedDateTime getScheduleStart() { + return scheduleStart; } - public void setScheduleStartDate(LocalDate newScheduleStartDate) { - scheduleStartDate = newScheduleStartDate; - } - - public LocalTime getScheduleStartTime() { - return scheduleStartTime; - } - - public void setScheduleStartTime(LocalTime newScheduleStartTime) { - scheduleStartTime = newScheduleStartTime; + public void setScheduleStart(ZonedDateTime newScheduleStart) { + scheduleStart = newScheduleStart; } public String getUsername() { diff --git a/src/main/java/name/nathanmcrae/numbersstation/StationSettingsController.java b/src/main/java/name/nathanmcrae/numbersstation/StationSettingsController.java index e261994..d8d41e0 100644 --- a/src/main/java/name/nathanmcrae/numbersstation/StationSettingsController.java +++ b/src/main/java/name/nathanmcrae/numbersstation/StationSettingsController.java @@ -15,6 +15,9 @@ import java.nio.file.Path; import java.time.format.DateTimeFormatter; import java.time.LocalDate; import java.time.LocalTime; +import java.time.ZonedDateTime; +import java.time.ZoneId; +import java.time.ZoneOffset; import java.util.ArrayList; import java.util.List; import java.util.logging.Level; @@ -433,7 +436,6 @@ public class StationSettingsController { settings.setPassword(password.get()); settings.getPrefixes().clear(); settings.getPrefixes().addAll(prefixListView.getItems()); - settings.setScheduleStartDate(scheduleStartDatePicker.getValue()); settings.setUsername(username.get()); try { @@ -447,7 +449,9 @@ public class StationSettingsController { try { DateTimeFormatter formatter = DateTimeFormatter.ofPattern("HH:mm:ss"); LocalTime startTime = LocalTime.parse(scheduleStartTimeField.getText(), formatter); - settings.setScheduleStartTime(startTime); + ZonedDateTime scheduleStart = ZonedDateTime.of(scheduleStartDatePicker.getValue(), startTime, ZoneId.systemDefault()); + settings.setScheduleStart(scheduleStart.withZoneSameInstant(ZoneOffset.UTC)); + } catch (Exception ex) { logger.log(Level.SEVERE, "Error parsing schedule start time", ex); } @@ -557,9 +561,9 @@ public class StationSettingsController { password.set(settings.getPassword()); System.out.println(settings.getPrefixes()); prefixListView.getItems().addAll(settings.getPrefixes()); - scheduleStartDate.set(settings.getScheduleStartDate()); + scheduleStartDate.set(settings.getScheduleStart().withZoneSameInstant(ZoneId.systemDefault()).toLocalDate()); DateTimeFormatter formatter = DateTimeFormatter.ofPattern("HH:mm:ss"); - LocalTime startTime = settings.getScheduleStartTime(); + LocalTime startTime = settings.getScheduleStart().withZoneSameInstant(ZoneId.systemDefault()).toLocalTime(); if (startTime == null) { startTime = LocalTime.now(); } diff --git a/src/main/java/name/nathanmcrae/numbersstation/WindowsScheduler.java b/src/main/java/name/nathanmcrae/numbersstation/WindowsScheduler.java index df7de7b..096a3f9 100644 --- a/src/main/java/name/nathanmcrae/numbersstation/WindowsScheduler.java +++ b/src/main/java/name/nathanmcrae/numbersstation/WindowsScheduler.java @@ -16,7 +16,9 @@ import java.util.concurrent.TimeUnit; import java.util.logging.Level; import java.util.logging.Logger; import java.time.format.DateTimeFormatter; +import java.time.LocalDate; import java.time.LocalDateTime; +import java.time.ZoneId; import javafx.util.Pair; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; @@ -44,7 +46,7 @@ public class WindowsScheduler { rootElement.setAttribute("xmlns", "http://schemas.microsoft.com/windows/2004/02/mit/task"); doc.appendChild(rootElement); - LocalDateTime scheduleDateTime = station.getScheduleStartDate().atTime(station.getScheduleStartTime()); + LocalDateTime scheduleDateTime = station.getScheduleStart().withZoneSameInstant(ZoneId.systemDefault()).toLocalDateTime(); DateTimeFormatter dateFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss"); // RegistrationInfo element @@ -107,7 +109,8 @@ public class WindowsScheduler { Element daysOfMonth = doc.createElement("DaysOfMonth"); scheduleByMonth.appendChild(daysOfMonth); Element day = doc.createElement("Day"); - day.appendChild(doc.createTextNode(String.valueOf(station.getScheduleStartDate().getDayOfMonth()))); + LocalDate startDate = station.getScheduleStart().withZoneSameInstant(ZoneId.systemDefault()).toLocalDate(); + day.appendChild(doc.createTextNode(String.valueOf(startDate.getDayOfMonth()))); daysOfMonth.appendChild(day); Element months = doc.createElement("Months");