Skip to content

Commit 2294ee3

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

File tree

1 file changed

+66
-26
lines changed

1 file changed

+66
-26
lines changed

sync_status_readme.py

Lines changed: 66 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -64,18 +64,44 @@ def get_date_range():
6464

6565

6666
def get_user_timezone(file_content):
67-
yaml_match = re.search(r'---\s*\ntimezone:\s*(\S+)\s*\n---', file_content)
67+
yaml_match = re.search(r'---\s*\ntimezone:\s*([^\n]+)\s*\n---', file_content)
6868
if yaml_match:
69-
timezone_str = yaml_match.group(1)
69+
timezone_str = yaml_match.group(1).strip()
70+
# 1) Try IANA timezone names directly (e.g., "Asia/Kolkata")
7071
try:
7172
return pytz.timezone(timezone_str)
7273
except pytz.exceptions.UnknownTimeZoneError:
73-
try:
74-
offset = int(timezone_str[3:]) # Extract the offset value
75-
return pytz.FixedOffset(offset * 60) # Offset in minutes
76-
except ValueError:
77-
logging.warning(f"Invalid timezone format: {timezone_str}. Using default {DEFAULT_TIMEZONE}.")
78-
return pytz.timezone(DEFAULT_TIMEZONE)
74+
pass
75+
76+
# 2) Support UTC/GMT fixed offsets like UTC+5:30, UTC-3, UTC+0530, GMT+9, etc.
77+
s = timezone_str.strip().upper().replace("UTC ", "UTC").replace("GMT ", "GMT")
78+
79+
# Special case: plain UTC/GMT
80+
if s in ("UTC", "GMT", "Z"):
81+
return pytz.UTC
82+
83+
# Match formats: UTC+H, UTC+HH, UTC+H:MM, UTC+HH:MM, UTC+HHMM (and GMT variants)
84+
m = re.match(r'^(?:UTC|GMT)\s*([+-])\s*(\d{1,2})(?::?(\d{2}))?$', s)
85+
if m:
86+
sign = 1 if m.group(1) == '+' else -1
87+
hours = int(m.group(2))
88+
minutes = int(m.group(3)) if m.group(3) else 0
89+
total_minutes = sign * (hours * 60 + minutes)
90+
return pytz.FixedOffset(total_minutes)
91+
92+
# Match decimal hours like UTC+5.5 or UTC-3.75
93+
m = re.match(r'^(?:UTC|GMT)\s*([+-])\s*(\d{1,2})\.(\d+)$', s)
94+
if m:
95+
sign = 1 if m.group(1) == '+' else -1
96+
hours = int(m.group(2))
97+
frac = float('0.' + m.group(3))
98+
minutes = int(round(frac * 60))
99+
total_minutes = sign * (hours * 60 + minutes)
100+
return pytz.FixedOffset(total_minutes)
101+
102+
logging.warning(f"Invalid timezone format: {timezone_str}. Using default {DEFAULT_TIMEZONE}.")
103+
return pytz.timezone(DEFAULT_TIMEZONE)
104+
79105
return pytz.timezone(DEFAULT_TIMEZONE)
80106

81107

@@ -155,19 +181,26 @@ def get_user_study_status(nickname):
155181
file_content = file.read()
156182
user_tz = get_user_timezone(file_content)
157183
logging.info(f"File content length for {nickname}: {len(file_content)} user_tz: {user_tz}")
158-
current_date = datetime.now(user_tz).replace(hour=0, minute=0, second=0, microsecond=0)
184+
now_local = datetime.now(user_tz)
159185

160186
for date in get_date_range():
161-
# 直接比较 UTC 日期,避免时区转换问题
162-
utc_date = date.astimezone(user_tz).replace(hour=0, minute=0, second=0, microsecond=0)
163-
user_current_date = current_date
164-
165-
if utc_date.date() == user_current_date.date():
166-
user_status[date] = "✅" if check_md_content(file_content, date, user_tz) else " "
167-
elif utc_date.date() > user_current_date.date():
187+
# Treat each UTC program day as a 24h window [start_utc, next_start_utc)
188+
start_utc = date.replace(hour=0, minute=0, second=0, microsecond=0)
189+
next_start_utc = (start_utc + timedelta(days=1))
190+
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)
194+
195+
if now_local < start_local:
196+
# Future day for this user
168197
user_status[date] = " "
169-
else:
198+
elif now_local >= end_local:
199+
# Past day: must be ✅ or ⭕️
170200
user_status[date] = "✅" if check_md_content(file_content, date, user_tz) else "⭕️"
201+
else:
202+
# 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 " "
171204
logging.info(f"Successfully processed file for user: {nickname}")
172205
except FileNotFoundError:
173206
logging.error(f"Error: Could not find file {file_name}")
@@ -285,21 +318,27 @@ def generate_user_row(user):
285318

286319
user_tz = get_user_timezone(file_content)
287320

288-
user_current_day = datetime.now(user_tz).replace(hour=0, minute=0, second=0, microsecond=0)
321+
now_local = datetime.now(user_tz)
289322
date_range = get_date_range()
290323

291324
for i, date in enumerate(date_range):
292-
user_datetime = date.astimezone(pytz.UTC).replace(hour=0, minute=0, second=0, microsecond=0)
325+
# UTC window for the program day
326+
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)
293331

294332
if is_eliminated:
295333
new_row += " |"
296334
continue
297335

298-
if user_datetime.date() > user_current_day.date():
336+
# Future day for this user
337+
if now_local < start_local:
299338
new_row += " |"
300339
continue
301340

302-
days_from_start = (user_datetime.date() - START_DATE.date()).days
341+
days_from_start = (start_utc.date() - START_DATE.date()).days
303342
week_number = days_from_start // 7
304343

305344
cycle_start_day = week_number * 7
@@ -308,14 +347,15 @@ def generate_user_row(user):
308347
absent_count = 0
309348
for day_idx in range(cycle_start_day, min(cycle_end_day + 1, i + 1)):
310349
if day_idx < len(date_range):
311-
check_date = date_range[day_idx].astimezone(pytz.UTC).replace(hour=0, minute=0, second=0, microsecond=0)
312-
check_date_local = check_date.astimezone(user_tz).replace(hour=0, minute=0, second=0, microsecond=0)
313-
if check_date.date() <= user_current_day.date():
314-
status = user_status.get(check_date, "⭕️")
350+
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)
352+
# Only count days that have fully ended in user's local time
353+
if now_local >= check_end_local:
354+
status = user_status.get(check_start_utc, "⭕️")
315355
if status == "⭕️":
316356
absent_count += 1
317357

318-
current_status = user_status.get(user_datetime, "⭕️")
358+
current_status = user_status.get(start_utc, "⭕️")
319359

320360
if absent_count > 2:
321361
is_eliminated = True

0 commit comments

Comments
 (0)