【问题标题】:Seconds from minutes从分钟到秒
【发布时间】:2015-12-16 10:24:12
【问题描述】:

我需要以秒为单位计算时间,但我能收到的唯一信息是分钟。

所以我可以每 5 秒向服务器发送一个请求,然后我会得到回复,基本上是说“嘿,你还有 10 分钟”,5 秒后我可以向服务器发送另一个请求,它要么说“嘿,你还有 10 分钟”,或者它会说“嘿,你现在还剩 9 分钟。”

我想我可以启动一个计时器,一旦它告诉我还剩 9 分钟。但这不会精确到秒,因为我每 5 秒刷新一次,有时服务器向我发送信息的时间可能比我上次询问时的时间长。

所以我的问题基本上是有什么方法可以根据上述标准准确计算出我还剩下多少秒?

编辑:可以调整我发送请求的频率。

【问题讨论】:

  • 不,除非您只是更频繁地发送请求。
  • 您的请求是否必须每 5 秒发送一次? 5 变成 60 太整齐了,随着时间的推移没有任何用处。
  • 对不起,我刚才做了编辑,才意识到我可以调整请求时间。
  • 您唯一能做的就是根据之前的时间信息对秒数进行最佳猜测。
  • 您可以在 9 分钟(±5 秒)时启动计时器,当您认为它达到每分钟标记时,询问。你将能够调整你的平分你的不确定性。但我不确定您的意思是服务器发送信息需要多长时间。服务器在发送信息后是否总是在相同的时间内收到信息,而您从服务器获得响应所需的时间是可变的?

标签: c# math


【解决方案1】:

如果您观察时钟从 11:43 到 11:44,您不知道大致的秒数是多少吗?如果一秒到 44 就启动秒表,现在您可以计算秒表的秒数。

如果你可以每x秒查询一次,你就可以知道还有多少秒的误差大约为x秒。您需要本地高分辨率/高精度时间源,例如 Windows 中的高性能计数器,可通过 Stopwatch 类或 pinvokes GetPerformanceCounterGetPerformanceFrequency 获得。

所以你有以下部分:

  • 具有高分辨率和准确性的本地时钟。通过GetPerformanceCounter 的HPET 符合条件,您可以使用Stopwatch 类访问它而无需编写任何pinvokes(但我编写了自己的包装器而不是使用Stopwatch)。
  • 您正在尝试提高其准确性的远程时钟。
  • 能够查询远程时钟。

一般策略如下:

  • 查询您当地的高精度计数器。将此另存为“L1”。
  • 查询远程时钟。将此另存为“R1”。
  • 查询远程时钟。将此另存为“R2”。
  • 查询您当地的高精度计数器。将此另存为“L2”。

您需要循环执行上述操作(当您这样做时,您可以进一步优化它)。

如果您的远程时钟只告诉您分钟,那么几乎每次您查询它时,R1 和 R2 的值都完全相同。

但是,如果您碰巧在它跳到下一分钟时抓住了它,那么 R1 和 R2 应该正好相差一分钟。如果发生这种情况,那么本地计数器 L1 和 L2 会准确地告诉您在整个循环中经过了多少时间。

如果 L2 - L1 告诉您只过去了 100 毫秒,那么您知道时间“R2 和零秒”发生在这 100 毫秒的某个地方。

所以当你执行上述循环时:

  • R1 和 R2 告诉您远程时间是多少,并告诉您是否看到它跳到下一分钟 - “零秒”时间。
  • L1 和 L2 告诉您对应的本地时间与那个“零秒”时间是多少,它们会告诉您有多少错误。

一旦您有一组时间戳可供使用,您就可以仅根据本地高精度时钟计算远程时间。

本地时间(R2 - R1) / 2(调用该值 LocalMark)大致等于“R2 和零秒”(调用该值 RemoteMark)。

从那里,从本地时间计算的远程时间计算如下:

RemoteTime = (LocalTime - LocalMark) + RemoteMark

LocalTime - LocalMark 告诉您自 RemoteMark 被占用以来已经过去了多少时间,因此如果将这两个部分加在一起,您应该有远程时间。

...

以上是我从几年前发现的一篇 MSDN 文章中学到的知识。可惜微软已经把那篇文章撤了,只能通过回路机找到:

Implement a Continuously Updating, High-Resolution Time Provider for Windows.

您还可以从 MSDN archives 恢复该文章 - 它是在 2004 年 3 月的 MSDN 杂志上,可作为 CHM - March 2004 CHM with the article

【讨论】:

    【解决方案2】:

    您可以做的是放松偏移误差: 每次你似乎提前或迟到时,让 loc_error 成为估计值(如果你没有更好的可能只是 +1/-1)。 然后让 time_offset 为 0.99*time_offset + 0.1*loc_error,这取决于本地错误信息的“噪音”程度以及您希望以多快的速度收敛到正确的值。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-06-08
      • 2011-04-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-03-23
      • 1970-01-01
      相关资源
      最近更新 更多