我正在使用Noda Time以Xamarin Forms形式获取设备上的本地时区。我们使用下面的代码将其返回。
NodaTime.DateTimeZoneProviders.Tzdb.GetSystemDefault().Id;
但是,如果您将手机的位置设置为美国西海岸的任何位置,它将返回“ America / Tijuana”。这给我们带来了一个问题,如果在您的位置设置为L.A时返回“ America / Los_Angeles”(有效的ID)之类的信息,则可以解决。
有什么想法吗?我如何才能使图书馆返回更准确的ID?
答案 0 :(得分:7)
在某些平台上,并且根据所使用的Noda Time的版本,系统时区的ID不可用,因此我们不得不猜测。我们基于5年后从当年1月1日到1月1日的时区转换来执行此操作。 (这是在生产代码中使用系统时钟的唯一位置。)
我们向TimeZoneInfo
询问其在该时间间隔(IANA时区中的任何有过渡的每个瞬间)的UTC偏移量的想法。然后,我们根据TimeZoneInfo
值对每个IANA时区“打分”,以查看有多少比例的时刻返回相同的UTC偏移量。我们返回匹配次数最多的时区ID,只要它至少是匹配的70%。
就您而言,America / Tijuana和America / Los_Angeles在2018年至2022年的5年中具有相同的过渡期。以tzvalidate格式:
2018-03-11 10:00:00Z -07:00:00 daylight PDT
2018-11-04 09:00:00Z -08:00:00 standard PST
2019-03-10 10:00:00Z -07:00:00 daylight PDT
2019-11-03 09:00:00Z -08:00:00 standard PST
2020-03-08 10:00:00Z -07:00:00 daylight PDT
2020-11-01 09:00:00Z -08:00:00 standard PST
2021-03-14 10:00:00Z -07:00:00 daylight PDT
2021-11-07 09:00:00Z -08:00:00 standard PST
2022-03-13 10:00:00Z -07:00:00 daylight PDT
2022-11-06 09:00:00Z -08:00:00 standard PST
Noda Time无法区分该5年时间段中的两个时区,因此它返回最先找到的那个时区。 (尚不确定首先找到哪个对象,这是我们可能要通过按ID排序时区来解决的问题。为此,我将提出一个问题。)
我希望能帮助您解释所看到的内容-它不能解决问题,但是它表明在可用信息有限的情况下,所有代码(您的代码和Noda Time的代码)均表现合理。
如注释中所建议,您可能想使用特定于平台的代码来解决此问题:iOS上Foundation.NSTimeZone.LocalTimeZone
的.Name
属性,也许还有Java.Util.TimeZone.Default
的.ID
属性在Android上。
答案 1 :(得分:0)
此问题可以通过以下方式解决:
例如: 1.在App.xaml.cs
中public partial class App : Application
{
public static string timeZoneName { get; set; } = string.Empty;
public App()
{
var timezone = string.Empty;
if (Device.RuntimePlatform == Device.Android)
{
timezone = TimeZoneInfo.Local.DisplayName;
}
else if (Device.RuntimePlatform == Device.iOS)
{
timezone = App.timeZoneName;
}
}
}
2。 AppDelegate.cs
public override bool FinishedLaunching(UIApplication app, NSDictionary options)
{
global::Xamarin.Forms.Forms.Init();
App.timeZoneName = NSTimeZone.LocalTimeZone.Name;
LoadApplication(new App());
return base.FinishedLaunching(app, options);
}
var timezone = App.timeZoneName;