[英]How Convert UTC Date & time to local time using different timezone Nodatime
i am using a function which is taking date time over the internet from external server. 我正在使用从外部服务器通过互联网获取日期时间的功能。 here is the function which i am using to get date and time without depend on user pc date time settings.
这是我用来获取日期和时间的功能,而无需依赖用户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
// http://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;
}
this variable result
has local date time but i need to use Nodatime library where i will put my local date time variable result
and also specify different timezone and Noda libraray will return local date and time of that timezone. 此
variable result
具有本地日期时间,但是我需要使用Nodatime库,在该库中我将放置本地日期时间变量result
,并指定不同的时区,Noda libraray将返回该时区的本地日期和时间。
just guide me how to achieve it. 只是指导我如何实现它。 i visit this url but still not clear how to incorporate Nodatime library and local time got from external server together to get another datetime based on different timezone.
我访问此URL,但仍不清楚如何将Nodatime库和从外部服务器获得的本地时间结合在一起,以获取基于不同时区的另一个datetime。
looking for help with bit of sample code thanks 寻求一些示例代码的帮助,谢谢
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();
timezone translation is not working. 时区转换无效。 i got the right date from this function
GetFastestNISTDate();
我从此函数
GetFastestNISTDate();
得到了正确的日期GetFastestNISTDate();
and next i try to get local date and time of different timezone based on my first utc time but code return wrong time for London. 接下来,我尝试根据我的第一个utc时间获取不同时区的本地日期和时间,但是代码返回伦敦的错误时间。 i guess i am making mistake the code.
我想我把代码弄错了。 can anyone see & help.
谁能看到和帮助。 thanks
谢谢
the samething i want to achieve by Nodatime library. 我想通过Nodatime库实现的目标。
var wc = GetFastestNISTDate();
TimeZoneInfo cstZone = TimeZoneInfo.FindSystemTimeZoneById("GMT Standard Time");
DateTime cstTime = TimeZoneInfo.ConvertTimeFromUtc(wc, cstZone);
the above code is giving more or less right time. 上面的代码给或多或少的正确时间。 just tell me how to replace my last 2 line using nodatime library.
告诉我如何使用nodatime库替换我的最后2行。 thanks
谢谢
var wc = GetFastestNISTDate();
Instant now = Instant.FromDateTimeUtc(wc);
var timeZone = DateTimeZoneProviders.Tzdb["Europe/London"];
var zonedDateTime = instant.InZone(timeZone);
var bclDateTime = zonedDateTime.ToDateTimeUnspecified();
@John just tell me the above code is ok because u said @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);`
does it solve the issue. 它解决了这个问题吗?
@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.
Point 1 点1
what was wrong you notice in this routine GetFastestNISTDate();
您在此例程
GetFastestNISTDate();
注意到了什么错误GetFastestNISTDate();
the routine was query few NIST time servers and get the utctime. 该例程是查询几个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]));
this routine GetFastestNISTDate();
此例程
GetFastestNISTDate();
was returning utcDateTime....was not a utc time ? 正在返回utcDateTime ....不是utc时间?
when i was calling GetFastestNISTDate();
当我调用
GetFastestNISTDate();
routine i notice some time this routine was returning DateTime.MinValue
which was not expected result. 例程我注意到一段时间,该例程返回
DateTime.MinValue
,这不是预期的结果。 i could understand why it was happening because NIST time servers
was busy or blocked or timeout occured at that time. 我可以理解为什么会发生这种情况,
because NIST time servers
正忙或阻塞,或者当时发生了超时。
NodaTime.NetworkClock
then i like to know which NTP server it will query by default? NodaTime.NetworkClock
那么我想知道默认情况下将查询哪个NTP服务器? if i use NodaTime.NetworkClock
then is there any chance that some time i may get wrong date or null date due to NTP server is busy/block
or timeout occur? 如果我使用
NodaTime.NetworkClock
那么是否有可能由于NTP server is busy/block
或发生超时而导致我得到错误的日期或空日期的时间?
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);
Your GetFastestNISTDate
function uses the daytime protocol - which is essentially deprecated and NOT meant for machine interaction because its results are in no specific format. 您的
GetFastestNISTDate
函数使用白天协议 -本质上已弃用,并且不打算用于机器交互,因为其结果没有特定的格式。 Even the docs from NIST strongly encourage users to use NTP instead of daytime. 甚至NIST的文档都强烈建议用户使用NTP而不是白天。
You can find a simple C# implementation of an NTP client here . 您可以在此处找到NTP客户端的简单C#实现。
To make things easier, I've implemented this client as a NodaTime.IClock
. 为了使事情变得简单,我已经将此客户端实现为
NodaTime.IClock
。 The code is on GitHub here . 该代码是在GitHub 这里 。 Simply install it from NuGet :
只需从NuGet安装它:
Install-Package NodaTime.NetworkClock
Then you can use it just like you would use the SystemClock
: 然后,您可以像使用
SystemClock
一样使用它:
var instant = NetworkClock.Instance.Now;
var timeZone = DateTimeZoneProviders.Tzdb["Europe/London"];
var zonedDateTime = instant.InZone(timeZone);
You shouldn't be converting the DateTime
to a string and back - but your current problem is that you're converting the UTC value you get back from the server into a local DateTime
for no obvious reason. 您不应该将
DateTime
转换为字符串并返回-但是当前的问题是,您将从服务器获取的UTC值转换为本地DateTime
的原因不明显。 Ideally, I'd suggest changing GetFastestNISTDate()
to return an Instant
, but assuming you can't do that: 理想情况下,我建议更改
GetFastestNISTDate()
以返回Instant
,但是假设您不能这样做:
DateTime.ParseExact
, specifying CultureInfo.InvariantCulture
and DateTimeStyles.AssumeUniversal
DateTime.ParseExact
,指定CultureInfo.InvariantCulture
和DateTimeStyles.AssumeUniversal
DateTime
to a local version - it's pointless and confusing DateTime
转换为本地版本-这毫无意义且令人困惑 Instant.FromDateTimeUtc
to convert a UTC DateTime
to an instant Instant.FromDateTimeUtc
将UTC DateTime
时间转换为即时 The final part of your code (the last three lines) is okay, but why do you need a DateTime
at all? 代码的最后部分(最后三行)可以,但是为什么您完全需要
DateTime
? If you can make as much of your code as possible use Noda Time, you'll get the greatest benefits in terms of code clarity. 如果您可以使用Noda Time尽可能多地使用代码,则在代码清晰性方面将获得最大的好处。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.