Skip to content

Commit 0607479

Browse files
authored
Update sync_status_readme.py
1 parent 2294ee3 commit 0607479

File tree

1 file changed

+36
-20
lines changed

1 file changed

+36
-20
lines changed

sync_status_readme.py

Lines changed: 36 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,23 @@ def get_content_for_date(content, start_pos):
149149
return content[start_pos:start_pos + next_date_match.start()]
150150
return content[start_pos:]
151151

152+
def get_local_day_bounds_for_label(label_date, user_tz):
153+
"""
154+
Given a program label date (UTC tz-aware datetime) and a user's timezone,
155+
compute the start and end of that calendar day in the user's local time.
156+
157+
Example: label 2024-10-17 and Asia/Shanghai ->
158+
local_start = 2024-10-17 00:00+08:00, local_end = 2024-10-18 00:00+08:00.
159+
"""
160+
try:
161+
local_start_naive = datetime(label_date.year, label_date.month, label_date.day, 0, 0, 0)
162+
local_start = user_tz.localize(local_start_naive)
163+
except Exception:
164+
# Fallback: construct with tzinfo if localize is unavailable
165+
local_start = datetime(label_date.year, label_date.month, label_date.day, 0, 0, 0, tzinfo=user_tz)
166+
local_end = local_start + timedelta(days=1)
167+
return local_start, local_end
168+
152169

153170
def check_md_content(file_content, date, user_tz):
154171
"""
@@ -157,16 +174,18 @@ def check_md_content(file_content, date, user_tz):
157174
try:
158175
content = extract_content_between_markers(file_content)
159176
# 直接使用 UTC 日期进行匹配,因为用户写日期标题时使用的是标准日期格式
160-
utc_date = date.replace(hour=0, minute=0, second=0, microsecond=0)
161-
current_date_match = find_date_in_content(content, utc_date)
177+
# Use the label date directly for matching (the table header uses the same
178+
# calendar date regardless of timezone).
179+
label_date = date.replace(hour=0, minute=0, second=0, microsecond=0)
180+
current_date_match = find_date_in_content(content, label_date)
162181

163182
if not current_date_match:
164-
logging.info(f"No match found for date {utc_date.strftime('%Y-%m-%d')}")
183+
logging.info(f"No match found for date {label_date.strftime('%Y-%m-%d')}")
165184
return False
166185

167186
date_content = get_content_for_date(content, current_date_match.end())
168187
date_content = re.sub(r'\s', '', date_content)
169-
logging.info(f"Content length for {utc_date.strftime('%Y-%m-%d')}: {len(date_content)}")
188+
logging.info(f"Content length for {label_date.strftime('%Y-%m-%d')}: {len(date_content)}")
170189
return len(date_content) > 10
171190
except Exception as e:
172191
logging.error(f"Error in check_md_content: {str(e)}")
@@ -184,23 +203,21 @@ def get_user_study_status(nickname):
184203
now_local = datetime.now(user_tz)
185204

186205
for date in get_date_range():
187-
# Treat each UTC program day as a 24h window [start_utc, next_start_utc)
206+
# Keyed by UTC midnight for consistency across the script
188207
start_utc = date.replace(hour=0, minute=0, second=0, microsecond=0)
189-
next_start_utc = (start_utc + timedelta(days=1))
190208

191-
# Convert window edges into user's local time for boundary checks
192-
start_local = start_utc.astimezone(user_tz)
193-
end_local = next_start_utc.astimezone(user_tz)
209+
# Use the user's local calendar day boundaries for the label date
210+
start_local, end_local = get_local_day_bounds_for_label(date, user_tz)
194211

195212
if now_local < start_local:
196213
# Future day for this user
197-
user_status[date] = " "
214+
user_status[start_utc] = " "
198215
elif now_local >= end_local:
199-
# Past day: must be ✅ or ⭕️
200-
user_status[date] = "✅" if check_md_content(file_content, date, user_tz) else "⭕️"
216+
# Past day in user's local time
217+
user_status[start_utc] = "✅" if check_md_content(file_content, date, user_tz) else "⭕️"
201218
else:
202219
# In-progress (today for this user): show ✅ if already posted, else blank
203-
user_status[date] = "✅" if check_md_content(file_content, date, user_tz) else " "
220+
user_status[start_utc] = "✅" if check_md_content(file_content, date, user_tz) else " "
204221
logging.info(f"Successfully processed file for user: {nickname}")
205222
except FileNotFoundError:
206223
logging.error(f"Error: Could not find file {file_name}")
@@ -322,18 +339,16 @@ def generate_user_row(user):
322339
date_range = get_date_range()
323340

324341
for i, date in enumerate(date_range):
325-
# UTC window for the program day
342+
# UTC key for this program label day
326343
start_utc = date.astimezone(pytz.UTC).replace(hour=0, minute=0, second=0, microsecond=0)
327-
next_start_utc = start_utc + timedelta(days=1)
328-
# Localized boundaries
329-
start_local = start_utc.astimezone(user_tz)
330-
end_local = next_start_utc.astimezone(user_tz)
344+
# Local day boundaries for this label date
345+
start_local, end_local = get_local_day_bounds_for_label(date, user_tz)
331346

332347
if is_eliminated:
333348
new_row += " |"
334349
continue
335350

336-
# Future day for this user
351+
# Future day for this user (based on local midnight)
337352
if now_local < start_local:
338353
new_row += " |"
339354
continue
@@ -348,7 +363,8 @@ def generate_user_row(user):
348363
for day_idx in range(cycle_start_day, min(cycle_end_day + 1, i + 1)):
349364
if day_idx < len(date_range):
350365
check_start_utc = date_range[day_idx].astimezone(pytz.UTC).replace(hour=0, minute=0, second=0, microsecond=0)
351-
check_end_local = (check_start_utc + timedelta(days=1)).astimezone(user_tz)
366+
# End of the label day in user's local timezone
367+
_, check_end_local = get_local_day_bounds_for_label(date_range[day_idx], user_tz)
352368
# Only count days that have fully ended in user's local time
353369
if now_local >= check_end_local:
354370
status = user_status.get(check_start_utc, "⭕️")

0 commit comments

Comments
 (0)