如何使用 react-day-picker Post 正确的工作日

How can I Post the correct week days using react-day-picker

在我的 React 应用程序中,我尝试使用库 react-day-picker https://react-day-picker.js.org/examples/selected-week 将周值发送到服务器,但它以一天的间隔将值发送到服务器。

例如,当我在客户端中选择 2021-03-07 到 2021-03-13 之间的一周时,我可以在日志中看到该周已正确发送,但在服务器中,我得到的值具有 1 天的偏移量,如下所示:

  selectedDays: [
    '2021-03-06T22:00:00.000Z',
    '2021-03-07T22:00:00.000Z',
    '2021-03-08T22:00:00.000Z',
    '2021-03-09T22:00:00.000Z',
    '2021-03-10T22:00:00.000Z',
    '2021-03-11T22:00:00.000Z',
    '2021-03-12T22:00:00.000Z'
  ]

这是我的客户端代码:

console.log(data);
// I get here the correct week values

axios({
  method: "post",
  url: "http://localhost:3001/",
  data: data,
}).then(
  (res) => {
    console.log(res);
  },
  (error) => {
    console.log(error);
  }
);

我的服务器代码:

exports.createNewGoals = async (request, response) => {
   
 // I get here the values with one day interval.
 console.log(request.body.selectedDays);

}

我猜这可能与本地化设置有关,但我没有定义任何自定义本地化设置。 我是 运行 在 Chrome 浏览器中 Windows 机器 (he-il) 上的本地项目。

日期在哪里更改,如何正确配置?

任何帮助将不胜感激

这确实是时区不匹配。客户端正在向服务器发送本地时间 parsing/saving 作为 UTC,并且由于您的时区早于格林威治标准时间,12:00AM 将始终落后一天。服务器可能配置为 GMT,这是一个很好的做法,因为 Web 服务器将有多个时区的用户,因此它需要一种通用的方法来准确地存储时间。如果你不需要转换,有几种方法取决于你的控制和要求:

  1. 在客户端转换为 UTC

sandbox 的示例 getWeekDays 中,客户端选择本地时间的日期并使用 moment 库然后转换回日期。默认情况下,它以用户时间准确捕获用户的选择,其中包括他们的时区偏移:

Sun Mar 14 2021 00:00:00 GMT-0500 (Eastern Standard Time), 
Mon Mar 15 2021 00:00:00 GMT-0400 (Eastern Daylight Time), 
Tue Mar 16 2021 00:00:00 GMT-0400 (Eastern Daylight Time), 
Wed Mar 17 2021 00:00:00 GMT-0400 (Eastern Daylight Time), 
Thu Mar 18 2021 00:00:00 GMT-0400 (Eastern Daylight Time), 
Fri Mar 19 2021 00:00:00 GMT-0400 (Eastern Daylight Time), 
Sat Mar 20 2021 00:00:00 GMT-0400 (Eastern Daylight Time)

如果要捕获用户点击的日历日期,可以在使用.utc(true)转换为JavaScript日期之前转换为UTC而不更改时间。这是将日期的值设置为“此位置的时间,而 UTC 中的时间为 12:00AM”。客户端将在本地发送它,但是当它在服务器上转换时,它将在预期日期转换回 12:00UTC:

function getWeekDays(weekStart) {
  const days = [moment(weekStart).utc(true).toDate()];
  for (let i = 1; i < 7; i += 1) {
    days.push(
      moment(weekStart)
        .add(i, 'days')
        .utc(true).toDate()
    );
  }
  console.log (days);
  return days;
}

结果如下。 (* 请注意,当我们的偏移量发生变化时,我特意选择了上周——这对服务器来说应该无关紧要):

Sat Mar 13 2021 19:00:00 GMT-0500 (Eastern Standard Time)
Sun Mar 14 2021 20:00:00 GMT-0400 (Eastern Daylight Time)
Mon Mar 15 2021 20:00:00 GMT-0400 (Eastern Daylight Time)
Tue Mar 16 2021 20:00:00 GMT-0400 (Eastern Daylight Time)
Wed Mar 17 2021 20:00:00 GMT-0400 (Eastern Daylight Time)
Thu Mar 18 2021 20:00:00 GMT-0400 (Eastern Daylight Time)
Fri Mar 19 2021 20:00:00 GMT-0400 (Eastern Daylight Time)
  1. 只需发送日期

如果不需要时间转换,只发送一个没有时间的日期通常要简单得多:

 function getWeekDays(weekStart) {
      const days = [moment(weekStart).format('YYYY-MM-DD')];
      for (let i = 1; i < 7; i += 1) {
        days.push(
          moment(weekStart)
            .add(i, 'days')
            .format('YYYY-MM-DD')
        );
      }
      console.log (days);
      return days;
    }
  1. 在服务器上转换为本地

同样,在服务器上,您可以将客户端时间转换为本地时间。这是由请求解析器上的类型处理程序决定的,但它可以转换回本地以获取用户的本地日期:

exports.createNewGoals = async (request, response) => {
   
 // I get here the values with one day interval.
 request.body.selectedDays.forEach(dt=> console.log(moment(dt).local()));

}

或者更简单地避免任何时间混淆并将其键入为字符串然后忽略本地时间部分:

exports.createNewGoals = async (request, response) => {
   
 // I get here the values with one day interval.
 request.body.selectedDays.forEach(dt=> console.log(dt.substring(0, 10)));

}