【问题标题】:Why is the passed date from frontend not the same as in backend (Java) in ms为什么从前端传递的日期与在 ms 中的后端 (Java) 中传递的日期不同
【发布时间】:2019-11-13 06:13:16
【问题描述】:

我正在开发一个应用程序,前端使用 AngularJS,后端使用 Java(使用 Spring)。
我注意到前端profile-entity 的显示日期与数据库中显示的日期不同。
所以我调试了保存日期的那一刻,发现在前端(保存日期时 - $scope.selectedProfile.$save)日期具有以下值:

$scope.selectedProfile.projects[1].start -> Date: 2017-10-31T23:00:00.000Z
$scope.selectedProfile.projects[1].start.getTime() -> 1509490800000

接下来我在返回行到达后端的断点:

@RestController
@RequestMapping(value = "/profiles", produces = MediaType.APPLICATION_JSON_VALUE)
public class ProfileController {

  @RequestMapping(method = RequestMethod.POST, consumes = MediaType.APPLICATION_JSON_VALUE)
  public Profile update(@RequestBody Profile profile) {
      return this.repository.save(profile);
  }

}

并且日期具有以下值:

profile.projects.get(1).start -> (Date) “Tue Oct 31 23:00:00 CET 2017”
profile.projects.get(1).start.getTime() -> 1509487200000

这里不是已经出现问题了吗? - 因为“getTime()”函数不应该在前端和后端返回相同的数字,因为它们不依赖于时区?

问题是当我将值导出到 Word 文件中并显示它写“十月”的月份时,即使前端显示的日期是 11 月 1 日。

有人知道我能做什么吗?

这是传递的 JSON:

{
  "id": 64,
  "projects": [
    {
      "id": 135,
      "project": 339,
      "start": null,
      "end": null
    },
    {
      "id": 132,
      "project": 403,
      "start": "2017-10-31T23:00:00.000Z",
      "end": null
    }
  ]
}

数据通过这段代码传递:

$http.post('/profiles/profiles', profile)

我认为映射是由 Spring 自动完成的。

【问题讨论】:

  • 尝试格式化日期
  • 将日期从字体端发送到后端的代码在哪里?您发送的 JSON 包含什么内容?
  • @JBNizet 感谢提示,我添加了该信息
  • 所以问题出在后端。你如何解析JSON?看来您仍在使用过时、糟糕的 java.util.Date 类。别。使用 java.time.Instant。
  • @JBNizet thx 提示 - 一旦我取得更多进展,我会尝试继续更新这篇文章

标签: java angularjs date spring-mvc


【解决方案1】:

我认为您误解了日期的方式(在 JavaScript 和 Java 中) 取决于时区,我认为在 Java 端解析入站日期的方式可能有问题。

在客户端(JavaScript 端),您的(格式化的)日期是“2017-10-31T23:00:00.000Z” 在后端(Java 端),您的(格式化)日期是“Tue Oct 31 23:00:00 CET 2017”。

请注意,这两个日期表示相隔一小时(或 2,具体取决于 DST)的时间点。日期和时间部分是等效的,但 JavaScript 日期采用 UTC,而 Java 日期显示 CET 时区。由于 CET 是 UTC+1 或 UTC+2 取决于 DST,它们并不相同。

看起来 Java 方面的某些东西正在采用 UTC 格式的日期字符串,忽略时区,并将其按原样反序列化为具有本地 (CET) 时区的 Java Date。

在将日期插入数据库然后再次检索后查看后端的日期,这为错误所在的位置留下了很多可能性。你必须在 Spring Controller 中检查它,在它被反序列化之后,然后在通往数据库的每一步并再次退出,看看错误的转换在哪里。

【讨论】:

  • 我找到了一个解决方案:当我在我的 java 模型中的日期类型属性上方添加此注释时,序列化是正确的:@JsonFormat(shape=JsonFormat.Shape.STRING, pattern="yyyy-MM-dd'T'HH:mm:ss.SSS'Z'", timezone="UTC") 但我不想将此注释添加到每个变量.必须有一种方法可以全局设置(?)
  • @Cold_Class 如果你使用 Jackon,你可以在 ObjectMapper 上定义一个默认的日期格式化程序。从 Jackson v2.9 开始,您拥有处理 ISO 日期的 StdDateFormat。试试objectMapper.setDateFormat(new StdDateFormat().withColonInTimeZone(true));
  • @StanislasKlukowski thx,我想我明白了 - 我在编码中找到了一个现有的映射器,刚刚添加了 mapper.setTimeZone(TimeZone.getTimeZone("UTC")); - 它现在似乎工作了,一旦我测试了所有东西,我会写我在回答中做到了。
猜你喜欢
  • 1970-01-01
  • 2022-06-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-12-24
  • 1970-01-01
  • 2021-09-14
相关资源
最近更新 更多