我有以下代码从位置转换为TimeZone名称.
public TimeZoneResponse ConvertCityToTimeZoneName(string location) { TimeZoneResponse response = new TimeZoneResponse(); var plusName = location.Replace(" ","+"); var address = "http://maps.google.com/maps/api/geocode/json?address=" + plusName + "&sensor=false"; var result = new System.Net.WebClient().DownloadString(address); var latLongResult = JsonConvert.DeserializeObject<GoogleGeoCodeResponse>(result); if (latLongResult.status == "OK") { var timeZoneRespontimeZoneRequest = "https://maps.googleapis.com/maps/api/timezone/json?location=" + latLongResult.results[0].geometry.location.lat + "," + latLongResult.results[0].geometry.location.lng + "×tamp=1362209227&sensor=false"; var timeZoneResponseString = new System.Net.WebClient().DownloadString(timeZoneRespontimeZoneRequest); var timeZoneResult = JsonConvert.DeserializeObject<TimeZoneResult>(timeZoneResponseString); if (timeZoneResult.status == "OK") { response.TimeZoneName = timeZoneResult.timeZoneName; response.Success = true; return response; } } return response;
}
因此,当我通过“纽约,美国”时,它返回“东部标准时间”
然后我有第二个函数将一个源时区的时间转换为上面的另一个检索时区.
var timeInDestTimeZone = TimeZoneInfo.ConvertTimeBySystemTimeZoneId(sourceDate.Date,TimeZoneInfo.Local.Id,destination.TimeZoneName);
它运作良好,直到我遇到这个例子.当我进入时:澳大利亚墨尔本成为我回归的第一个功能:澳大利亚东部夏令时
当我将澳大利亚东部夏令时传递到我的第二个函数(作为最终参数)时,我得到了这个错误:
在本地计算机上找不到时区ID“Australian Eastern Daylight Time”
关于我做错了什么的任何建议?当我查看来自第二个谷歌地图API调用的响应时,这些是我得到的所有字段(以LA为例):
{ "dstOffset" : 0.0,"rawOffset" : -28800.0,"status" : "OK","timeZoneId" : "America/Los_Angeles","timeZoneName" : "Pacific Standard Time" }
当我通过墨尔本时,我看到TimeZoneId字段设置为:“”Australia / Hobart“”.这是查看时区计算的正确字段吗?或者我应该看看其他“偏移”字段?
任何建议将不胜感激.
解决方法
由于.NET实现了时区,因此没有内置的方法来进行1:1转换.您将不得不求助于使用第三方库(或实施您自己的转换).
这question要求提供与您正在寻找的非常相似的解决方案.
提问者在内部使用Olson Time Zone Database(tz数据库/ zoneinfo数据库/ IANA时区数据库)找到了解决方案.提问者参考了page,其中解释了有关转换的一些内容.
最后,您可以使用Noda Time,它实现了您正在寻找的功能. Jon Skeet的answer早在2011年就可以看到图书馆的发展.
库的Key Concepts page包含一个解释转换功能的Date/Time Zone块.
UPDATE
这是关于如何创建这样的查找表的example:
// Note: this version lets you work with any IDateTimeZoneSource,although as the only // other built-in source is BclDateTimeZoneSource,that may be less useful :) private static IDictionary<string,string> LoadTimeZoneMap(IDateTimeZoneSource source) { var nodaToWindowsMap = new Dictionary<string,string>(); foreach (var bclZone in TimeZoneInfo.GetSystemTimeZones()) { var nodaId = source.MapTimeZoneId(bclZone); if (nodaId != null) { nodaToWindowsMap[nodaId] = bclZone.Id; } } return nodaToWindowsMap; }