使用时区城市坐标和当地时间

时间:2016-06-08 20:05:41

标签: c# datetime timezone-offset google-maps-timezone

我正在开发一个安排网站,您可以在其中指定日期,时间,时区城市。我希望在UTC时间将其保存在后端。所以我必须在服务器上以某种方式转换它。我还希望能够即时转换到不同的时区。

在Javascript中,我有一个日期/时间值以及一个时区城市(来自http://www.citytimezones.info,它给出了我的地理坐标)。我没有UTC时间,只有指定时区的时间。

现在我需要将此未来的本地时间转换为UTC。当然,它必须考虑到当时适用的夏令时偏移量。

此外,我想使用第二个时区城市转换为其他当地时间。

我考虑使用Google地图时区API,但这会强制您传递UTC时间,而我没有这个时间,因为我正在尝试计算它。

换句话说,理想情况下我需要一个能够采用这些参数的系统:

  • 未来时间/日期
  • 来源时区城市坐标
  • 目的地时区城市坐标(或null = UTC时间)

并将返回转换时间。

知道如何才能实现这一目标吗?

这可以是Web服务,也可以是Windows C#库。

2 个答案:

答案 0 :(得分:1)

您需要一个时区数据库来执行所需的日期和时间转换。时区比简单地作为偏移更复杂,因为许多时区都包含夏令时规则。

.NET框架允许您使用TimeZoneInfo类来使用基础Windows时区数据库。但是,您可以将Windows时区数据库视为专有。 IANA维护Time Zone Database (TZDB)中描述的Best Current Practice (BCP) 175

Noda Time支持TZDB并提供本地时间戳作为.NET DateTime和时区标识符,您可以计算相应的UTC时间戳:

var localDateTime = LocalDateTime.FromDateTime(dateTime);
var timeZoneId = "America/New_York"];
var timeZone = DateTimeZoneProviders.Tzdb[timeZoneId];
var zonedDateTime = timeZone.AtLeniently(localDateTime);
var utcDateTime = zonedDateTime.ToDateTimeUtc();

请注意,本地时间戳可能不明确或无效。这种情况发生在夏令时转换期间,其中本地时钟向后移动(产生歧义)或向前移动(产生无效时间)。 AtLeniently方法对如何处理歧义和无效时间戳做出了一些假设。这可能是您申请中的错误来源。

当您拥有UTC时间戳和时区ID时,您可以以类似的方式转换为本地时间:

var instant = Instant.FromDateTimeUtc(utcDateTime);
var timeZone = DateTimeZoneProviders.Tzdb[timeZoneId];
var zonedDateTime = instant.InZone(timeZone);
var localDateTime = zonedDateTime.ToDateTimeUnspecified();

在查看http://www.citytimezones.info/之后,似乎cities.txt包含最后一列中每个城市的Windows时区ID。这使您可以根据城市查找Windows时区ID。

然后,您可以使用以下代码将本地DateTime转换为UTC:

var timeZoneId = "Eastern Standard Time";
var timeZoneInfo = TimeZoneInfo.FindSystemTimeZoneById(timeZoneId);
var utcDateTime = TimeZoneInfo.ConvertTimeToUtc(localDateTime, timeZoneInfo);

请注意,如果本地时间戳不明确或无效,ConvertTimeToUtc将抛出ArgumentException

从UTC到本地时间的反向转换:

var localDateTime = TimeZoneInfo.ConvertTimeFromUtc(utcDateTime, timeZoneInfo);

答案 1 :(得分:1)

将问题分成两部分:

  • 从位置协作确定时区
  • 转换时区之间的时间

你会发现有几种方法可以做到。

对于第1步,您提到了Google时区API和CityTimeZones。这两个are listed here以及其他几种方法。

对于第2步,您对.NET的选择主要在Noda TimeTimeZoneInfo之间。马丁给出了每个in his answer的几个很好的例子。

另外,请考虑调度比大多数情况更困难。您应该阅读this post了解更多详情。