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

Sha*_*ayD 3 date reactjs 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'
  ]
Run Code Online (Sandbox Code Playgroud)

这是我的客户端代码:

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);
  }
);
Run Code Online (Sandbox Code Playgroud)

我的服务器代码:

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

}
Run Code Online (Sandbox Code Playgroud)

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

日期在哪里更改以及如何正确配置它?

任何帮助将不胜感激

Mat*_* E. 5

这确实是时区不匹配。客户端将本地时间发送到解析/保存为 UTC 的服务器,并且由于您的时区在 GMT 之前,12:00AM 将始终落后一天。服务器可能配置为 GMT,这是一种很好的做法,因为 Web 服务器将拥有多个时区的用户,因此它需要一种通用的方式来准确地存储时间。如果您不需要转换,根据您的控制和要求,有几种方法:

  1. 在客户端转换为 UTC

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

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)
Run Code Online (Sandbox Code Playgroud)

如果您想捕获用户点击的日历日期,您可以在转换为 JavaScript 日期之前使用.utc(true). 这是将 Date 的值设置为“该位置的时间,当它是 UTC12: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;
}
Run Code Online (Sandbox Code Playgroud)

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

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)
Run Code Online (Sandbox Code Playgroud)
  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;
    }
Run Code Online (Sandbox Code Playgroud)
  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()));

}
Run Code Online (Sandbox Code Playgroud)

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

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)));

}
Run Code Online (Sandbox Code Playgroud)