了解 DateTime.Now 和 ISO8601 'Z' 名称

Understanding DateTime.Now and ISO8601 'Z' designation

我正在尝试处理 DateTime.Now 和我正在处理的 API 的 ISO-8601 时区指定之间的交互。端点包含时间戳作为询问我们的数据历史记录的标准。 EndPoint returns 请求的数据点最近的前 1/2 小时平均值,并包含以下代码:

If criteria.EndTime = "" Then
     timeStamp = DateTime.Now
Else
     timeStamp = CType(criteria.EndTime, DateTime)
End If

post 的正文接受以下 json:

 {
      "Interval": "30m",
      "StartTime": "",
      "EndTime": "2022-04-21T00:45:00Z",
      "TagList": "PointName",
      "Delim":",",
      "PointSource": "P",
      "ServerName": "PIServer"
 }

其中 EndTime 是端点拾取的参数。我们目前处于英国夏令时,即 DST 是 UTC +01:00。根据上述标准,我返回的数据的时间戳如下:

[
  {
    "PointName": "PointName",
    "TimeStamp": "21/04/2022 01:30:00",
    "Value": "-2.3607"
  },
  {
    "PointName": "PointName",
    "TimeStamp": "21/04/2022 01:30:00",
    "Value": "-2.6333"
  }
]

如您所见,返回的数据是 01:30 而不是预期的 00:30。如果我将 'Z' 指定排除在条件之外,那么我会返回正确的内容。请有人解释一下这里发生了什么。

让我们假设客户端发送基于 UTC 的时间(你的是)并且服务器以 UTC 时间响应(它 而不是 )。如前所述,...T00:30:00Z(00:30:00 UTC)是根据您所说的端点所做的 ...T00:45:00Z 输入的正确答案。

现在假设服务器以 BST 响应(似乎是)相同的基于 UTC 的客户端请求。那么...T01:30:00(没有指定时区,假定为BST)是你输入的正确答案,因为00:30:00UTC等同于01:30:00BST,这是给定服务器规则的正确结果.

我认为您错过了这样一个事实,即服务器似乎总是在没有指定时区的情况下返回 BST(可能是服务器本地的)(即您可以争辩说它应该返回 T01:30:00+1:00

似乎 如果您发送 UTC(或任何其他时间带有 时区信息),您会收到 BST 响应,但没有时区指定,如果您发送的时间没有时区信息,服务器会假定您发送的是 BST,并且 still returns BST。

因此,当您从请求中删除 Z 时,您会得到您认为错误的答案,但这并不是因为 T00:45:00(又名 00:45:00 假定 BST)服务器将以 T00:30:00 响应(又名 00:30:00 假设 BST)。

我怀疑如果你发送 T00:45:00+1:00 你会返回 T00:00:00+1:00,但如果你不发送(即拒绝 zime 区域信息),则可能是服务器错误。您可以通过发送 T00:45:00+2:00 并查看是否返回 T00:00:00+2:00 来测试它。