Die Zeitzoneneinstellung des Betriebssystems Ihres Servers und JVM sollte für Ihre Programmierung nicht relevant sein. Beide können sich jederzeit ändern, während Laufzeit, also nicht darauf verlassen. Geben Sie immer die gewünschte/erwartete Zeitzone im optionalen Argument für die verschiedenen Datum/Uhrzeit-Methoden an.
Beachten Sie, dass zeitzonenempfindliche Momente nicht im Voraus geplant werden können. Politiker sind berüchtigt dafür, die Zeitzonendefinitionen oft mit sehr wenig Vorankündigung zu ändern.
Wenn Sie einen Alarm für den nächsten Montag um 11:00 Uhr im Kontext der Zeitzone des Benutzers einrichten möchten, benötigen Sie zuerst die Zeitzone des Benutzers. Möglicherweise können Sie eine Standardzeitzone erkennen, aber letztlich ist der einzige zuverlässige Weg, den Benutzer nach der gewünschten/erwarteten Zeitzone zu fragen.
Festlegen eines proper time zone name im Format von continent/region
wie America/Montreal
, Africa/Casablanca
oder Pacific/Auckland
. Verwenden Sie niemals die 3-4 Buchstaben Abkürzung wie EST
oder IST
, da sie keine echten Zeitzonen sind, nicht standardisiert und nicht einmal eindeutig (!).
Halten Sie den Wochentag des Alarms als DayOfWeek
Enum-Objekt.
DayOfWeek alarmDow = DayOfWeek.MONDAY ;
der Time-of-Tages-Alarm halten als LocalTime
.
LocalTime alarmTimeOfDay = LocalTime.parse("11:00:00");
Diese Klasse enthält kein Datum und keine Offset-von-UTC- oder Zeitzone. Es hat also keine Bedeutung, bis man sich in eine Zeitzone einstellt.
Halten Sie die Alarmzeitzone als ZoneId
.
ZoneId z = ZoneId.of("America/Montreal");
Mit diesen Teilen können Sie den Alarm planen.
Erhalten Sie den aktuellen Moment als Instant
. Die Instant
Klasse repräsentiert einen Moment auf der Timeline in UTC mit einer Auflösung von nanoseconds (bis zu neun (9) Ziffern eines Dezimalbruchteils).
Instant now = Instant.now();
Wenden Sie die gewünschte Zeitzone an, um eine ZonedDateTime
zu erhalten.
ZonedDateTime zdtNow = instant.atZone(z);
Um die Zukunft Moment des Alarms zu bestimmen, verwenden Sie die TemporalAdjuster
Schnittstelle Datum-Zeit-Werte zu manipulieren. Die Klasse TemporalAdjusters
(beachten Sie die Plural s
) bietet Implementierungen. Extrahieren Sie zuerst einen Nur-Datumswert, da wir die Alarmzeit LocalTime
als Uhrzeit zuweisen.
LocalDate today = zdtNow.toLocalDate();
LocalDate dateOfNextOrSameDow = today.with(TemporalAdjusters.withNextOrSame(alarmDow));
Die gewünschte Tageszeit anwenden.
ZonedDateTime zdtAlarm = ZonedDateTime.of(dateOfNextOrSameDow , alarmTimeOfDay , z) ;
Diese spezielle Alarmdatumszeit ist möglicherweise heute schon früher vergangen. Also teste. Wenn ja, fügen Sie eine Woche hinzu, um das nächste Vorkommen des gewünschten Wochentags zu erhalten.
if(zdtAlarm.isBefore(zdtNow)) { // If already passed…
zdtAlarm = zdtAlarm.plusWeeks(1); // …go to next day-of-week occurrence.
}
Also können Sie uns sagen, was das Problem ist? Können Sie uns Ihren Code zeigen? Die Systemuhr ist immer um UTC, deshalb gibt es keinen Grund, dass es ein Problem geben muss. –
@PeterLawrey Ich habe meine Frage bearbeitet – jahra
Sie müssen die Uhrzeit und Wochentag zusammen konvertieren. Beachten Sie bei der Sommerzeit, dass Sie nicht nur einmal rechnen können und davon ausgehen, dass dies immer richtig ist. Sie müssen das nächste Mal berechnen und eine Aufgabe hinzufügen, die zu diesem Zeitpunkt ausgeführt werden soll. z.B. Wenn sie sich in New York für 1 Uhr morgens entscheiden, wird es zu verschiedenen Zeiten des Jahres 21 Uhr UTC-4 und 20 Uhr UTC-5 sein. –