fix: date breaks on iOS devices set to 12-hour time, making getTokenInfo throw FormatException - #67
Merged
Conversation
APIJSONEncoder の DateFormatter に locale が設定されておらず、Locale.current が 使われていた。固定フォーマットの DateFormatter に en_US_POSIX を指定しないと、 端末が12時間表示のとき Foundation が "HH" を "h" + AM/PM に書き換える (QA1480)。 その結果 Flutter チャネルに渡る日付が ISO8601 でなくなり、Dart 側の DateTime.parse が FormatException を投げていた。 ja_JP: 2026-11-20T午前6:56:43.091000Z en_US: 2026-11-20T6:56:43.091000 AMZ レスポンスの日付を文字列化しているのは APIJSONEncoder のみで、生成側の AutogenMethodHandlers.swift も全 150 箇所が self.after 経由のため、この1行で 手書き・生成の両経路が直る。 回帰テストとして、ネイティブが壊れた日付を返したことを Dart 側で検知する テストを追加した (異常系の文字列は iOS 26.5 シミュレータでの実測値)。 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01W5pXxkWbYKDAnQZDpYu1RG
masatoi
force-pushed
the
fix/ios-datetime-12hour-format
branch
from
August 31, 2026 07:48
cce44cf to
f3f9d1c
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Symptom
On an iOS device set to 12-hour time (Settings > General > Date & Time > 24-Hour Time = off), passing a topup QR (check) URL to
PokepayClient.getTokenInfo()fails withFormatException: Invalid date format. Payment QRs (bill) are unaffected.Cause
APIJSONEncoderinios/Classes/SwiftPokepaySdkPlugin.swiftnever set alocaleon itsDateFormatter, soLocale.currentwas used.A fixed-format
DateFormattermust specifyen_US_POSIX; without it, Foundation rewritesHHintohplus an AM/PM marker while the device is on 12-hour time (Apple QA1480). The date that reaches Flutter then stops being ISO8601, and Dart'sDateTime.parsethrows.Measured on the iOS 26.5 simulator:
2026-11-20T06:56:43.091000Z2026-11-20T午前6:56:43.091000Z❌2026-11-20T06:56:43.091000Z✅2026-11-20T6:56:43.091000 AMZ❌2026-11-20T06:56:43.091000Z✅2026-11-20T06:56:43.091000ZPayment QRs survived because
lib/responses/bill.darthas noDateTimefield, so the malformed string passes straight through.lib/responses/check.dartdeclaresexpiresAtas a requiredDateTime.Fix
One line in
APIJSONEncoder:dateFormatter.locale = Locale(identifier: "en_US_POSIX").APIJSONEncoderis the only place that serializes response dates — it is also the onlyDateFormatterin the repository. The generatedAutogenMethodHandlers.swiftcarries no encoder of its own and routes all 150 of its call sites throughself.after, so this single line fixes both the hand-written and the generated paths.Verification
Unit (encoder in isolation): extracted
APIJSONEncoderfrom the real plugin source, compiled it, and measured all four combinations in the table above on the iOS 26.5 simulator.End to end: created a check and a bill on dev, then ran a minimal Flutter app (depending on this SDK by local path) on an iPhone 17 Pro / iOS 26.5.
FormatException: Invalid date format❌expiresAt=2026-11-30 07:11:16.856Z✅The first row reproduces the reported symptom exactly. The real build resolving the
Pokepay2.2.0 pod through CocoaPods also succeeds.Regression tests: added
test/responses/check_test.dart(the firsttest/in this repository). The malformed strings are the measured values above, used verbatim.flutter testpasses 6/6 andflutter analyzereportsNo issues found!.Impact
Before this fix, every response carrying a
DateTimebroke on iOS devices set to 12-hour time: Cashtray, Account (nearest_expires_at), AccountBalance, AccountCpmToken, Coupon, Message,UserTransaction.done_aton the autogen side, and others.Already investigated
2026-11-30T07:11:16.856289Z, valid ISO8601.en_US_POSIXin bothBankAPIJSONDecoder.swiftandBankAPIDateFormatter.swift.res.toString()and contains no date formatting at all (zero uses ofSimpleDateFormatorLocale). The behaviour where a 12/24-hour user preference rewrites a formatter is specific to Foundation/ICU.SwiftPokepaySdkPlugin.swiftcarries no generated-file header, and nogenerate-sdk-*commit has ever touched it. No generator change is required.git log -S "en_US_POSIX"returns nothing across the entire history.APIJSONEncoderhas looked like this since the very first commit (209976e init lib, 2021-07-08), so this is unrelated to any recent change or to 2.2.0. The symptom took its current shape once ios-sdk fixed the decoding side ina765b19(2022-09-05).Note
Version, tags and CHANGELOG are deliberately untouched. Please decide the release plan separately.
Out of scope for this PR
flutter testto thecheckjob here or in a separate PR.pokepay_sdkdoes not support Swift Package Manager and that this will become an error in a future Flutter release. Unrelated to this bug, but it will need attention.🤖 Generated with Claude Code
https://claude.ai/code/session_01W5pXxkWbYKDAnQZDpYu1RG