11using Microsoft . Data . Sqlite ;
22using PCL . Core . IO . Storage . Cache . Model ;
33using System ;
4+ using System . Globalization ;
45using System . Collections . Generic ;
56using System . Threading ;
67using System . Threading . Tasks ;
@@ -471,6 +472,16 @@ private static void _BindEntryParams(SqliteCommand cmd, CacheEntry e)
471472 cmd . Parameters . AddWithValue ( "@priority" , e . Priority ) ;
472473 }
473474
475+ // 数据库中的时间以 ISO-8601 往返格式("O",UTC 带 Z)写入;读取必须用 RoundtripKind 解析,
476+ // 否则 DateTime.Parse 会把 UTC 转成本地时间并丢失 Kind,使其与 DateTime.UtcNow 的比较偏移一个
477+ // 时区(例如 UTC+8 用户的缓存过期判断会差 8 小时,导致缓存过久失效/供应陈旧数据)。
478+ // 用 TryParse 以容忍损坏/遗留数据:单行时间戳解析失败时回退到 MinValue(对过期判断即视为已过期、
479+ // 对时间排序即视为最旧,均为 fail-safe),避免一行坏数据抛异常中断整个读取路径。
480+ private static DateTime _ParseDateTime ( string value ) =>
481+ DateTime . TryParse ( value , CultureInfo . InvariantCulture , DateTimeStyles . RoundtripKind , out var result )
482+ ? result
483+ : DateTime . MinValue ;
484+
474485 private static CacheEntry _ReadEntry ( SqliteDataReader r ) =>
475486 new ( )
476487 {
@@ -483,9 +494,9 @@ private static CacheEntry _ReadEntry(SqliteDataReader r) =>
483494 FilePath = r . IsDBNull ( 6 ) ? null : r . GetString ( 6 ) ,
484495 ContentHash = r . IsDBNull ( 7 ) ? null : r . GetString ( 7 ) ,
485496 ContentVersion = r . GetInt32 ( 8 ) ,
486- CachedAt = DateTime . Parse ( r . GetString ( 9 ) ) ,
487- LastAccessAt = DateTime . Parse ( r . GetString ( 10 ) ) ,
488- ExpiresAt = r . IsDBNull ( 11 ) ? null : DateTime . Parse ( r . GetString ( 11 ) ) ,
497+ CachedAt = _ParseDateTime ( r . GetString ( 9 ) ) ,
498+ LastAccessAt = _ParseDateTime ( r . GetString ( 10 ) ) ,
499+ ExpiresAt = r . IsDBNull ( 11 ) ? null : _ParseDateTime ( r . GetString ( 11 ) ) ,
489500 HitCount = r . GetInt64 ( 12 ) ,
490501 Tags = r . GetString ( 13 ) ,
491502 GroupName = r . GetString ( 14 ) ,
@@ -538,8 +549,8 @@ private static InstanceCacheRow _ReadInstanceRow(SqliteDataReader r)
538549 JavaVersion = r . IsDBNull ( 16 ) ? null : r . GetInt32 ( 16 ) ,
539550 SourceJsonHash = r . GetString ( 17 ) ,
540551 FormatVersion = r . GetInt32 ( 18 ) ,
541- CachedAt = DateTime . Parse ( r . GetString ( 19 ) ) ,
542- LastLoadedAt = r . IsDBNull ( 20 ) ? null : DateTime . Parse ( r . GetString ( 20 ) ) ,
552+ CachedAt = _ParseDateTime ( r . GetString ( 19 ) ) ,
553+ LastLoadedAt = r . IsDBNull ( 20 ) ? null : _ParseDateTime ( r . GetString ( 20 ) ) ,
543554 } ;
544555 }
545556
@@ -573,7 +584,7 @@ private static ComponentCacheRow _ReadComponentRow(SqliteDataReader r)
573584 RelativePath = r . GetString ( 3 ) ,
574585 FileHash = r . IsDBNull ( 4 ) ? null : r . GetString ( 4 ) ,
575586 FileSize = r . GetInt64 ( 5 ) ,
576- LastModified = DateTime . Parse ( r . GetString ( 6 ) ) ,
587+ LastModified = _ParseDateTime ( r . GetString ( 6 ) ) ,
577588 Enabled = r . GetInt32 ( 7 ) != 0 ,
578589 ModName = r . IsDBNull ( 8 ) ? null : r . GetString ( 8 ) ,
579590 ModVersion = r . IsDBNull ( 9 ) ? null : r . GetString ( 9 ) ,
@@ -582,7 +593,7 @@ private static ComponentCacheRow _ReadComponentRow(SqliteDataReader r)
582593 ModLoader = r . IsDBNull ( 12 ) ? null : r . GetString ( 12 ) ,
583594 ModDependencies = r . IsDBNull ( 13 ) ? null : r . GetString ( 13 ) ,
584595 CacheVersion = r . GetInt32 ( 14 ) ,
585- ScannedAt = DateTime . Parse ( r . GetString ( 15 ) ) ,
596+ ScannedAt = _ParseDateTime ( r . GetString ( 15 ) ) ,
586597 ScanHash = r . IsDBNull ( 16 ) ? null : r . GetString ( 16 ) ,
587598 } ;
588599 }
0 commit comments