Describe the bug
On a Thai-language Android or iPhone, the Clock component reads dates with the wrong year. Calling Clock.MakeInstant("06/10/2026") and asking for the year back returns 1483 instead of 2026. This breaks any app that saves and reloads dates, runs countdowns, calculates ages, or schedules alarms.
This is the same class of bug fixed in #3891 (Chart date formatters), but in the Clock component, which has much broader reach since it's used in nearly every tutorial that touches time.
appinventor/components/src/com/google/appinventor/components/runtime/util/Dates.java creates SimpleDateFormat instances without a Locale in three places:
- Line 148,
tryParseDate — used by Clock.MakeInstant, Clock.MakeInstantFromMillis, and Clock.MakeInstantFromParts when parsing a string.
- Line 202,
FormatDateTime.
- Line 222,
FormatDate.
On devices set to a Thai locale, SimpleDateFormat resolves against the Buddhist calendar. Parsing is the dangerous side: Clock.MakeInstant("06/10/2026") reads 2026 as a Buddhist Era year, which is Gregorian year 1483. Any app that parses a date string (saved data, hardcoded dates, user input) silently gets an instant about 543 years in the past. Format has the mirror problem — Clock.FormatDate produces a Buddhist-year string, which then round-trips wrong.
The same root cause exists on iOS. appinventor/components-ios/src/Clock.swift line 16 sets date.locale = Locale.preferredLanguage, so a Thai-language iPhone hits the same wrong-calendar parsing.
Note this should not affect the WeekdayName / MonthName style functions, which intentionally use the device locale for display names and should keep their current behavior.
Also worth flagging: tryParseDate swallows ParseException silently (catch (ParseException e) {} on line 149), so when parsing fails it produces an IllegalArgumentException with no underlying detail. I'll surface the underlying error in the same PR so any remaining locale-related parse failures are debuggable.
Affects
Expected behavior
Clock.MakeInstant with one of the documented format strings (e.g. MM/dd/yyyy) should produce the same instant on every device, regardless of locale. Format and parse should round-trip on every locale.
Steps to reproduce
- Set an Android device or emulator to Thai (Settings > System > Languages > Thai).
- In a test app, call
Clock.MakeInstant("06/10/2026") then Clock.Year(...) on the result.
- Expected:
2026. Actual: 1483.
I have a fix ready following the same approach approved in #3891 and will open PRs for both Android and iOS.
Describe the bug
On a Thai-language Android or iPhone, the Clock component reads dates with the wrong year. Calling
Clock.MakeInstant("06/10/2026")and asking for the year back returns1483instead of2026. This breaks any app that saves and reloads dates, runs countdowns, calculates ages, or schedules alarms.This is the same class of bug fixed in #3891 (Chart date formatters), but in the Clock component, which has much broader reach since it's used in nearly every tutorial that touches time.
appinventor/components/src/com/google/appinventor/components/runtime/util/Dates.javacreatesSimpleDateFormatinstances without aLocalein three places:tryParseDate— used byClock.MakeInstant,Clock.MakeInstantFromMillis, andClock.MakeInstantFromPartswhen parsing a string.FormatDateTime.FormatDate.On devices set to a Thai locale,
SimpleDateFormatresolves against the Buddhist calendar. Parsing is the dangerous side:Clock.MakeInstant("06/10/2026")reads2026as a Buddhist Era year, which is Gregorian year1483. Any app that parses a date string (saved data, hardcoded dates, user input) silently gets an instant about 543 years in the past. Format has the mirror problem —Clock.FormatDateproduces a Buddhist-year string, which then round-trips wrong.The same root cause exists on iOS.
appinventor/components-ios/src/Clock.swiftline 16 setsdate.locale = Locale.preferredLanguage, so a Thai-language iPhone hits the same wrong-calendar parsing.Note this should not affect the
WeekdayName/MonthNamestyle functions, which intentionally use the device locale for display names and should keep their current behavior.Also worth flagging:
tryParseDateswallowsParseExceptionsilently (catch (ParseException e) {}on line 149), so when parsing fails it produces anIllegalArgumentExceptionwith no underlying detail. I'll surface the underlying error in the same PR so any remaining locale-related parse failures are debuggable.Affects
Expected behavior
Clock.MakeInstantwith one of the documented format strings (e.g.MM/dd/yyyy) should produce the same instant on every device, regardless of locale. Format and parse should round-trip on every locale.Steps to reproduce
Clock.MakeInstant("06/10/2026")thenClock.Year(...)on the result.2026. Actual:1483.I have a fix ready following the same approach approved in #3891 and will open PRs for both Android and iOS.