如何转换UTC日期和放大器;使用不同的时区Nodatime时间为当地时间 [英] How Convert UTC Date & time to local time using different timezone Nodatime

查看:537
本文介绍了如何转换UTC日期和放大器;使用不同的时区Nodatime时间为当地时间的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用的正在约会时在从外部服务器的互联网功能。这里
是我用来获取日期和时间没有功能取决于用户PC日期和时间设置。

 使用NodaTime; 
使用NodaTime.Text;
:使用System.IO;
使用System.Globalization;

公共静态的DateTime GetFastestNISTDate()
{
VAR的结果= DateTime.MinValue;
的DateTime utcDateTime = DateTime.MinValue;

//初始化NIST的时间服务器
名单// http://tf.nist.gov/tf-cgi/servers.cgi
的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
};

//尝试5个服务器以随机顺序以分散负荷
随机RND =新的随机();
的foreach(在servers.OrderBy串服务器(S =方式> rnd.NextDouble())取(5))
{
尝试
{
//连接到服务器(端口处13),并获得响应
串serverResponse =的String.Empty;使用
(VAR读者=新的StreamReader(新System.Net.Sockets.TcpClient(服务器,13).GetStream()))
{
serverResponse = reader.ReadToEnd();
}

//如果响应收到
如果(!string.IsNullOrEmpty(serverResponse))
{
//拆分响应字符串( 55596 14年11月2日13点54分11秒00 0 0 478.1 UTC(NIST)*)
的String []标记= serverResponse.Split('');

//检查令牌
的号码,如果(tokens.Length> = 6)
{
//检查健康状况
串健康=令牌[5];
如果(健康==0)
{
//来自服务器的响应
串获取日期和时间部分[] =日期部分令牌[1] .Split(' - ');
的String [] = timeParts令牌[2] .Split(':');

//创建一个DateTime实例,
utcDateTime =新日期时间(
Convert.ToInt32(日期部分[0])+ 2000年,
Convert.ToInt32(日期部分[1 ]),Convert.ToInt32(日期部分[2]),
Convert.ToInt32(timeParts [0]),Convert.ToInt32(timeParts [1]),
Convert.ToInt32(timeParts [2]) );

//转换接收(UTC)日期时间值到本地时区
结果= utcDateTime.ToLocalTime();

//返回结果;
返回utcDateTime;
//响应成功接收;退出循环

}
}

}

}

{
/ /忽略异常,并尝试下一个服务器
}
}
//返回结果;
返回utcDateTime;
}

变量结果有当地的日期时间,但我需要使用Nodatime图书馆,在那里我会把我的本地日期时间变量结果,还可以指定不同的时区和野田libraray将返回本地日期和时间时区。



只是指导我如何去实现它。我访问这个网址,但尚不清楚如何将Nodatime库和本地时间从外部服务器联合起来根据不同的时区得到另一个日期时间。



寻找与示例代码
感谢的一点帮助



修改



  VAR WC = GetFastestNISTDate(); 

VAR模式= InstantPattern.CreateWithInvariantCulture(DD / MM / YYYY HH:MM:SS);
VAR parseResult = pattern.Parse(wc.ToString(DD / MM / YYYY HH:MM:SS,CultureInfo.InvariantCulture));
如果(!parseResult.Success)
抛出新InvalidDataException(...什么...);
无功瞬间= parseResult.Value;

变种的timeZone = DateTimeZoneProviders.Tzdb [欧洲/伦敦];
VAR zonedDateTime = instant.InZone(的timeZone);
VAR bclDateTime = zonedDateTime.ToDateTimeUnspecified();



时区转换是行不通的。我得到了正确的日期,从这个函数 GetFastestNISTDate(); 和明年我尝试基于我第UTC时间,但代码返回错误的时间,以获得本地日期和不同的时区的时间伦敦。我想我犯错误的代码。任何人都可以看到和放大器;帮帮我。谢谢



编辑2



我想通过Nodatime库来实现samething。

  VAR WC = GetFastestNISTDate(); 

的TimeZoneInfo cstZone = TimeZoneInfo.FindSystemTimeZoneById(GMT标准时间);
的DateTime cstTime = TimeZoneInfo.ConvertTimeFromUtc(WC,cstZone);



上面的代码是给或多或少正确的时间。只是告诉我如何使用nodatime库替换我的最后2行。谢谢



编辑3



  VAR WC = GetFastestNISTDate(); 
即时现在= Instant.FromDateTimeUtc(WC);

变种的timeZone = DateTimeZoneProviders.Tzdb [欧洲/伦敦];
VAR zonedDateTime = instant.InZone(的timeZone);
VAR bclDateTime = zonedDateTime.ToDateTimeUnspecified();



@约翰只是告诉我上面的代码就可以了,因为ü说

 不要将UTC日期时间转换为本地版本 - 这是毫无意义和混乱
使用Instant.FromDateTimeUtc到UTC日期时间转换为即时$ b `
<;
$ b GetFastestNISTDate()返回日期时间实例,在这里,我们刚刚从UTC日期时间使用如下代码`现在即时= Instant.FromDateTimeUtc(WC)创建实例,野田/ pre>

它解决的问题。



编辑4



  @马特·约翰逊:非常感谢重定向我一个很好的图书馆。 
我肯定想与该库工作,实现我的任务。前
使用图书馆我有一些问题。




  1. 点1



    什么是错的,你在这个例程 GetFastestNISTDate()通知; 常规是查询几个NIST的时间服务器,并获得utctime

      utcDateTime =新日期时间(
    Convert.ToInt32(日期部分[0])+ 2000,
    Convert.ToInt32(日期部分[1]),Convert.ToInt32(日期部分[2]),
    Convert.ToInt32(timeParts [0]),Convert.ToInt32(timeParts [1]),
    转换。 ToInt32(timeParts [2]));




这个程序 GetFastestNISTDate (); 返航utcDateTime ....不是UTC时间




  • 点2



  • 当我打电话 GetFastestNISTDate(); 常规我注意到有些时候这个例程返回 DateTime.MinValue 这是没有预期的结果。我能理解为什么发生,因为NIST的时间服务器忙或阻止或超时发生在那个时候。




  • 3点
    如果我可以用你当前的代码/库 NodaTime.NetworkClock 然后我想知道哪些NTP服务器将默认查询?



  • 如果我使用 NodaTime.NetworkClock 那么有没有机会,有一段时间我可能会得到错误的日期或空日期因 NTP服务器忙/块或超时发生的?



    编辑5



      VAR即时= NetworkClock.Instance.Now; 
    变种的timeZone = DateTimeZoneProviders.Tzdb [欧洲/伦敦];
    VAR zonedDateTime = instant.InZone(的timeZone);

    lbldate.Text = zonedDateTime.ToString(DD / MM / YYYY,CultureInfo.InvariantCulture);
    lbltime.Text = zonedDateTime.ToString(HH:MM:SS,CultureInfo.InvariantCulture);


    解决方案

    GetFastestNISTDate 函数使用白天协议 - 这基本上弃用,并不意味着人机交互,因为其结果是在任何特定的格式。即使从NIST的文档大力鼓励用户使用的 NTP 中,而不是白天。



    您可以找到一个简单的C#实现NTP客户端这里



    为方便起见,我'已经实现了这个客户端为 NodaTime.IClock 。该代码是在GitHub上这里。只需从的NuGet 安装



    <预类=郎PowerShell的prettyprint-覆盖> 安装封装NodaTime.NetworkClock

    然后你可以使用它,就像你会使用 SystemClock

      VAR即时= NetworkClock.Instance.Now; 
    变种的timeZone = DateTimeZoneProviders.Tzdb [欧洲/伦敦];
    VAR zonedDateTime = instant.InZone(的timeZone);


    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.

    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.

    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.

    looking for help with bit of sample code thanks

    EDIT

    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(); 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. i guess i am making mistake the code. can anyone see & help. thanks

    EDIT 2

    the samething i want to achieve by Nodatime library.

        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. thanks

    Edit 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 just tell me the above code is ok because u said

    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.

    EDIT 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. Point 1

      what was wrong you notice in this routine GetFastestNISTDate(); the routine was query few NIST time servers and get the 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(); was returning utcDateTime....was not a utc time ?

    1. Point 2

    when i was calling GetFastestNISTDate(); routine i notice some time this routine was returning DateTime.MinValue which was not expected result. i could understand why it was happening because NIST time servers was busy or blocked or timeout occured at that time.

    1. Point 3 if i use your current code/library NodaTime.NetworkClock then i like to know which NTP server it will query by default?

    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?

    EDIT 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);
    

    解决方案

    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. Even the docs from NIST strongly encourage users to use NTP instead of daytime.

    You can find a simple C# implementation of an NTP client here.

    To make things easier, I've implemented this client as a NodaTime.IClock. The code is on GitHub here. Simply install it from NuGet:

    Install-Package NodaTime.NetworkClock
    

    Then you can use it just like you would use the SystemClock:

    var instant = NetworkClock.Instance.Now;
    var timeZone = DateTimeZoneProviders.Tzdb["Europe/London"];
    var zonedDateTime = instant.InZone(timeZone);
    

    这篇关于如何转换UTC日期和放大器;使用不同的时区Nodatime时间为当地时间的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

    查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆