Skip to content

Commit a6510d5

Browse files
authored
Fix ACML information and timezone problem for VLDB (#1554)
* Update the journal track deadline and timezone for ACML 2026 * Support PT timezone with automatic daylight-saving adjustment PT (US Pacific Time) is UTC-7 during daylight saving and UTC-8 otherwise, so a single fixed offset cannot represent it. This was wrong for VLDB, whose rolling deadlines span April through March and cross the DST boundary — winter deadlines were off by one hour under the fixed UTC-7. Resolve the offset per deadline date: PT picks UTC-7/UTC-8 based on whether the date falls within US DST (2nd Sunday of March to 1st Sunday of November). All other timezones keep their existing fixed offsets, verified byte-identical across every value used in the dataset. - showtable.rs: add is_us_dst/resolve_tz_offset; parse_deadline_to_rfc3339 now resolves the offset from the deadline date - schema + README: add PT - vldb.yml: switch to PT
1 parent d03bad4 commit a6510d5

5 files changed

Lines changed: 83 additions & 46 deletions

File tree

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -150,7 +150,7 @@ Description of the fields:
150150
</tr>
151151
<tr>
152152
<td colspan="2"><code>timezone</code>*</td>
153-
<td>Timezone of deadline, currently support <code>UTC-12</code> ~ <code>UTC+12</code> & <code>AoE</code></td>
153+
<td>Timezone of deadline, currently support <code>UTC-12</code> ~ <code>UTC+12</code>, <code>AoE</code> & <code>PT</code> (US Pacific Time, auto-adjusts for daylight saving)</td>
154154
</tr>
155155
<tr>
156156
<td colspan="2"><code>date</code>*</td>

conference-yaml-schema.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,7 @@ items:
137137
- UTC+11
138138
- UTC+12
139139
- AoE
140+
- PT
140141
date:
141142
description: When the main conference is happening, e.g., Mar 12-16, 2021
142143
type: string

conference/AI/acml.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,10 +46,10 @@
4646
id: acml26
4747
link: https://www.acml-conf.org/2026/
4848
timeline:
49-
- deadline: '2026-06-06 23:59:59'
49+
- deadline: '2026-06-20 23:59:59'
5050
comment: 'Journal Track'
5151
- deadline: '2025-06-26 23:59:59'
5252
comment: 'Conference Track'
53-
timezone: UTC-7
53+
timezone: AoE
5454
date: December 1-4, 2026
5555
place: Melbourne, Australia

conference/DB/vldb.yml

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323
- deadline: '2021-01-01 17:00:00'
2424
- deadline: '2021-02-01 17:00:00'
2525
- deadline: '2021-03-01 17:00:00'
26-
timezone: UTC-7
26+
timezone: PT
2727
date: August 16-20, 2021
2828
place: Copenhagen, Denmark
2929
- year: 2022
@@ -42,7 +42,7 @@
4242
- deadline: '2022-01-01 17:00:00'
4343
- deadline: '2022-02-01 17:00:00'
4444
- deadline: '2022-03-01 17:00:00'
45-
timezone: UTC-7
45+
timezone: PT
4646
date: September 05-09, 2022
4747
place: Sydney, Australia
4848
- year: 2023
@@ -61,7 +61,7 @@
6161
- deadline: '2023-01-01 17:00:00'
6262
- deadline: '2023-02-01 17:00:00'
6363
- deadline: '2023-03-01 17:00:00'
64-
timezone: UTC-7
64+
timezone: PT
6565
date: August 28 - September 01, 2023
6666
place: Vancouver, Canada
6767
- year: 2024
@@ -80,7 +80,7 @@
8080
- deadline: '2024-01-01 17:00:00'
8181
- deadline: '2024-02-01 17:00:00'
8282
- deadline: '2024-03-01 17:00:00'
83-
timezone: UTC-7
83+
timezone: PT
8484
date: August 25-29, 2024
8585
place: Guangzhou, China (and hybrid)
8686
- year: 2025
@@ -99,7 +99,7 @@
9999
- deadline: '2025-01-01 17:00:00'
100100
- deadline: '2025-02-01 17:00:00'
101101
- deadline: '2025-03-01 17:00:00'
102-
timezone: UTC-7
102+
timezone: PT
103103
date: September 1-5, 2025
104104
place: London, United Kingdom
105105
- year: 2026
@@ -118,7 +118,7 @@
118118
- deadline: '2026-01-01 17:00:00'
119119
- deadline: '2026-02-01 17:00:00'
120120
- deadline: '2026-03-01 17:00:00'
121-
timezone: UTC-7
121+
timezone: PT
122122
date: August 31 - September 4, 2026
123123
place: Boston, MA, USA
124124
- year: 2027
@@ -149,6 +149,6 @@
149149
deadline: '2027-02-01 17:00:00'
150150
- abstract_deadline: '2027-02-25 17:00:00'
151151
deadline: '2027-03-01 17:00:00'
152-
timezone: UTC-7
152+
timezone: PT
153153
date: August 23 - August 27, 2027
154154
place: Athens, Greece

src/components/showtable.rs

Lines changed: 72 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ use crate::components::countdown::CountDown;
66
use crate::components::subscription_modal::*;
77
use crate::components::timeline::*;
88
use crate::components::timezone::*;
9-
use chrono::{DateTime, FixedOffset};
9+
use chrono::{DateTime, Datelike, Duration, FixedOffset, NaiveDate};
1010
use leptos::prelude::*;
1111
use serde_json;
1212
use std::collections::HashMap;
@@ -146,16 +146,13 @@ pub fn ShowTable() -> impl IntoView {
146146
let _ = page.get();
147147

148148
let (current_time, _) = get_browser_time_and_timezone();
149-
let utc_map = load_utc_map();
150149

151150
all_conf_list.update(|conferences| {
152151
for item in conferences.iter_mut() {
153152
if item.deadline != "TBD" {
154-
let tz_str = normalize_timezone(&item.timezone);
155-
156-
if let Some(tz_offset) = utc_map.get(&tz_str) {
157-
let ddl_str = parse_deadline_to_rfc3339(&item.deadline, tz_offset);
158-
153+
if let Some(ddl_str) =
154+
parse_deadline_to_rfc3339(&item.deadline, &item.timezone)
155+
{
159156
if let Ok(ddl_datetime) = DateTime::parse_from_rfc3339(&ddl_str) {
160157
let diff = ddl_datetime.signed_duration_since(current_time);
161158
if diff.num_milliseconds() <= 0 {
@@ -180,7 +177,6 @@ pub fn ShowTable() -> impl IntoView {
180177
time_zone.set(get_timezone_name().unwrap());
181178

182179
spawn_local(async move {
183-
let utc_map = load_utc_map();
184180
let rank_options: HashMap<&str, &str> = RANK_OPTIONS.iter().cloned().collect();
185181

186182
let (current_time, current_timezone) = get_browser_time_and_timezone();
@@ -205,26 +201,34 @@ pub fn ShowTable() -> impl IntoView {
205201
let mut ddl_vec = Vec::<TimePoint>::new();
206202

207203
for timeline_item in year_conf.timeline.iter() {
208-
let tz_offset = utc_map.get(&year_conf.timezone).unwrap();
209-
210-
let ddl_str = parse_deadline_to_rfc3339(&timeline_item.deadline, tz_offset);
204+
let tz = &year_conf.timezone;
211205

212206
// abstract type:0 submission type:1
213207
if let Some(abs_ddl) = timeline_item.abstract_deadline.clone() {
214-
let abs_ddl_str = parse_deadline_to_rfc3339(&abs_ddl, tz_offset);
215-
216-
if let Ok(abs_ddl_datetime) =
217-
DateTime::parse_from_rfc3339(&abs_ddl_str)
208+
if let Some(abs_ddl_str) =
209+
parse_deadline_to_rfc3339(&abs_ddl, tz)
218210
{
219-
ddl_vec.push(TimePoint {
220-
timepoint: abs_ddl_datetime
221-
.with_timezone(&current_timezone)
222-
.clone(),
223-
r#type: 0,
224-
});
211+
if let Ok(abs_ddl_datetime) =
212+
DateTime::parse_from_rfc3339(&abs_ddl_str)
213+
{
214+
ddl_vec.push(TimePoint {
215+
timepoint: abs_ddl_datetime
216+
.with_timezone(&current_timezone)
217+
.clone(),
218+
r#type: 0,
219+
});
220+
}
225221
}
226222
}
227223

224+
let ddl_str = match parse_deadline_to_rfc3339(
225+
&timeline_item.deadline,
226+
tz,
227+
) {
228+
Some(s) => s,
229+
None => continue,
230+
};
231+
228232
if let Ok(ddl_datetime) = DateTime::parse_from_rfc3339(&ddl_str) {
229233
ddl_vec.push(TimePoint {
230234
timepoint: ddl_datetime
@@ -298,12 +302,10 @@ pub fn ShowTable() -> impl IntoView {
298302
continue;
299303
}
300304

301-
let tz_str = normalize_timezone(&item.timezone);
302-
303305
// 4. Calculate deadlines and remaining time
304-
if let Some(tz_offset) = utc_map.get(&tz_str) {
305-
let ddl_str = parse_deadline_to_rfc3339(&item.deadline, tz_offset);
306-
306+
if let Some(ddl_str) =
307+
parse_deadline_to_rfc3339(&item.deadline, &item.timezone)
308+
{
307309
if let Ok(ddl_datetime) = DateTime::parse_from_rfc3339(&ddl_str) {
308310
// Convert to browser local time and format
309311
let local_ddl_datetime =
@@ -321,7 +323,9 @@ pub fn ShowTable() -> impl IntoView {
321323

322324
// Handle abstract deadline
323325
if let Some(abs_ddl) = &item.abstract_deadline {
324-
let abs_ddl_str = parse_deadline_to_rfc3339(abs_ddl, tz_offset);
326+
if let Some(abs_ddl_str) =
327+
parse_deadline_to_rfc3339(abs_ddl, &item.timezone)
328+
{
325329
if let Ok(abs_datetime) =
326330
DateTime::parse_from_rfc3339(&abs_ddl_str)
327331
{
@@ -338,6 +342,7 @@ pub fn ShowTable() -> impl IntoView {
338342
_ => format!("{}.", abs_note),
339343
});
340344
}
345+
}
341346
}
342347

343348
let diff = ddl_datetime.signed_duration_since(current_time);
@@ -1053,17 +1058,53 @@ fn normalize_timezone(tz: &str) -> String {
10531058
}
10541059
}
10551060

1056-
fn parse_deadline_to_rfc3339(deadline: &str, tz_offset: &str) -> String {
1057-
if deadline.contains(' ') {
1061+
/// Nth (1-indexed) Sunday of the given month/year.
1062+
fn nth_sunday(year: i32, month: u32, n: u32) -> Option<NaiveDate> {
1063+
let first = NaiveDate::from_ymd_opt(year, month, 1)?;
1064+
let days_to_first_sunday = (7 - first.weekday().num_days_from_sunday()) % 7;
1065+
Some(first + Duration::days(days_to_first_sunday as i64 + 7 * (n as i64 - 1)))
1066+
}
1067+
1068+
/// Whether the given date falls within US daylight saving time, which runs from
1069+
/// the second Sunday in March to the first Sunday in November.
1070+
fn is_us_dst(date: NaiveDate) -> bool {
1071+
let year = date.year();
1072+
match (nth_sunday(year, 3, 2), nth_sunday(year, 11, 1)) {
1073+
(Some(start), Some(end)) => date >= start && date < end,
1074+
_ => false,
1075+
}
1076+
}
1077+
1078+
/// Resolve a timezone label to a fixed `+HH:MM` / `-HH:MM` offset for a given
1079+
/// deadline date. Labels with a constant offset (`UTC-8`, `AoE`, ...) ignore the
1080+
/// date; daylight-saving labels such as `PT` (US Pacific Time) pick UTC-7 during
1081+
/// DST and UTC-8 otherwise based on the deadline date.
1082+
fn resolve_tz_offset(tz: &str, date: &str) -> Option<String> {
1083+
if tz == "PT" {
1084+
let naive = NaiveDate::parse_from_str(date, "%Y-%m-%d").ok()?;
1085+
return Some(if is_us_dst(naive) {
1086+
"-07:00".to_string()
1087+
} else {
1088+
"-08:00".to_string()
1089+
});
1090+
}
1091+
let tz_str = normalize_timezone(tz);
1092+
get_utc_map().get(&tz_str).cloned()
1093+
}
1094+
1095+
fn parse_deadline_to_rfc3339(deadline: &str, tz: &str) -> Option<String> {
1096+
let date_part = deadline.split(' ').nth(0).unwrap_or(deadline);
1097+
let tz_offset = resolve_tz_offset(tz, date_part)?;
1098+
Some(if deadline.contains(' ') {
10581099
format!(
10591100
"{}T{}{}",
1060-
deadline.split(' ').nth(0).unwrap_or(""),
1101+
date_part,
10611102
deadline.split(' ').nth(1).unwrap_or("00:00:00"),
10621103
tz_offset
10631104
)
10641105
} else {
10651106
format!("{}T23:59:59{}", deadline, tz_offset)
1066-
}
1107+
})
10671108
}
10681109

10691110
const RANK_OPTIONS: &[(&str, &str)] = &[("A", "CCF A"), ("B", "CCF B"), ("C", "CCF C"), ("N", "Non-CCF")];
@@ -1096,11 +1137,6 @@ fn get_utc_map() -> &'static HashMap<String, String> {
10961137
})
10971138
}
10981139

1099-
#[allow(dead_code)]
1100-
fn load_utc_map() -> HashMap<String, String> {
1101-
get_utc_map().clone()
1102-
}
1103-
11041140
#[cfg(target_arch = "wasm32")]
11051141
fn get_browser_time_and_timezone() -> (DateTime<FixedOffset>, FixedOffset) {
11061142
let utc_now = chrono::Utc::now();

0 commit comments

Comments
 (0)