如何使用不同的时区Nodatime将UTC日期和时间转换为当地时间
我正在使用从外部服务器通过互联网获取日期时间的function。 这是我用来获取日期和时间的function,而不依赖于用户的PC日期时间设置。
using NodaTime; using NodaTime.Text; using System.IO; using System.Globalization; public static DateTime GetFastestNISTDate() { var result = DateTime.MinValue; DateTime utcDateTime = DateTime.MinValue; // Initialize the list of NIST time servers // https://tf.nist.gov/tf-cgi/servers.cgi string[] servers = new string[] { "nist1-ny.ustiming.org", "nist1-nj.ustiming.org", "nist1-pa.ustiming.org", "time-a.nist.gov", "time-b.nist.gov", "nist1.aol-va.symmetricom.com", "nist1.columbiacountyga.gov", "nist1-chi.ustiming.org", "nist.expertsmi.com", "nist.netservicesgroup.com" }; // Try 5 servers in random order to spread the load Random rnd = new Random(); foreach (string server in servers.OrderBy(s => rnd.NextDouble()).Take(5)) { try { // Connect to the server (at port 13) and get the response string serverResponse = string.Empty; using (var reader = new StreamReader(new System.Net.Sockets.TcpClient(server, 13).GetStream())) { serverResponse = reader.ReadToEnd(); } // If a response was received if (!string.IsNullOrEmpty(serverResponse)) { // Split the response string ("55596 11-02-14 13:54:11 00 0 0 478.1 UTC(NIST) *") string[] tokens = serverResponse.Split(' '); // Check the number of tokens if (tokens.Length >= 6) { // Check the health status string health = tokens[5]; if (health == "0") { // Get date and time parts from the server response string[] dateParts = tokens[1].Split('-'); string[] timeParts = tokens[2].Split(':'); // Create a DateTime instance utcDateTime = new DateTime( Convert.ToInt32(dateParts[0]) + 2000, Convert.ToInt32(dateParts[1]), Convert.ToInt32(dateParts[2]), Convert.ToInt32(timeParts[0]), Convert.ToInt32(timeParts[1]), Convert.ToInt32(timeParts[2])); // Convert received (UTC) DateTime value to the local timezone result = utcDateTime.ToLocalTime(); //return result; return utcDateTime; // Response successfully received; exit the loop } } } } catch { // Ignore exception and try the next server } } //return result; return utcDateTime; }
这个variable result
有本地日期时间,但我需要使用Nodatime库,我将把我的本地日期时间变量result
,并指定不同的时区,Noda libraray将返回该时区的本地日期和时间。
只是指导我如何实现它。 我访问这个url但仍不清楚如何将Nodatime图书馆和本地时间从外部服务器整合在一起,以获得基于不同时区的另一个日期时间。
寻求帮助的一些示例代码谢谢
编辑
var wc = GetFastestNISTDate(); var pattern = InstantPattern.CreateWithInvariantCulture("dd/MM/yyyy HH:mm:ss"); var parseResult = pattern.Parse(wc.ToString("dd/MM/yyyy HH:mm:ss", CultureInfo.InvariantCulture)); if (!parseResult.Success) throw new InvalidDataException("...whatever..."); var instant = parseResult.Value; var timeZone = DateTimeZoneProviders.Tzdb["Europe/London"]; var zonedDateTime = instant.InZone(timeZone); var bclDateTime = zonedDateTime.ToDateTimeUnspecified();
时区翻译不起作用。 我从这个函数GetFastestNISTDate();
得到了正确的日期GetFastestNISTDate();
然后我尝试根据我的第一个utc时间获取不同时区的本地日期和时间,但代码返回伦敦错误的时间。 我想我错了代码。 任何人都可以看到和帮助。 谢谢
编辑2
我想通过Nodatime图书馆实现的目标。
var wc = GetFastestNISTDate(); TimeZoneInfo cstZone = TimeZoneInfo.FindSystemTimeZoneById("GMT Standard Time"); DateTime cstTime = TimeZoneInfo.ConvertTimeFromUtc(wc, cstZone);
上面的代码给出了或多或少的正确时间。 告诉我如何使用nodatime库替换我的最后2行。 谢谢
编辑3
var wc = GetFastestNISTDate(); Instant now = Instant.FromDateTimeUtc(wc); var timeZone = DateTimeZoneProviders.Tzdb["Europe/London"]; var zonedDateTime = instant.InZone(timeZone); var bclDateTime = zonedDateTime.ToDateTimeUnspecified();
@John告诉我上面的代码是可以的,因为你说
Don't convert the UTC DateTime to a local version - it's pointless and confusing Use Instant.FromDateTimeUtc to convert a UTC DateTime to an instant GetFastestNISTDate() returning datetime instance and here we just create noda instance from utc datetime using like this code `Instant now = Instant.FromDateTimeUtc(wc);`
它解决了这个问题。
编辑4
@Matt Johnson : thanks a lot for redirecting me to a good library. i would definitely like to work with that library to achieve my task. before use your library i have some question.
-
第1点
你在这个例程中注意到了什么错误
GetFastestNISTDate();
例程查询几个NIST时间服务器并获取utctime。utcDateTime = new DateTime( Convert.ToInt32(dateParts[0]) + 2000, Convert.ToInt32(dateParts[1]), Convert.ToInt32(dateParts[2]), Convert.ToInt32(timeParts[0]), Convert.ToInt32(timeParts[1]), Convert.ToInt32(timeParts[2]));
这个例程GetFastestNISTDate();
回来了utcDateTime ….不是时候吗?
- 第2点
当我打电话给GetFastestNISTDate();
例程我注意到这个例程有一段时间返回DateTime.MinValue
,这不是预期的结果。 我可以理解为什么会发生这种情况, because NIST time servers
正忙或被阻止或当时发生超时。
- 点3如果我使用你当前的代码/库
NodaTime.NetworkClock
然后我想知道它将默认查询哪个NTP服务器?
如果我使用NodaTime.NetworkClock
那么由于NTP server is busy/block
或超时发生,有时候我可能会错误的日期或空日期吗?
编辑5
var instant = NetworkClock.Instance.Now; var timeZone = DateTimeZoneProviders.Tzdb["Europe/London"]; var zonedDateTime = instant.InZone(timeZone); lbldate.Text = zonedDateTime.ToString("dd/MM/yyyy", CultureInfo.InvariantCulture); lbltime.Text = zonedDateTime.ToString("hh:mm:ss", CultureInfo.InvariantCulture);
您的GetFastestNISTDate
函数使用白天协议 – 基本上已弃用, GetFastestNISTDate
用于机器交互,因为其结果不是特定格式。 即使是来自NIST的文档也强烈建议用户使用NTP而不是白天。
您可以在此处找到NTP客户端的简单C#实现。
为了NodaTime.IClock
,我将此客户端实现为NodaTime.IClock
。 代码在GitHub上。 只需从NuGet安装它:
Install-Package NodaTime.NetworkClock
然后就像使用SystemClock
一样使用它:
var instant = NetworkClock.Instance.Now; var timeZone = DateTimeZoneProviders.Tzdb["Europe/London"]; var zonedDateTime = instant.InZone(timeZone);
您不应该将DateTime
转换为字符串并返回 – 但您当前的问题是您将从服务器返回的UTC值转换为本地DateTime
,原因并非明显。 理想情况下,我建议更改GetFastestNISTDate()
以返回Instant
,但假设您不能这样做:
代码的最后一部分(最后三行)没问题,但为什么你需要一个DateTime
呢? 如果您可以使用Noda Time尽可能多地编写代码,那么在代码清晰度方面您将获得最大的好处。
上述就是C#学习教程:如何使用不同的时区Nodatime将UTC日期和时间转换为当地时间分享的全部内容,如果对大家有所用处且需要了解更多关于C#学习教程,希望大家多多关注—计算机技术网(www.ctvol.com)!
本文来自网络收集,不代表计算机技术网立场,如涉及侵权请联系管理员删除。
ctvol管理联系方式QQ:251552304
本文章地址:https://www.ctvol.com/cdevelopment/992249.html