.NET DateTime - 呼叫者时区的服务器端解决方案
.NET DateTime - Server-side solution for callers Time Zone
我正在构建一个允许用户指定 his/her 工作时间的系统。这在数据库中存储为:
- 星期几:星期一
- 开始时间:08:00
- 结束时间:17:00
此信息是相对于用户 A 的,因此基于他的时区。用户在 his/her 配置文件中选择的,例如(UTC+00:00) 都柏林、爱丁堡、里斯本、伦敦
我想达到什么目标?
- 用户 B 当前使用日期调用 .NET Web API,例如2019 年 1 月 1 日。
- 我需要 API 到 return 用户 A 的工作时间,但在用户 B 的时区。
- 然后用户 B 可以通过再次调用 API 向用户 A 预订该时间。在这种情况下,预订以 UTC 日期格式存储。
我需要什么?
有人可以为此提供合适的解决方案吗,因为用户 A 和用户 B 可以有不同的时区?
您可以看看 NodaTime,它可能是 .NET 的最佳时区相关库
使用内置的 .Net 功能也可以实现同样的效果,但它存在一些棘手的罕见问题,因此使用 NodaTime 更可靠。
在问题下的评论中,您说:
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 的时区偏移量执行调整。
问题是许多时区会根据您所谈论的日期和时间经历不同的偏移量。例如,如果在 client-side JS 中您执行类似 new Date().getTimezoneOffset()
的操作,您将获得用户的 current 偏移量。它不一定是应用于相关日期的相同偏移量。 the timezone tag wiki.
标题 "Time Zone != Offset" 下的更多相关信息
此外,您继续说返回 API 的请求是在用户 A 的时区完成的(这很好),但是您随后将时间转换并存储为 UTC。那里要小心-您需要保留预定的约会时间。知道特定事件的 UTC 时间可能是什么很好,但实际上这也可以改变。
举个例子,考虑一下几年前的 the latest time zone changes that occurred in Morocco. They were planning to end daylight saving time on October 28th 2018, switching the clocks back from UTC+1 to UTC+0. However, on October 26th 2018, with just two days warning, the government announced that they would stay on UTC+1 permanently and abolish daylight saving time. These sorts of short-notice changes are highly problematic, and has happened around the world many times before. I wrote a blog post about them,这在今天仍然非常适用。
因此,如果用户 A 在摩洛哥,并且您在 UTC 更改后的某个时间存储了约会,那么由于更改没有发生,他们的约会现在会在他们的本地日历上显示一个小时。
在此类事件中,如果您保留了事件的预期当地时间,那么您还可以根据当前时区数据重新计算 UTC 时间你已经安装了。临时通知更改非常困难,但如果有几个月的通知,那么您将有时间应用更新并以编程方式更正事件的时间。如果你只存储UTC时间,那么你就没有那个能力了。
另一种思考方式是,虽然 UTC 始终保持一致(除了在某些情况下闰秒附近),但人类不会这样思考。如果我说我想在某个地方的上午 10 点与你会面,那么会议将与该地点的当地时间对齐——无论该地点的时间与 UTC 之间发生什么变化。
相反,根据 UTC 安排会议是盲目相信不会发生超出当前预测的变化。由于我们无法预见未来,因此我们真的不应该做出这样的假设。
(同样,如果您需要代码方面的帮助,请显示您在问题中尝试过的代码。通常在 .NET 中,人们使用 TimeZoneInfo
class .Here's an overview on how to use it.)
我正在构建一个允许用户指定 his/her 工作时间的系统。这在数据库中存储为:
- 星期几:星期一
- 开始时间:08:00
- 结束时间:17:00
此信息是相对于用户 A 的,因此基于他的时区。用户在 his/her 配置文件中选择的,例如(UTC+00:00) 都柏林、爱丁堡、里斯本、伦敦
我想达到什么目标?
- 用户 B 当前使用日期调用 .NET Web API,例如2019 年 1 月 1 日。
- 我需要 API 到 return 用户 A 的工作时间,但在用户 B 的时区。
- 然后用户 B 可以通过再次调用 API 向用户 A 预订该时间。在这种情况下,预订以 UTC 日期格式存储。
我需要什么?
有人可以为此提供合适的解决方案吗,因为用户 A 和用户 B 可以有不同的时区?
您可以看看 NodaTime,它可能是 .NET 的最佳时区相关库 使用内置的 .Net 功能也可以实现同样的效果,但它存在一些棘手的罕见问题,因此使用 NodaTime 更可靠。
在问题下的评论中,您说:
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 的时区偏移量执行调整。
问题是许多时区会根据您所谈论的日期和时间经历不同的偏移量。例如,如果在 client-side JS 中您执行类似 new Date().getTimezoneOffset()
的操作,您将获得用户的 current 偏移量。它不一定是应用于相关日期的相同偏移量。 the timezone tag wiki.
此外,您继续说返回 API 的请求是在用户 A 的时区完成的(这很好),但是您随后将时间转换并存储为 UTC。那里要小心-您需要保留预定的约会时间。知道特定事件的 UTC 时间可能是什么很好,但实际上这也可以改变。
举个例子,考虑一下几年前的 the latest time zone changes that occurred in Morocco. They were planning to end daylight saving time on October 28th 2018, switching the clocks back from UTC+1 to UTC+0. However, on October 26th 2018, with just two days warning, the government announced that they would stay on UTC+1 permanently and abolish daylight saving time. These sorts of short-notice changes are highly problematic, and has happened around the world many times before. I wrote a blog post about them,这在今天仍然非常适用。
因此,如果用户 A 在摩洛哥,并且您在 UTC 更改后的某个时间存储了约会,那么由于更改没有发生,他们的约会现在会在他们的本地日历上显示一个小时。
在此类事件中,如果您保留了事件的预期当地时间,那么您还可以根据当前时区数据重新计算 UTC 时间你已经安装了。临时通知更改非常困难,但如果有几个月的通知,那么您将有时间应用更新并以编程方式更正事件的时间。如果你只存储UTC时间,那么你就没有那个能力了。
另一种思考方式是,虽然 UTC 始终保持一致(除了在某些情况下闰秒附近),但人类不会这样思考。如果我说我想在某个地方的上午 10 点与你会面,那么会议将与该地点的当地时间对齐——无论该地点的时间与 UTC 之间发生什么变化。
相反,根据 UTC 安排会议是盲目相信不会发生超出当前预测的变化。由于我们无法预见未来,因此我们真的不应该做出这样的假设。
(同样,如果您需要代码方面的帮助,请显示您在问题中尝试过的代码。通常在 .NET 中,人们使用 TimeZoneInfo
class .Here's an overview on how to use it.)