diff --git a/quickfixj-core/src/main/java/quickfix/DefaultSessionSchedule.java b/quickfixj-core/src/main/java/quickfix/DefaultSessionSchedule.java index c1ec3e5c4..e2d85ef18 100644 --- a/quickfixj-core/src/main/java/quickfix/DefaultSessionSchedule.java +++ b/quickfixj-core/src/main/java/quickfix/DefaultSessionSchedule.java @@ -220,6 +220,8 @@ private TimeInterval theMostRecentIntervalBefore(Calendar t) { } } else { + // Note that depending on locale, calling 'set(Calendar.DAY_OF_WEEK, ...)' could result in intervalStart being + // a date in the future. if (isSet(startTime.getDay())) { intervalStart.set(Calendar.DAY_OF_WEEK, startTime.getDay()); if (intervalStart.getTimeInMillis() > t.getTimeInMillis()) { @@ -236,6 +238,11 @@ private TimeInterval theMostRecentIntervalBefore(Calendar t) { if (intervalEnd.getTimeInMillis() <= intervalStart.getTimeInMillis()) { intervalEnd.add(Calendar.WEEK_OF_MONTH, 1); } + + // in some cases (certain locale), we could run into scenario where the interval end is before the interval start. + if (intervalEnd.getTimeInMillis() < intervalStart.getTimeInMillis()) { + intervalEnd.add(Calendar.WEEK_OF_YEAR, 1); + } } else if (intervalEnd.getTimeInMillis() <= intervalStart.getTimeInMillis()) { intervalEnd.add(Calendar.DAY_OF_WEEK, 1); } diff --git a/quickfixj-core/src/test/java/quickfix/SessionScheduleTest.java b/quickfixj-core/src/test/java/quickfix/SessionScheduleTest.java index 348c3226d..d024ac432 100644 --- a/quickfixj-core/src/test/java/quickfix/SessionScheduleTest.java +++ b/quickfixj-core/src/test/java/quickfix/SessionScheduleTest.java @@ -344,6 +344,31 @@ public void testIsSameSessionWithDay() throws Exception { doIsSameSessionTest(schedule, t1, t2, true); } + @Test + public void testSessionStartInPreviousDayOfWeek() throws Exception { + Locale.setDefault(new Locale("en", "AU")); + + final TimeZone tz = TimeZone.getTimeZone("Australia/Victoria"); + mockSystemTimeSource.setTime(getTimeStamp(2026, Calendar.FEBRUARY, 23, 10, 0, 0, tz)); + + final SessionSettings settings = new SessionSettings(); + settings.setString(Session.SETTING_START_TIME, "13:00:00 Australia/Victoria"); + + // AU week starts on Sunday on Java 17 and below, but on Monday on Java 21 and above (not sure about in between). + settings.setString(Session.SETTING_START_DAY, "Sunday"); + + settings.setString(Session.SETTING_END_TIME, "17:00:00 America/New_York"); + settings.setString(Session.SETTING_END_DAY, "Saturday"); + + SessionID sessionID = new SessionID("FIX.4.2", "SENDER", "TARGET"); + final SessionSchedule schedule = new DefaultSessionSchedule(settings, sessionID); + + mockSystemTimeSource + .setTime(getTimeStamp(2026, Calendar.FEBRUARY, 23, 10, 0, 0, tz)); + assertEquals("in session expectation incorrect", true, schedule + .isSessionTime()); + } + @Test public void testSettingsWithoutStartEndDay() throws Exception { SessionSettings settings = new SessionSettings();