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

マイグレーション処理のタイムゾーン補正に起因する不具合を修正する #531

Merged
merged 25 commits into from
Feb 18, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
0be0ea3
Reproduce a critical bug that migration failed by 'System.ArgumentOut…
keiji Nov 28, 2021
eaf2818
Add data initialization method `SetUpVersion120`.
keiji Nov 28, 2021
eb5bf4b
Add migration-tests from v1.2.0 to 1.2.2, 1.2.3, 1.3.0.
keiji Nov 28, 2021
eaf0b57
Merge pull request #527 from keiji/fix_migration_test
keiji Nov 28, 2021
f76a589
Fix an issue that migration failed when DateTime is DateTime.MinValue.
keiji Nov 27, 2021
e8c0222
Add TimeZoneConverter license.
keiji Nov 28, 2021
40c38bd
Refactoring.
keiji Nov 28, 2021
e6bb4a2
Change timezone convet process in TermsUpdateInfoModel.
keiji Nov 28, 2021
3bba6d2
Change timezone convet process in MigrationServiceTests.
keiji Nov 28, 2021
8ba2ee4
Fix test.
keiji Nov 28, 2021
f96b165
Merge pull request #525 from keiji/fix_convert_timezone_jst_to_utc
keiji Nov 28, 2021
5545bff
Add warning comment.
keiji Nov 28, 2021
6fe2f48
Merge pull request #533 from keiji/add_warning_comment
keiji Nov 28, 2021
c8c3131
Merge branch 'develop' of github.com:cocoa-mhlw/cocoa into feature/fi…
keiji Dec 2, 2021
e3d48a1
Make compatible with Hotfix(v1.4.1).
keiji Dec 2, 2021
259c44b
Merge branch 'fix-ios-build' of github.com:cocoa-mhlw/cocoa into feat…
keiji Dec 2, 2021
808a840
Merge branch 'develop' of github.com:cocoa-mhlw/cocoa into feature/fi…
keiji Dec 28, 2021
ed89580
Use TimeZoneInfo as singleton.
keiji Dec 28, 2021
41cf45a
Merge branch 'develop' of github.com:cocoa-mhlw/cocoa into feature/fi…
keiji Jan 8, 2022
ba3f41a
Fix build.
keiji Jan 8, 2022
7b9c90d
Fix test.
keiji Jan 8, 2022
52da97d
Fix build.
keiji Jan 8, 2022
aad5a45
Merge branch 'develop' of github.com:cocoa-mhlw/cocoa into feature/fi…
keiji Feb 17, 2022
0b109a7
Fix unit-test.
keiji Feb 17, 2022
4e4b913
Update TimeZoneConverter version.
keiji Feb 18, 2022
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 34 additions & 0 deletions COPYRIGHT_THIRD_PARTY_SOFTWARE_NOTICES.md
Original file line number Diff line number Diff line change
Expand Up @@ -360,6 +360,40 @@ A "contributor" is any person that distributes its contribution under this licen

(E) The software is licensed "as-is." You bear the risk of using it. The contributors give no express warranties, guarantees or conditions. You may have additional consumer rights under your local laws which this license cannot change. To the extent permitted under your local laws, the contributors exclude the implied warranties of merchantability, fitness for a particular purpose and non-infringement.

---
## TimeZoneConverter
---

Copyright (c) 2017 Matt Johnson-Pint
https://github.com/mattjohnsonpint/TimeZoneConverter

While we certainly hope this software is useful, none of the authors or
contributors place any guarantees as to the accuracy of the data or the
results returned by using this library.

This library is distributed under the terms of the MIT License:

-----------------------------------------------------------------------------
The MIT License (MIT)

Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-----------------------------------------------------------------------------

---
## Google.Protobuf
---
Expand Down
22 changes: 22 additions & 0 deletions Covid19Radar/Covid19Radar.Android/Assets/license.html
Original file line number Diff line number Diff line change
Expand Up @@ -1267,6 +1267,28 @@ <h2>
<p>(E) The software is licensed "as-is." You bear the risk of using it. The contributors give no express warranties, guarantees or conditions. You may have additional consumer rights under your local laws which this license cannot change. To the extent permitted under your local laws, the contributors exclude the implied warranties of merchantability, fitness for a particular purpose and non-infringement.</p>
<hr>
<h2>
<a id="user-content-timezoneconverter" class="anchor" href="#timezoneconverter" aria-hidden="true"><span aria-hidden="true" class="octicon octicon-link"></span></a>TimeZoneConverter</h2>
<hr>
<p>The MIT License (MIT)</p>
<p>Copyright (c) 2017 Matt Johnson-Pint</p>
<p>https://github.com/mattjohnsonpint/TimeZoneConverter</p>
<p>Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:</p>
<p>The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.</p>
<p>THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.</p>
<hr>
<h2>
<a id="user-content-googleprotobuf" class="anchor" href="#googleprotobuf" aria-hidden="true"><span aria-hidden="true" class="octicon octicon-link"></span></a>Google.Protobuf</h2>
<hr>
<p>Copyright 2008 Google Inc. All rights reserved.</p>
Expand Down
22 changes: 22 additions & 0 deletions Covid19Radar/Covid19Radar.iOS/Resources/license.html
Original file line number Diff line number Diff line change
Expand Up @@ -1267,6 +1267,28 @@ <h2>
<p>(E) The software is licensed "as-is." You bear the risk of using it. The contributors give no express warranties, guarantees or conditions. You may have additional consumer rights under your local laws which this license cannot change. To the extent permitted under your local laws, the contributors exclude the implied warranties of merchantability, fitness for a particular purpose and non-infringement.</p>
<hr>
<h2>
<a id="user-content-timezoneconverter" class="anchor" href="#timezoneconverter" aria-hidden="true"><span aria-hidden="true" class="octicon octicon-link"></span></a>TimeZoneConverter</h2>
<hr>
<p>The MIT License (MIT)</p>
<p>Copyright (c) 2017 Matt Johnson-Pint</p>
<p>https://github.com/mattjohnsonpint/TimeZoneConverter</p>
<p>Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:</p>
<p>The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.</p>
<p>THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.</p>
<hr>
<h2>
<a id="user-content-googleprotobuf" class="anchor" href="#googleprotobuf" aria-hidden="true"><span aria-hidden="true" class="octicon octicon-link"></span></a>Google.Protobuf</h2>
<hr>
<p>Copyright 2008 Google Inc. All rights reserved.</p>
Expand Down
31 changes: 31 additions & 0 deletions Covid19Radar/Covid19Radar/Common/AppConstants.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,24 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */

using System;
using TimeZoneConverter;

namespace Covid19Radar.Common
{
public static class AppConstants
{
/// <summary>
/// COCOA's birthday.
/// </summary>
public static readonly DateTime COCOA_FIRST_RELEASE_DATE
= DateTime.SpecifyKind(new DateTime(2020, 06, 19, 9, 0, 0), DateTimeKind.Utc);

/// <summary>
/// Japan Standard Time (JST), UTC +9
/// </summary>
public static TimeZoneInfo TIMEZONE_JST = JstTimeZoneInfo();

/// <summary>
/// Timestamp format - RFC 3339
/// </summary>
Expand Down Expand Up @@ -66,5 +80,22 @@ public static class AppConstants
/// Delay for error in TEK re-registration.
/// </summary>
public const int DelayForRegistrationErrorMillis = 5000;

#region Other Private Methods

private static TimeZoneInfo JstTimeZoneInfo()
{
if (TZConvert.TryGetTimeZoneInfo("Asia/Tokyo", out var timezoneInfo))
{
return timezoneInfo;
}
else
{
// Emergency fallback
return TimeZoneInfo.CreateCustomTimeZone("JST", new TimeSpan(9, 0, 0), "(GMT+09:00) JST", "JST");
}
}

#endregion
}
}
36 changes: 2 additions & 34 deletions Covid19Radar/Covid19Radar/Common/Utils.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */

using System;
using System.Linq;

namespace Covid19Radar.Common
{
Expand All @@ -12,9 +11,7 @@ public static class Utils
#region Other Public Methods

public static DateTime JstNow()
{
return TimeZoneInfo.ConvertTime(DateTime.Now, JstTimeZoneInfo());
}
=> TimeZoneInfo.ConvertTime(DateTime.Now, AppConstants.TIMEZONE_JST);
This conversation was marked as resolved.
Show resolved Hide resolved

public static DateTime[] JstDateTimes(int days)
{
Expand All @@ -25,41 +22,12 @@ public static DateTime[] JstDateTimes(int days)
DateTime[] dateTimes = new DateTime[days];
for (int index = 0; index < days; index++)
{
dateTimes[index] = TimeZoneInfo.ConvertTime(DateTime.Now.AddDays(-index), JstTimeZoneInfo());
dateTimes[index] = TimeZoneInfo.ConvertTime(DateTime.Now.AddDays(-index), AppConstants.TIMEZONE_JST);
}
return dateTimes;
}

#endregion

#region Other Private Methods

private static TimeZoneInfo JstTimeZoneInfo()
{
// iOS/Android/Unix
try
{
return TimeZoneInfo.FindSystemTimeZoneById("Asia/Tokyo");
}
catch (TimeZoneNotFoundException)
{
// Not iOS/Android/Unix
}

// Windows
try
{
return TimeZoneInfo.FindSystemTimeZoneById("Tokyo Standard Time");
}
catch (TimeZoneNotFoundException)
{
// Not Windows
}

// Emergency fallback
return TimeZoneInfo.CreateCustomTimeZone("JST", new TimeSpan(9, 0, 0), "(GMT+09:00) JST", "JST");
}

#endregion
}
}
1 change: 1 addition & 0 deletions Covid19Radar/Covid19Radar/Covid19Radar.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@
<PackageReference Include="Azure.Storage.Blobs" Version="12.9.1" />
<PackageReference Include="Chino.Common" Version="1.0.0-rc11" />
<PackageReference Include="Prism.DryIoc.Extensions" Version="8.0.62" />
<PackageReference Include="TimeZoneConverter" Version="5.0.0" />
</ItemGroup>
<ItemGroup>
<Compile Include="Controls\CustomDatePicker.cs" />
Expand Down
8 changes: 5 additions & 3 deletions Covid19Radar/Covid19Radar/Model/TermsUpdateInfoModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */

using System;
using Covid19Radar.Common;
using Newtonsoft.Json;

namespace Covid19Radar.Model
Expand All @@ -17,8 +18,6 @@ public class TermsUpdateInfoModel

public class Detail
{
private readonly TimeSpan TIME_DIFFERENCIAL_JST_UTC = TimeSpan.FromHours(+9);

[JsonProperty("text")]
public string Text { get; set; }

Expand All @@ -29,7 +28,10 @@ public class Detail
public DateTime UpdateDateTimeJst { get; set; }

public DateTime UpdateDateTimeUtc
=> DateTime.SpecifyKind(UpdateDateTimeJst - TIME_DIFFERENCIAL_JST_UTC, DateTimeKind.Utc);
=> TimeZoneInfo.ConvertTimeToUtc(
DateTime.SpecifyKind(UpdateDateTimeJst, DateTimeKind.Unspecified),
AppConstants.TIMEZONE_JST
);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,11 @@ private async Task MigrateTermAsync(TermsType termsType, bool isAgree)
}
else
{
/// **WARNING**
/// `new DateTime()` means `DateTime.MinValue`, it equals `0001/01/01 00:00:00`.
/// For converting timezone, please use `TimeZoneInfo.ContertTimeTo*`.
/// Do not use direct calculation (e.g. subtract `TimeSpan.FromHours(9)` from `DateTime.MinValue`)
/// because it cause an ArgumentOutOfRangeException.
_preferencesService.SetValue(preferenceKey, new DateTime().ToString());
_loggerService.Info($"Migrated {applicationPropertyKey}");
}
Expand Down
44 changes: 25 additions & 19 deletions Covid19Radar/Covid19Radar/Services/Migration/Migrator_1_3_0.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,6 @@ internal class Migrator_1_3_0
private const string TERMS_OF_SERVICE_LAST_UPDATE_DATETIME = "TermsOfServiceLastUpdateDateTime";
private const string PRIVACY_POLICY_LAST_UPDATE_DATETIME = "PrivacyPolicyLastUpdateDateTime";

private readonly DateTime FALLBACK_DATETIME = new DateTime(2020, 6, 19);
private readonly TimeSpan TIME_DIFFERENCIAL_JST_UTC = TimeSpan.FromHours(+9);

private readonly IPreferencesService _preferencesService;
private readonly ILoggerService _loggerService;

Expand All @@ -34,16 +31,19 @@ public Task ExecuteAsync()
{
if (_preferencesService.ContainsKey(START_DATETIME))
{
MigrateDateTimeToEpoch(START_DATETIME, PreferenceKey.StartDateTimeEpoch, TimeSpan.Zero, DateTime.UtcNow);
MigrateDateTimeToEpoch(START_DATETIME, PreferenceKey.StartDateTimeEpoch,
timeZoneInfo: null,
fallbackDateTime: DateTime.UtcNow
);
}

if (_preferencesService.ContainsKey(TERMS_OF_SERVICE_LAST_UPDATE_DATETIME))
{
MigrateDateTimeToEpoch(
TERMS_OF_SERVICE_LAST_UPDATE_DATETIME,
PreferenceKey.TermsOfServiceLastUpdateDateTimeEpoch,
-TIME_DIFFERENCIAL_JST_UTC,
FALLBACK_DATETIME
timeZoneInfo: AppConstants.TIMEZONE_JST,
fallbackDateTime: AppConstants.COCOA_FIRST_RELEASE_DATE
);
}

Expand All @@ -52,38 +52,44 @@ public Task ExecuteAsync()
MigrateDateTimeToEpoch(
PRIVACY_POLICY_LAST_UPDATE_DATETIME,
PreferenceKey.PrivacyPolicyLastUpdateDateTimeEpoch,
-TIME_DIFFERENCIAL_JST_UTC,
FALLBACK_DATETIME
timeZoneInfo: AppConstants.TIMEZONE_JST,
fallbackDateTime: AppConstants.COCOA_FIRST_RELEASE_DATE
);
}

return Task.CompletedTask;
}

private void MigrateDateTimeToEpoch(string dateTimeKey, string epochKey, TimeSpan differential, DateTime fallbackDateTime)
private void MigrateDateTimeToEpoch(string dateTimeKey, string epochKey, TimeZoneInfo? timeZoneInfo, DateTime fallbackDateTime)
{
string dateTimeStr = _preferencesService.GetValue(dateTimeKey, fallbackDateTime.ToString());

/// **Note**
/// `dateTime` still can be `0001/01/01 00:00:00` (= UNIX Epoch:`-62135596800`).
/// For compatibility reasons, do not change this behavior.
DateTime dateTime;
try
{
dateTime = DateTime.SpecifyKind(DateTime.Parse(dateTimeStr), DateTimeKind.Utc);
dateTime = DateTime.Parse(dateTimeStr);

if (timeZoneInfo is null)
{
dateTime = DateTime.SpecifyKind(dateTime, DateTimeKind.Utc);
}
else
{
dateTime = TimeZoneInfo.ConvertTimeToUtc(
DateTime.SpecifyKind(dateTime, DateTimeKind.Unspecified),
timeZoneInfo
);
}
}
catch (FormatException exception)
{
_loggerService.Exception($"Parse dateTime FormatException occurred. {dateTimeStr}", exception);
dateTime = fallbackDateTime;
}

try
{
dateTime += differential;
}
catch (ArgumentOutOfRangeException exception)
{
_loggerService.Exception($"{dateTimeStr} {differential} The added or subtracted value results in an un-representable DateTime.", exception);
}

_preferencesService.SetValue(epochKey, dateTime.ToUnixEpoch());
_preferencesService.RemoveValue(dateTimeKey);
}
Expand Down
Loading