亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

更改.NET中的默認(rèn)時(shí)區(qū)的操作方法

 更新時(shí)間:2024年06月17日 08:58:31   作者:VAllen  
除了"在操作系統(tǒng)中修改時(shí)區(qū)信息,然后重啟.NET應(yīng)用程序,使其生效"之外,如何在不修改操作系統(tǒng)時(shí)區(qū)的前提下,修改.NET中的默認(rèn)時(shí)區(qū)呢,下面小編給大家分享更改.NET中的默認(rèn)時(shí)區(qū)的操作方法,感興趣的朋友一起看看吧

如何更改.NET中的默認(rèn)時(shí)區(qū)?

除了"在操作系統(tǒng)中修改時(shí)區(qū)信息,然后重啟.NET應(yīng)用程序,使其生效"之外。如何在不修改操作系統(tǒng)時(shí)區(qū)的前提下,修改.NET中的默認(rèn)時(shí)區(qū)呢?

這是一位 同學(xué)兼同事 于5月21日在技術(shù)群里問(wèn)的問(wèn)題,我當(dāng)時(shí)簡(jiǎn)單地研究了一下,就寫出來(lái)了。

現(xiàn)在寫文章分享給大家,雖然我覺(jué)得這種需求非常小眾,幾乎不會(huì)有人用到。

正文

正常手段下,.NET是不允許開(kāi)發(fā)者修改默認(rèn)時(shí)區(qū)的,它沒(méi)有公開(kāi)這樣的API。

在 .NET 中,管理時(shí)區(qū)的類型叫 TimeZoneInfo,它位于 System 命名空間下,由 System.Private.CoreLib.dll 提供。

使用 ILSpy 反編譯 System.Private.CoreLib.dll,找到 TimeZoneInfo 類型,我們可以看到 TimeZoneInfo.Local 指向一個(gè)私有字段 s_cachedData 的成員屬性 Local,該字段類型是一個(gè)屬于 TimeZoneInfo 的私有嵌套類型 CachedData。

當(dāng)首次訪問(wèn) CachedData.Local 時(shí),它會(huì)先檢查 _localTimeZone 私有字段是否有值。如果沒(méi)有值,則調(diào)用 CreateLocal 方法從操作系統(tǒng)獲取時(shí)區(qū)信息并且賦值。

看到了這里,我腦海里就浮現(xiàn)了兩種方案:

  • 使用 hook 技術(shù)挾持并修改 win32 api 返回的時(shí)區(qū)信息。
  • 使用 reflection 技術(shù)反射并且修改時(shí)區(qū)信息。

方案1的優(yōu)點(diǎn)是穩(wěn)定,但可能會(huì)被殺毒軟件報(bào)毒。

方案2的優(yōu)點(diǎn)是不會(huì)報(bào)毒,但可能不穩(wěn)定。

為什么說(shuō)方案2不穩(wěn)定呢?因?yàn)?s_cachedData 私有字段值有可能在某個(gè)時(shí)候被重置。

現(xiàn)在我們來(lái)看看方案2的實(shí)現(xiàn):

public static bool TrySetLocalTimeZoneInfo(TimeZoneInfo timeZoneInfo)
{
  Type timeZoneInfoType = typeof(TimeZoneInfo);
  // 獲取TimeZoneInfo類型的私有靜態(tài)字段成員信息s_cachedData
  FieldInfo cachedDataFieldInfo = timeZoneInfoType.GetField("s_cachedData", BindingFlags.NonPublic | BindingFlags.Static);
  if (cachedDataFieldInfo == null)
  {
    return false;
  }
  // 獲取TimeZoneInfo類型的私有嵌套類型CachedData
  Type cachedDataType = timeZoneInfoType.GetNestedType("CachedData", BindingFlags.NonPublic);
  if (cachedDataType == null)
  {
    return false;
  }
  // 獲取CachedData類型的私有字段成員信息_localTimeZone
  FieldInfo localTimeZoneFieldInfo = cachedDataType.GetField("_localTimeZone", BindingFlags.NonPublic | BindingFlags.Instance);
  if (localTimeZoneFieldInfo == null)
  {
    return false;
  }
  // 獲取TimeZoneInfo類型的私有靜態(tài)字段s_cachedData值
  object cachedData = cachedDataFieldInfo.GetValue(null);
  if (cachedData == null)
  {
    return false;
  }
  // 設(shè)置私有字段的值
  localTimeZoneFieldInfo.SetValue(cachedData, timeZoneInfo);
  return true;
}

PS: 該方法代碼實(shí)際測(cè)試在 .NET Core 3.1.NET 5.0.NET 6.0.NET 7.0.NET 8.0 都可以正常工作。

用法:

void Main()
{
  // 設(shè)置前
  Console.WriteLine(TimeZoneInfo.Local);
  // 修改為 GMT 時(shí)區(qū)
  TimeZoneInfo hkTimeZoneInfo = TimeZoneInfo.FindSystemTimeZoneById("GMT Standard Time");
  bool setResult = TrySetLocalTimeZoneInfo(hkTimeZoneInfo);
  // 設(shè)置后
  Console.WriteLine(TimeZoneInfo.Local);
}

注意:這種方案需要嚴(yán)謹(jǐn)測(cè)試,反復(fù)驗(yàn)證。

因?yàn)槭谴鄹?NET內(nèi)部私有變量,不知道是否會(huì)引起其它后果。

比如.NET內(nèi)部其它API沒(méi)有使用 TimeZoneInfo.Local,而是自己在其它地方又緩存了一套 TimeZoneInfo,那就GG了。

又比如,需要檢查整個(gè) .NET Runtime 和其它第三方組件,是否有調(diào)用 TimeZoneInfo.ClearCachedData 靜態(tài)方法 或者 調(diào)用 CultureInfo.ClearCachedData 對(duì)象方法。

到此這篇關(guān)于如何更改.NET中的默認(rèn)時(shí)區(qū)?的文章就介紹到這了,更多相關(guān).NET默認(rèn)時(shí)區(qū)內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

最新評(píng)論