MongoDB服务器实例存储旧日期时区偏移异常问题咨询
德黑兰时区下MongoDB存储旧日期时时区偏移异常
服务器时区为德黑兰时区(GMT+3:30),执行以下JavaScript代码:
var now = new Date(); now.getTimezoneOffset();
返回结果为-210,符合预期。但向MongoDB存储两个日期时出现时区偏移不一致问题:
- 2023-10-13 被存储为
2023-10-12T20:30:00.000+00:00(对应+3:30偏移,正确) - 1966-07-23 被存储为
1966-07-22T19:30:00.000+00:00(对应+4:30偏移,错误,正确应为1966-07-22T20:30:00.000+00:00)
本地MongoDB实例可正确存储该日期,服务器端MongoDB实例存在什么问题?
使用的C#程序代码如下:
var year = 1; var month = 1; var day = 1; Console.Write("Year:"); year = int.Parse(Console.ReadLine()); Console.Write("Month:"); month = int.Parse(Console.ReadLine()); Console.Write("Day:"); day = int.Parse(Console.ReadLine()); var date = new DateTime(year, month, day, 0,0, 0); const string connectionUri = "mongodb://localhost:27017"; var client = new MongoClient(connectionUri); var collection = client.GetDatabase("TestDb").GetCollection<DateClass>("DateClass"); var obj = new DateClass(); obj.DateAndTime = date; await collection.InsertOneAsync(obj); public class DateClass { public ObjectId _id { get; set; } public DateTime DateAndTime { get; set; } }
问题原因及解决方案
核心原因
服务器端的时区数据库(tzdata)版本过旧。德黑兰的时区规则在历史上有过变更:1979年伊朗伊斯兰革命前,伊朗曾短暂使用GMT+4:30的时区偏移,但1966年实际执行的是GMT+3:30偏移。旧版本的tzdata未正确记录这一历史规则,导致存储1966年日期时错误套用了GMT+4:30偏移,生成了错误的UTC时间。
而本地MongoDB实例使用的是较新版本的tzdata,能正确解析1966年德黑兰的时区规则,所以存储结果正确。
解决办法
- 更新服务器时区数据库:根据服务器操作系统执行对应命令更新tzdata包,确保时区规则为最新版本。比如:
- Ubuntu/Debian系统:
apt install tzdata - CentOS/RHEL系统:
yum update tzdata
- Ubuntu/Debian系统:
- 代码层面规避时区依赖:
- 直接以UTC时间存储,避免本地时区转换:
var date = new DateTime(year, month, day, 0, 0, 0, DateTimeKind.Utc); - 明确指定德黑兰时区进行转换,强制使用正确偏移计算:
var tehranTimeZone = TimeZoneInfo.FindSystemTimeZoneById("Iran Standard Time"); var date = new DateTime(year, month, day, 0, 0, 0, DateTimeKind.Unspecified); var utcDate = TimeZoneInfo.ConvertTimeToUtc(date, tehranTimeZone); obj.DateAndTime = utcDate;
- 直接以UTC时间存储,避免本地时区转换:
内容的提问来源于stack exchange,提问作者Nima Masghadi
相关产品推荐
相关产品推荐

