Skip to content
This repository has been archived by the owner on Apr 12, 2023. It is now read-only.

接触一覧でのタイムゾーン変換が正しくないことがある #978

Open
yoshitomo-g opened this issue Apr 17, 2022 · 9 comments
Labels
confirmed 開発内部管理用

Comments

@yoshitomo-g
Copy link

yoshitomo-g commented Apr 17, 2022

不具合の内容 / Describe the bug

接触一覧での時刻表示は端末のタイムゾーン設定に従って変換された結果が使われるが、それが正しくない例があった。

Twitterで見かけたもので、自動設定で東京となっていたにもかかわらず、午前12時00分が起点になっている。
https://twitter.com/Tanukichi01/status/1515406675104366593

再現手順 / Steps to reproduce

不明。

期待される挙動 / Expected behavior

正しくタイムゾーンが変換される。

スクリーンショット / Screenshots

接触一覧

接触一覧

タイムゾーン設定(設定アプリの、「一般」→「日付と時刻」)

タイムゾーン設定

動作環境 / Environments

  • デバイス:iPhone11 Pro
  • OS:iOS 15.4.1
  • バージョン:COCOA v2.0.0

その他 / Additional context

確認をしたスレッド
https://twitter.com/yoshitomo_y/status/1515604339364048898


Internal IDs:

  • Bug 6804
@b-wind
Copy link

b-wind commented Apr 17, 2022

補足情報として。
.NET 的に「0時(24時間表記)」=「午前12時」、「12時(24時間表記)」=「午後12時」 の表記になる様子。

UTC のまま出力されている?(考えにくいとは思う)

@keiji keiji added the waiting-for-confirmation 関係者に確認中のもの label Apr 18, 2022
@keiji
Copy link
Collaborator

keiji commented Apr 18, 2022

ご報告ありがとうございます。
コード上は、次のIExposureDataRepository.ConvertToTermで期間に変換しています。端末の設定に応じてタイムゾーンを変換しているのは .ToLocalTime()ですね。

public static string ConvertToTerm(DateTime utcDatetime)
{
var from = utcDatetime.Date.ToLocalTime();
var to = from.AddDays(1).ToLocalTime();
bool changeMonth = from.Month != to.Month;
bool changeYear = from.Year != to.Year;
string fromFormat = AppResources.ExposureDateFormatMonth;
string toFormat = AppResources.ExposureDateFormatDate;
if (changeMonth)
{
toFormat = AppResources.ExposureDateFormatMonth;
}
if (changeYear)
{
fromFormat = AppResources.ExposureDateFormatYear;
toFormat = AppResources.ExposureDateFormatYear;
}
string fromStr = string.Format(fromFormat, from.Year, from.Month, from.Day, from.Hour);
string toStr = string.Format(toFormat, to.Year, to.Month, to.Day, to.Hour);
return string.Format("{0} {1} {2}", fromStr, AppResources.ExposuresPageTo, toStr);
}

端末のタイムゾーンが、Xamarin(Mono)から、どのように認識されているのかに注目しています。
原因調査・解決と並行して、今すぐできる現象への対応としては、テキストの「設定されているタイムゾーン」に、具体的な時差情報を含めるというのも1つの手かと思います。

@b-wind
Copy link

b-wind commented Apr 18, 2022

https://docs.microsoft.com/ja-jp/dotnet/api/system.timezoneinfo?view=net-5.0

  • TimeZoneInfo.Local.StandardName
  • TimeZoneInfo.Local.DisplayName

のどちらかを表示する手もあるかとは思いますが、分かりやすいかはちょっと疑問が残ります。

@cocoa-dev008 cocoa-dev008 added confirmed 開発内部管理用 and removed waiting-for-confirmation 関係者に確認中のもの labels Apr 18, 2022
@b-wind
Copy link

b-wind commented Apr 18, 2022

これ、「1回の接触」となっているので、COCOA v1.x での接触情報を v2.0.0 で見てるのかな?

@b-wind
Copy link

b-wind commented Apr 18, 2022

現状、 COCOA v1.x で行った接触確認の記録を取りだしたときに、Timestamp の DateTimeKind が Local になっている可能性を考えています。 (あまり自信は無い)

@b-wind
Copy link

b-wind commented Apr 18, 2022

COCOA v1.x での接触確認の結果は userExposureInformationList として取り扱われている。

foreach (var ei in userExposureInformationList.GroupBy(userExposureInformation => userExposureInformation.Timestamp))
{
var ens = new ExposureSummary()
{
Timestamp = ei.Key,
ExposureDate = IExposureDataRepository.ConvertToTerm(ei.Key),
};
ens.SetExposureCount(ei.Count());
exposures.Add(ens);
}

ViewModel で userExposureInformationList を取得している箇所。

var userExposureInformationList
= _exposureDataRepository.GetExposureInformationList(AppConstants.DaysOfExposureInformationToDisplay);

exposureInformation は JSON 形式で保存されているのでデシリアライズ。

var exposureInformationJson = _secureStorageService.GetValue<string>(PreferenceKey.ExposureInformation, null);
if (!string.IsNullOrEmpty(exposureInformationJson))
{
result = JsonConvert.DeserializeObject<List<UserExposureInfo>>(exposureInformationJson);
}

Json.NET での DateTime 型のデシリアライズについて。
#64 (comment)

この想定が正しい場合、ConvertToTerm に渡される引数も(変数名とは違い)ローカル時刻。
ローカル時刻のまま日付操作を行ってしまうので、頂いたスクリーンショットのような結果が予測されます。
(ローカル時刻に対する toLocalTime() は何もしない為)

@keiji
Copy link
Collaborator

keiji commented Apr 18, 2022

ありがとうございます。
シリアライズの時にタイムゾーンが失われ、デシリアライズの過程でDateTimeKind.Localとなっている可能性ですね。その場合、再現性という意味では100%になると思うのですが、ちゃんと表示されてるケースもあるのが気になります。

https://twitter.com/aurata4/status/1515088238108897283

Issueに引用いただいているTanukiti01さんは、iOS版のCOCOAをお使いですね。Tweet時点でのスクリーンショットではENv1での接触記録だけが表示されていますが、次のタイミングでENv2での接触記録が出る可能性があります。
これはiOS版はENv2に切り替えた後、ENv1の接触についてもExposureWindowとDailySummaryが得られるのですが、新しいENv2で得られた接触と、ENv1のころの接触は、タイムスタンプが同じでも実態が同じと区別することができないのでそのまま表示しているためです。

次に出てくる(かもしれない)ENv2の行の日時がどうなっているかで、ExposureInformation固有の問題なのか、C#のToLocal()の不調なのか(ENv2の行も12からになっていればC#起因と判定できる)がわかると考えています。

@b-wind
Copy link

b-wind commented May 30, 2022

こちら、現時点では再現条件が不明と認識していますが問題無いでしょうか。
私の観測範囲では(自身の端末を含め)同様の事象は発見できていないです。

@keiji
Copy link
Collaborator

keiji commented May 30, 2022

はい。再現条件は不明。実際に発生している端末でアプリからどのタイムゾーンが表示されるかを確認すれば何か分かるかも。というフェーズです。

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
confirmed 開発内部管理用
Projects
None yet
Development

No branches or pull requests

4 participants