2016-06-08 72 views
3

我正在开发一个可以指定日期,时间,时区城市的日程安排网站。我想将它保存在UTC时间的后端。所以我必须在服务器上以某种方式转换它。我也想提供转换到不同时区的能力。使用时区城市坐标和当地时间的时区转换

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

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

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

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

换句话说,最好我需要一个系统,将这些参数:

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

并且将返回转换的时间。

任何想法我能做些什么来实现这一点?

这可能是Web服务或Windows C#库。

+0

如果未来的时区规则发生变化,那么未来的UTC时间可能会变得不正确。时区规则经常令人惊讶地发生变化。显然,这个问题适用于所有多时区调度应用程序,我认为唯一的解决方案是存储原始本地时间,以便在将来适用的时区规则发生变化时重新计算UTC时间。 –

+0

@MartinLiversage是的,我打算存储这样做。调度还会保存当地时间,以便我们可以重新计算UTC时间。 – Emmanuel

+0

我不知道为什么这被标记为“DateTime vs DateTimeOffset”的重复。这太荒谬了,因为另一个问题甚至没有谈到时区之间的翻译。充其量,这可能是“谷歌地图时区API vs DateTimeOffset”,但这是它的延伸。 – Emmanuel

回答

1

拆分问题分为两个部分:

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

你会发现几种方法来做每个。

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

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

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

1

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

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

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:在http://www.citytimezones.info/

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

服用后一看似乎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);