首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >酒店预订功能-处理UTC日期和时区

酒店预订功能-处理UTC日期和时区
EN

Code Review用户
提问于 2019-04-26 21:56:12
回答 1查看 585关注 0票数 0

这里的人经常要求分享尽可能多的代码。我的应用程序只是一个沙箱,一个典型的新创建的AspNetCore +角模板,没有太多代码。所以,请不要责怪我-我提供了所有与日期和时区相关的代码。

我正在.NET中玩约会,并开始详细学习Moment.js。

我认为学习它的最好方法是编写类似基本的酒店预订应用程序--仅仅是因为它带来了足够的复杂性,而且您可以处理很多与时区相关的细微差别。

网络上的教程只涵盖大多数常见的情况,比如日期操作。很少有关于处理时区偏移的文章。

我们都知道,当一个日期被后端获取时,它必须作为UTC日期存储在DB中--关于它有一篇伟大的文章,我完全同意这个家伙的观点。

我们开始吧!

INITIAL信息:

酒店的Location:西班牙(GMT+1 / GMT+2 -取决于DST)

登记日期和时间:2019年4月24日14:30:00西班牙当地时间

HOTEL预订WEB服务:

(比如说,我们还没有开始为酒店员工和酒店客人创建单独的门户--为了简单起见,我们只有两个单独的页面,因为我们的应用程序更像是一个沙箱-我在Visual中选择了ASP.NET核心和角模板)

  • 有一个页面,我们作为客人选择到达的日期和时间-该页面包含DateTimePicker UI控件
  • 这里有一个单独的页面,酒店工作人员可以在那里看到入住。

听起来很可行吗?我有个坏消息。让我们跳进去..。

我们正在处理的是JavaScript前端--可能是AngularJS /角2+ / Vue / React,甚至是jQuery。与AJAX调用没有太大的区别。

PART 1-预订页面:

来自不同时区的多个用户正在访问此页面。他们想预订一家酒店--他们使用DateTimePicker来选择日期和时间。

Nuance 1-您的时区:

如果您的时区是GMT+3,并且在JavaScript中新建了一个日期变量,会发生什么情况?

答案是:

您的日期现在有一个偏移,例如4月24日,2019,00:00:00 GMT+0300 (莫斯科标准时间)。

如果你把这个日期推迟到后端,那就需要3个小时--4月23日,2019,21:00--因此现在不是24日,而是4月23日。

你觉得这是唯一的细微差别吗?潜得更深。

Nuance 2-酒店时区:

酒店位于不同的时区。在大多数情况下,它们不一定与您的时区相匹配。

如果你在西班牙订旅馆呢?您的酒店时区是GTM+1 / GMT+2,您的时区是GMT+3。您正在选择日期和时间。新挑选的日期和时间属于哪个时区?

答案是:

当然,新挑选的日期属于酒店的时区。

When您选择的酒店页面必须考虑酒店的时区,并在将日期转换为UTC时使用它。

下一步是什么?那得看情况了。我使用的DatePicker来自ng引导程序,它生成以下对象:

代码语言:javascript
运行
复制
{
  "year": 2019,
  "month": 4,
  "day": 24
}

为了保持更简单,我排除了时间部分,所以我们只选择日期--我在硬编码时间,所以从现在开始是14:30 moment([e.year, e.month - 1, e.day, 14, 30, 0])

We需要将一个UTC日期传递给后端-我们应该如何处理它?

我的解决办法:

  1. 使用Moment.js生成日期
  2. 格式化它以排除时区偏移量。
  3. 将它从GMT+1 / GMT+2 (西班牙酒店的时区)转换为UTC
  4. 再次格式化以排除时区偏移量。

代码:

代码语言:javascript
运行
复制
let format = 'YYYY-MM-DDTHH:mm:ss';
let zone = "Europe/Madrid";

let initialDateString = moment([e.year, e.month - 1, e.day, 14, 30, 0]).format(format); // "2019-04-24T14:30:00"

let resultDateString = moment.tz(initialDateString , format, zone).utc().format(format); // results in "2019-04-24T12:30:00" - Spain is 2 hours ahead of UTC right now in April

因此,剩下的部分是AJAX请求和控制器操作调用,其中创建预订记录。

您可能还在想,为什么存储在DB中的日期的时间部分是12:30:00而不是14:30:00。在我们的规范中(请参阅上面的初始信息部分),它会读到

登记日期和时间:2019年4月24日14:30 GMT+1 / GMT+2。

答案是:

放松,这是一个UTC DateTime。当UTC时钟点击12:30:00时,西班牙时间是14:30:00

您的下一个问题可能是:如果数据库中存储的时间是12:30,那么酒店工作人员如何知道您将到达14:30?答案是在下一部分。

PART 2-酒店员工页面:

还记得在第一部分中,我们使用酒店的时区进行日期转换吗?(由酒店时区转换为协调世界时)

现在,我们必须考虑用户的本地时区--酒店工作人员打开浏览器,导航到web服务,并在页面上呈现对其特定酒店的预订。在每次预订下,他们都可以看到入住日期和时间。

我们应该如何处理UTC日期,以便将其显示为GMT+1 / GMT+2?

答案是:

我们必须将其转换为GMT+1 / GMT+2,这是显而易见的。

  1. 后端返回24 2019年4月12:30:00
  2. 前端将它从协调世界时转换为GMT+1 / GMT+2。

下面是处理转换的位:

代码语言:javascript
运行
复制
let fmt = 'YYYY-MM-DDTHH:mm:ss';
let zone  = "Europe/Madrid";

let utc = moment.tz("2019-04-24T12:30:00",'UTC');
let spanishTime = moment.tz(utc.format(), zone).format(fmt);

代码:

因此,我已经披露了所有涉及到的JavaScript代码。

您可能想知道后端代码是什么样子的,对吗?

就像,一定是些狡猾而聪明的东西.或者,它是否涉及任何与时区相关的操作或任何复杂的事情。

惊喜吧!

代码语言:javascript
运行
复制
[HttpGet("[action]")]
public List CheckBookings()
{
    using (var db = new AppDbContext())
    {
        var booking = db.Bookings.ToList();
        return booking;
    }
}

[HttpPost("[action]")]
public bool BookHotel([FromBody] CheckIn input)
{
    using (var db = new AppDbContext())
    {
        var booking = new Booking() { Name = "NAME", Date = input.Value };
        db.Bookings.Add(booking);
        db.SaveChanges();
    }

    return true;
}

除了日期我们什么都不感兴趣所以我用硬编码的名字..。

我听说过野田时代图书馆。有几个人向我推荐这个预订功能。看起来确实很棒。但说实话,我看不出它在哪里适用。

<#>The后端只处理UTC日期。也就是说,后端从前端接收UTC日期,并将UTC日期发送给它。

<#>Looks和我们所需要的一样,就是Moment.js --所以我看不出其他库在哪里有帮助。

EN

回答 1

Code Review用户

回答已采纳

发布于 2019-04-27 22:34:50

删除时区

作为一项学习练习(处理时区),我认为您选择了错误的应用程序。

日期时间作为字符串

我建议您使用没有时区信息的日期时间字符串,而不是UTC Unix滴答号。标准格式ISO 8601使用moment.js客户端(各地都符合浏览器ISO 8601 )来解析日期选择器,而格式没有时区(偏移为零"Z"),以便传输到后端。

后端(.net)支持ISO8601.解析要存储的预订日期时间字符串,然后使用往返格式说明符例如bookingDate.ToString("o");发送为日期时间字符串。

为什么

在客户端上处理多个时区最多是有问题的。您将需要一个强大的时区库。moment.js不能胜任这项工作,它的继任者Luxon将提供更好的时区管理,但这会带来巨大的数据开销。

您所需要的只是一个日期选择器,以便客户进行预订,因为我不认为当本地时间字符串(酒店位置)完成这项工作时,复杂的时区处理是值得的。

票数 1
EN
页面原文内容由Code Review提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://codereview.stackexchange.com/questions/219216

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档