【问题标题】:How to save correct time in database?如何在数据库中保存正确的时间?
【发布时间】:2018-02-10 06:05:38
【问题描述】:

我有一个名为 appointment 的对象,它有两个属性:StartDate 和 EndDate。

当我发出POST 请求时,我使用ISOString 时间发送这些值。

this.appointment.StartDate.toISOString()

在服务器端,我收到了这些具有正确值的属性。此外,当我创建model 以便将appointment 保存到数据库时,这似乎是正确的。我用.ToUniversalTime()方法。

var newAppointment = new Appointment()
{
        StartDate =Convert.ToDateTime(model.StartDate).ToUniversalTime(),
        EndDate = Convert.ToDateTime(model.EndDate).ToUniversalTime(),
        SpecialityId = speciality.Id,
        LocationId = location.Id,
        PatientId = patient.Id,
        UserId = user.Id,
        Observations = model.Observations
};

但在数据库中我发现了另一个值。可以解释一下为什么会这样吗?

例如,我将2017.09.01 11:00 用于StartDate,在数据库中我找到了2017-09-01 08:00

服务器和数据库位于westeurope。

【问题讨论】:

  • 还有什么价值?您能否添加一个具体的示例,Angular 中的值是什么,您发送的 JSON 中的值是什么样的,以及实际存储在数据库中的值是什么?
  • @Alexandru-IonutMihai 我想我的客户端也有类似的问题,问题来自数据库服务器的日期时间集。由于我们的时间和设置为服务器的时间之间存在差距,我们总是保存 datetime + 2 小时。
  • @GünterZöchbauer,现在看看。
  • 对不起,但对我来说,从您的代码中仍然很不清楚该值在什么时候在您的应用程序的哪个部分看起来到底是什么样的。 Angular 的第一个值是来自 C# 吗? UTC 通常在末尾有一个 Z。
  • @GünterZöchbauer,在c# 我收到与angular 相同的值

标签: javascript c# angular typescript timezone


【解决方案1】:

问题在于您当前的时区。

在这种情况下,您的应用程序所做的是获取当前时区 (+3)。

现在它有了您的时区,但它会转换为 UTC 时间。那么会发生什么,您当前的时间将是 -3 小时。

如果您不适应夏令时和冬令时,则只需将日期时间增加 3 小时即可。否则,您必须获取时区的偏移量并将其添加到当前日期时间值。 如果您在不同的时区使用此应用程序,请注意。 例如,您生活在 +3 时区,而其他人生活在 +2 时区。

【讨论】:

  • 我怎样才能适应我的当地时间?当我从数据库中获取数据时它需要调整吗?
  • 您只需要在发布时进行调整。数据库只会给出没有时区的日期时间(取决于您的设置)。
  • 我用了片刻来做这件事。 let number = moment(event).utcOffset();let dateTimeTimezone = moment(event).utc().add(number, 'minutes');
【解决方案2】:

一些事情:

  • 不要在 Web 应用程序中调用 ToUniversalTime。它旨在从 服务器的本地时区 转换为 UTC。服务器的时区应该与您的应用程序无关。 Web 应用程序绝不能使用ToUniversalTime、ToLocalTime、DateTime.Now、TimeZoneInfo.Local、DateTimeKind.Local 或任何其他使用运行它的计算机的时区的方法。

  • 理想情况下,在服务器端,您的model.StartDate 和model.EndDate 将已经成为DateTime 对象,因为它们会以这种方式被反序列化。因此,您可能不需要致电Convert.ToDateTime。如果它们是字符串,那么我会相应地调整您的模型类。

  • 在客户端,假设 StartDate 和 EndDate 是 JavaScript Date 对象,并且它们是使用本地时间值(即浏览器的时区)创建的,当您调用 @ 987654337@,您获得的不仅仅是 ISO 8601 格式的字符串 - 还 将其从浏览器的时区转换为 UTC。

  • 在您的示例中,对于显示的日期和时间,UTC 时间比 UTC 时间早 3 小时。从您的个人资料中,我看到您位于罗马尼亚,该日期确实是 UTC+3,因为它目前正在观察东欧夏令时。夏季时间结束时 (on October 29, 2017 at 04:00),它将返回 UTC+2。因此,您不能简单地将三个小时添加到所有值。

  • 如果您想从客户端发送本地时间值,您应该以 ISO 8601 格式发送它们,不带任何Z 或偏移量,例如2017-09-01T11:00。有几种方法可以实现:

    • 最好的方法是不要将它们放在 Date 对象中。例如,如果您的输入使用<input type="datetime-local" /> 输入类型(as specified in HTML5),则.value 属性不是Date 对象,而是ISO 8601 格式的string。

    • 如果您无法避免Date 对象,则创建一个本地 ISO 字符串,如下所示:

      function dateToLocalISOString(date) {
          var offset = date.getTimezoneOffset();
          var shifted = new Date(date - offset * 60 * 1000);
          return shifted.toISOString().slice(0, -1);
      }
      

      或者,使用Moment.js:

      moment(yourDateObject).format("YYYY-MM-DD[T]HH:mm:ss.SSS")
      
  • 最后,您可能会阅读其他人关于将这些存储为 UTC 的建议。不要听。 “始终使用 UTC”的建议是短视的。许多场景需要本地时间。安排约会是当地时间的主要用例。但是,如果您需要对该约会采取,您将使用当前的 UTC 时间,并且您还需要一些有关约会时区的信息,以便您可以从 UTC 转换为约会的时区。例如,如果这类似于面对面的医生办公室预约,那么假设医生办公室的时区是安全的。但如果是在线会议的约会,那么您必须单独捕获用户的时区,并在适当的情况下将其应用到后端。

【讨论】:

    猜你喜欢
    • 2013-04-20
    • 2020-07-21
    • 2018-08-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-12-10
    • 1970-01-01
    相关资源
    最近更新 更多