我有以下代码从位置转换到时区名称。
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;
}
所以当我传入"New York, United States"时,它返回"Eastern Standard Time"
然后我有第二个函数,它将时间从一个源时区转换为上面检索到的另一个时区。
var timeInDestTimeZone = TimeZoneInfo.ConvertTimeBySystemTimeZoneId(sourceDate.Date, TimeZoneInfo.Local.Id, destination.TimeZoneName);
它工作得很好,直到我遇到这个例子。当我传入:墨尔本,澳大利亚到第一个函数我得到返回:澳大利亚东部夏令时
当我将澳大利亚东部夏令时传递给第二个函数(作为最后一个参数)时,我得到这个错误:
在本地计算机上找不到时区ID '澳大利亚东部夏令时'
有什么建议我做错了吗?当我看到来自第二个google maps API调用的响应时,这些都是我返回的所有字段(以LA为例):
{
"dstOffset" : 0.0,
"rawOffset" : -28800.0,
"status" : "OK",
"timeZoneId" : "America/Los_Angeles",
"timeZoneName" : "Pacific Standard Time"
}
当我经过墨尔本时,我看到TimeZoneId字段被设置为:"Australia/Hobart"。这是查看时区计算的正确字段吗?或者我应该看看其他"偏移"字段?
由于。net实现时区的方式,没有内置的方法来进行1:1
转换。你将不得不求助于使用第三方库(或实现你自己的转换)。
这个问题要求的解决方案与你正在寻找的非常相似。
询问者通过内部使用Olson时区数据库(tz数据库/zoneinfo数据库/IANA时区数据库)找到了解决方案。请求者引用了一个页面,其中解释了一些关于转换的内容。
最后,您可以使用Noda Time,它实现了您正在寻找的这个功能。乔恩·斯基特的回答让我们提前了解了2011年图书馆的发展情况。
库的关键概念页面包含一个日期/时区块,解释转换功能。
下面是如何创建这样一个查找表的示例:
// 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;
}
100%?然后使用标准时区名称进行验证:
http://en.wikipedia.org/wiki/List_of_tz_database_time_zones
如果在给定的机器上找不到时区,则没有保证的解决方案。您应该让代码创建一个错误消息,说明出现问题的原因。
您确实意识到给定系统的所有者/管理员可能会更改这些设置,或者添加新的设置-这意味着在tz数据库中没有非标准tz名称。