我正在使用从外部服务器通过互联网获取日期时间的功能。 这是我用来获取日期和时间的功能,而不依赖于用户的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;
}
这个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();
得到了正确的日期,然后我尝试根据我的第一个utc时间得到不同时区的本地日期和时间,但代码返回错误的伦敦时间。我想我错了代码。任何人都可以看到&救命。感谢
我想通过Nodatime图书馆实现的目标。
var wc = GetFastestNISTDate();
TimeZoneInfo cstZone = TimeZoneInfo.FindSystemTimeZoneById("GMT Standard Time");
DateTime cstTime = TimeZoneInfo.ConvertTimeFromUtc(wc, cstZone);
上面的代码给出了或多或少的正确时间。告诉我如何使用nodatime库替换我的最后2行。感谢
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);`
是否解决了这个问题。
@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 ....这不是一个时间吗?
当我打电话给GetFastestNISTDate();
例程时,我注意到这个例程正在返回DateTime.MinValue
一段时间,这不是预期的结果。我能理解为什么because NIST time servers
正忙或被阻止或当时发生超时。
NodaTime.NetworkClock
,那么我想知道它默认会查询哪个NTP服务器?如果我使用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);
答案 0 :(得分:4)
您的GetFastestNISTDate
函数使用daytime protocol - 基本上已弃用,不适用于机器交互,因为其结果不是特定格式。即使docs from NIST强烈建议用户使用NTP而不是白天。
您可以找到NTP客户端here的简单C#实现。
为了简化操作,我将此客户端实现为NodaTime.IClock
。代码在GitHub here上。只需安装from NuGet:
Install-Package NodaTime.NetworkClock
然后您可以像使用SystemClock
:
var instant = NetworkClock.Instance.Now;
var timeZone = DateTimeZoneProviders.Tzdb["Europe/London"];
var zonedDateTime = instant.InZone(timeZone);
答案 1 :(得分:3)
您不应该将DateTime
转换为字符串并返回 - 但您当前的问题是您将从服务器返回的UTC值转换为本地{{1没有明显的原因。理想情况下,我建议更改DateTime
以返回GetFastestNISTDate()
,但假设您不能这样做:
Instant
,指定DateTime.ParseExact
和CultureInfo.InvariantCulture
DateTimeStyles.AssumeUniversal
转换为本地版本 - 它毫无意义且令人困惑DateTime
将UTC Instant.FromDateTimeUtc
转换为即时代码的最后部分(最后三行)没问题,但为什么你需要一个DateTime
?如果您可以尽可能多地使用Noda Time,那么您将在代码清晰度方面获得最大的好处。