Skip to content

处理系统语音崩溃问题 ValueError: time data '٢٠٢٥-١١-٢٧ ٠٠:٥٢:١٦' does not match format '%Y-%m-%d %H:%M:%S'#199

Open
bxvip wants to merge 1 commit intoopenatx:masterfrom
bxvip:master
Open

处理系统语音崩溃问题 ValueError: time data '٢٠٢٥-١١-٢٧ ٠٠:٥٢:١٦' does not match format '%Y-%m-%d %H:%M:%S'#199
bxvip wants to merge 1 commit intoopenatx:masterfrom
bxvip:master

Conversation

@bxvip
Copy link

@bxvip bxvip commented Nov 27, 2025

No description provided.

@bxvip bxvip changed the title 处理系统语音崩溃问题 处理系统语音崩溃问题 ValueError: time data '٢٠٢٥-١١-٢٧ ٠٠:٥٢:١٦' does not match format '%Y-%m-%d %H:%M:%S' Nov 27, 2025
@codeskyblue codeskyblue requested a review from Copilot January 6, 2026 06:23
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR fixes a ValueError that occurs when parsing app installation timestamps on Android devices configured with non-Latin numeral systems (e.g., Arabic, Persian, Thai). The issue arose because the app_info method expected timestamps in ASCII digits but received them in localized digit formats.

  • Adds a digit normalization function to convert non-ASCII digits from 10 different language numeral systems to ASCII digits
  • Wraps date parsing in try-except blocks with fallback to Unix epoch (1970-01-01) on parsing failures
  • Applies normalization before parsing firstInstallTime and lastUpdateTime fields

)
try:
first_install_time = (datetime.datetime.strptime(_deal_number_cover(m.group(1)), "%Y-%m-%d %H:%M:%S") if m else None)
except (ValueError, TypeError) as e:
Copy link

Copilot AI Jan 6, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The exception variable e is caught but never used. Either remove the variable (use bare except clauses like except (ValueError, TypeError):) or log the exception for debugging purposes to help diagnose parsing issues.

Copilot uses AI. Check for mistakes.
Comment on lines +423 to +426
try:
last_update_time = (datetime.datetime.strptime(_deal_number_cover(m.group(1)), "%Y-%m-%d %H:%M:%S") if m else None)
except (ValueError, TypeError) as e:
last_update_time = datetime.datetime(1970, 1, 1)
Copy link

Copilot AI Jan 6, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Silently falling back to Unix epoch (1970-01-01) when date parsing fails may mask underlying issues and lead to incorrect app metadata. Consider logging the error or providing a more meaningful default value like None, which would be consistent with the original intent (returning None when regex doesn't match). The AppInfo dataclass expects datetime.datetime for these fields, so the type contract may need adjustment if None is preferred.

Copilot uses AI. Check for mistakes.
)
try:
last_update_time = (datetime.datetime.strptime(_deal_number_cover(m.group(1)), "%Y-%m-%d %H:%M:%S") if m else None)
except (ValueError, TypeError) as e:
Copy link

Copilot AI Jan 6, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The exception variable e is caught but never used. Either remove the variable (use bare except clauses like except (ValueError, TypeError):) or log the exception for debugging purposes to help diagnose parsing issues.

Copilot uses AI. Check for mistakes.
Comment on lines +391 to +426
def _deal_number_cover(text):
"""转换任何语言的数字为英文数字"""
if not text:
return text

# 所有数字映射字典
DIGIT_MAPS = {
'arabic': dict(zip('٠١٢٣٤٥٦٧٨٩', '0123456789')), # 阿拉伯语
'persian': dict(zip('۰۱۲۳۴۵۶۷۸۹', '0123456789')), # 波斯语 乌尔都文
'hindi': dict(zip('०१२३४५६७८९', '0123456789')), # 印地文 尼泊尔文 马拉地文
'bengali': dict(zip('০১২৩৪๕৬৭৮৯', '0123456789')), # 孟加拉文
'thai': dict(zip('๐๑๒๓๔๕๖๗๘๙', '0123456789')), # 泰语
'burmese': dict(zip('၀၁၂၃၄၅၆၇၈၉', '0123456789')), # 缅甸文
'khmer': dict(zip('០១២៣៤៥៦៧៨៩', '0123456789')), # 高棉文
'lao': dict(zip('໐໑໒໓໔໕໖໗໘໙', '0123456789')), # 老挝文
'tamil': dict(zip('௦௧௨௩௪௫௬௭௮௯', '0123456789')), # 泰米尔文
'gujarati': dict(zip('૦૧૨૩૪૫૬૭૮૯', '0123456789')), # 古吉拉特文
}

result = text
for lang, digit_map in DIGIT_MAPS.items():
for native_digit, english_digit in digit_map.items():
result = result.replace(native_digit, english_digit)
return result
time_regex = r"[-\d]+\s+[:\d]+"
m = re.compile(f"firstInstallTime=({time_regex})").search(output)
first_install_time = (
datetime.datetime.strptime(m.group(1), "%Y-%m-%d %H:%M:%S") if m else None
)
try:
first_install_time = (datetime.datetime.strptime(_deal_number_cover(m.group(1)), "%Y-%m-%d %H:%M:%S") if m else None)
except (ValueError, TypeError) as e:
first_install_time = datetime.datetime(1970, 1, 1)

m = re.compile(f"lastUpdateTime=({time_regex})").search(output)
last_update_time = (
datetime.datetime.strptime(m.group(1).strip(), "%Y-%m-%d %H:%M:%S")
if m
else None
)
try:
last_update_time = (datetime.datetime.strptime(_deal_number_cover(m.group(1)), "%Y-%m-%d %H:%M:%S") if m else None)
except (ValueError, TypeError) as e:
last_update_time = datetime.datetime(1970, 1, 1)
Copy link

Copilot AI Jan 6, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The app_info method now has digit normalization and error handling logic for date parsing, but lacks test coverage. Since the repository has comprehensive unit tests (in tests/test_adb_shell.py), consider adding a test case that verifies the function correctly handles non-ASCII digits (e.g., Arabic numerals) and gracefully handles parsing failures.

Copilot uses AI. Check for mistakes.
Comment on lines +410 to +413
result = text
for lang, digit_map in DIGIT_MAPS.items():
for native_digit, english_digit in digit_map.items():
result = result.replace(native_digit, english_digit)
Copy link

Copilot AI Jan 6, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The nested function unnecessarily iterates through all 10 digit mappings for every language, even after a replacement is made. Consider using a single comprehensive mapping dictionary that combines all languages, or optimize the function to stop processing after finding matches. For example, you could create a translation table once and use str.translate() which is more efficient than multiple replace() calls.

Copilot uses AI. Check for mistakes.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@copilot open a new pull request to apply changes based on this feedback

pkgflags = pkgflags.split()


def _deal_number_cover(text):
Copy link

Copilot AI Jan 6, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The function name _deal_number_cover is unclear and doesn't follow Python naming conventions. Consider renaming it to _normalize_digits or _convert_digits_to_ascii which better describes its purpose of converting non-ASCII digits to ASCII digits.

Copilot uses AI. Check for mistakes.
Comment on lines +397 to +408
DIGIT_MAPS = {
'arabic': dict(zip('٠١٢٣٤٥٦٧٨٩', '0123456789')), # 阿拉伯语
'persian': dict(zip('۰۱۲۳۴۵۶۷۸۹', '0123456789')), # 波斯语 乌尔都文
'hindi': dict(zip('०१२३४५६७८९', '0123456789')), # 印地文 尼泊尔文 马拉地文
'bengali': dict(zip('০১২৩৪๕৬৭৮৯', '0123456789')), # 孟加拉文
'thai': dict(zip('๐๑๒๓๔๕๖๗๘๙', '0123456789')), # 泰语
'burmese': dict(zip('၀၁၂၃၄၅၆၇၈၉', '0123456789')), # 缅甸文
'khmer': dict(zip('០១២៣៤៥៦៧៨៩', '0123456789')), # 高棉文
'lao': dict(zip('໐໑໒໓໔໕໖໗໘໙', '0123456789')), # 老挝文
'tamil': dict(zip('௦௧௨௩௪௫௬௭௮௯', '0123456789')), # 泰米尔文
'gujarati': dict(zip('૦૧૨૩૪૫૬૭૮૯', '0123456789')), # 古吉拉特文
}
Copy link

Copilot AI Jan 6, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Defining DIGIT_MAPS as a constant inside the function on every call is inefficient. This dictionary should be defined as a module-level constant or class attribute to avoid recreating it each time the function is called. Move this dictionary outside the function scope.

Copilot uses AI. Check for mistakes.
Comment on lines +417 to +420
try:
first_install_time = (datetime.datetime.strptime(_deal_number_cover(m.group(1)), "%Y-%m-%d %H:%M:%S") if m else None)
except (ValueError, TypeError) as e:
first_install_time = datetime.datetime(1970, 1, 1)
Copy link

Copilot AI Jan 6, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Silently falling back to Unix epoch (1970-01-01) when date parsing fails may mask underlying issues and lead to incorrect app metadata. Consider logging the error or providing a more meaningful default value like None, which would be consistent with the original intent (returning None when regex doesn't match). The AppInfo dataclass expects datetime.datetime for these fields, so the type contract may need adjustment if None is preferred.

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants