关于c#:. NET DateTime – 呼叫者时区的服务器端解决方案

.NET DateTime - Server-side solution for callers Time Zone

我正在构建一个允许用户指定他/她的工作时间的系统。这在数据库中存储为:

  • 星期几:星期一
  • 开始时间:08:00
  • 结束时间:17:00

此信息是相对于用户A的,因此基于他的时区。用户在其配置文件中选择的内容,例如(UTC+00:00)都柏林、爱丁堡、里斯本、伦敦

我想达到什么目的?

  • 用户B当前调用日期为2019年1月1日的.NET Web API。
  • 我需要API返回用户A的工作时间,但在用户B的时区。
  • 然后,用户B可以通过对API进行第二次调用,与用户A一起预订该时间。在这种情况下,预订以UTC日期格式存储。
  • 我需要什么?

    如果用户A和用户B可以有不同的时区,是否可以有人为此提供合适的解决方案?


    在你对这个问题的评论中,你说:

    the current solution I have is that I store User A’s working hours as start and end times for each day of the week. I also store the users TimeZone. Currently the API will return the Working Times as a JSON Payload with the workers TimeZone. I then display this data for User B and perform the adjustment with User B TimeZone offset using client side JS. When User B decides to book, the request back to the API is done using User A TimeZone setting and then that date time value is converted and stored in UTC format.

    这基本上是很好的,除非您说使用用户B的时区偏移执行调整。

    问题是,许多时区根据您所说的日期和时间进行不同的偏移。例如,如果在客户端JS中执行类似于new Date().getTimezoneOffset()的操作,则会得到用户当前的偏移量。这不一定是相同的抵消,应适用于有关日期。更多关于这个标题下"时区!=offset"在时区标记wiki中。

    另外,您继续说,返回API的请求是在用户A的时区内完成的(这很好),但是您随后将时间转换并存储为UTC。小心点-你需要保留预定的预约时间。可以知道特定事件的UTC时间是什么,但实际上这也可能改变。

    例如,考虑摩洛哥最近发生的时区变化。他们计划在2018年10月28日结束夏令时,将时钟从UTC+1切换回UTC+0。然而,在2018年10月26日,政府仅提前两天发出警告,宣布他们将永久使用UTC+1,并取消夏令时。这些短期的变化是非常有问题的,而且在世界各地发生过很多次。几年前我写了一篇关于它们的博客文章,现在仍然非常适用。

    因此,如果用户A在摩洛哥,并且您在UTC中更改后的某个时间内存储了一个约会,那么由于没有发生更改,他们的约会现在在本地日历上显示为一个小时的移动。

    在这种情况下,如果您保留了事件的预期本地时间,那么您也可以有一个流程根据您安装的当前时区数据重新计算UTC时间。短期通知更改是非常困难的,但是如果有人说有几个月的通知,那么您就有时间应用更新并以编程方式更正事件的时间。如果你只存储了UTC时间,那么你就没有这个能力。

    另一种思考方法是,虽然UTC总是持续不断地前进(在某些情况下,在闰秒左右),但人类并不这样想。如果我说我想在某个地方上午10点与您会面,那么会议将与该地方的当地时间保持一致-无论该地方的时间与UTC之间发生了什么变化。

    相反,基于UTC安排会议是盲目的,认为当前预测之外不会发生任何变化。既然我们无法洞察未来,我们真的不应该做出这样的假设。

    (同样,如果您希望获得代码方面的帮助,请显示您在问题中尝试过的代码。在.NET中,通常使用TimeZoneInfo类。以下是如何使用它的概述。)


    您可以看看nodatime,它可能是.NET中与时区相关的最佳库。使用内置的.NET功能也可以达到同样的效果,但它存在一些棘手的罕见问题,因此使用nodatime更可靠。