Дата в основном на один день вперед и непоследовательна.

Вопрос или проблема

Итак, в заключение, я хочу, чтобы мои даты работали в униформе. Поскольку мы имеем дело только с датами, а не с временем, как я могу этого достичь? Я уже пробовал много способов. В клиентской части я использую календарь React для пользовательского интерфейса даты и dayjs для форматирования даты. В серверной части я также использую dayjs для форматирования. Я создал веб-приложение, в котором пользователи могут создавать поездки. Эти поездки сильно зависят от дат для таких операций, как даты начала и конца поездки, сроки оплаты, даты окончания бронирования и т. д. Позвольте мне использовать даты начала и окончания поездки в качестве примера. Все, что я хочу, это чтобы, когда пользователь A создает поездку и устанавливает дату начала и окончания с 1 сентября по 10 сентября и публикует поездку, независимо от того, где находится человек, который хочет забронировать поездку, он или она должны видеть те же даты, которые установил владелец поездки для начала и окончания. То, что у меня сейчас, вызывает разочарование. Очень хороший пример: я настроил поездку с следующими датами: дата начала: 1 сентября 2025 года, дата окончания: 10 сентября 2025 года.

На странице бронирования я вижу 31 августа 2025 года.

Я читал, что мне следует рассматривать все как UTC и сохранять мои даты как UTC в базе данных. Я это сделал или, скажем так, я думаю, что сделал это. Вот коды, которые у меня есть. В клиентской части, которая построена с использованием Nextjs, я использую календарь React. Итак, я создал компонент для обработки этого.

 import Calendar from "react-calendar";
 import "react-calendar/dist/Calendar.css";

export function CustomDatePicker(dates, dateStateFunc){

//это тег p, который показывает дату, когда пользователь выбирает даты из календаря.
<div>
  <p>
    {dates === null || dates === undefined || !dates ? "Выберите дату"
     : dayjs(dates).format("YYYY-MM-DD")}
  </p>
</div>
}



<Calendar
  value={dates === undefined || dates === null || !dates ? dayjs(new Date()).toDate()
   : dayjs(dates).utc()?.format()}
    onChange={(e) =>dateStateFunc(e)}
  />

В одном из компонентов, где я использовал компонент даты, я обработал это так: // компонент создания поездки

import { CustomDatePicker } from "../customDate/CustomDate.component";

//Я пытался создать дату utc из дат, которые пришли из календаря React

const createNewDate = (date: Date | string)=>{
 let fullDate: Date | string;
  const m = dayjs(date).utc().format();

  fullDate = m;

  return fullDate;
}

 const handleDepositeDate = (datePara: Date | string, eventType) => {
    const fullDate = createNewDate(datePara as Date);
    if (eventType === "start_date") {
      setTripData({ ...tripsData, startDate: fullDate });
    } else if (eventType === "end_date") {
      setTripData({ ...tripsData, endDate: fullDate });
    }
  };

export function CreateTrip(){
 <CustomDatePicker
   dates={tripsData?.startDate as string}
   dateStateFunc={handleDepositeDate}
  />
}

С приведенными выше кодами, когда я console.log(tripData.startDate, tripData.endDate), я вижу UTC дату так: 2024-08-31T23:00:00Z, 2024-09-09T23:00:00Z.

Это означает, что это на один день меньше. Это то, что отправляется на сервер, который создает ту же дату, которая на один день меньше. В моем бэкенде я просто восстановил дату, поскольку я хочу доверять только бэкенду. Я не знаю, правильно ли это или нет. В приложении большинство дат создаются пользователем. Поэтому в бэкенде я просто беру то, что они создали, и воссоздаю это перед сохранением в базу данных, чтобы убедиться, что правильный формат даты сохранен в базе данных. Мой бэкенд написан на node.js.

Мне сказали всегда использовать полночь UTC.

export const convertDate = (date: Date | string) => {
  const converted = dayjs(date).utc().utcOffset(0).startOf("day").format(); 
  return converted;
};

Приведенный выше код также генерирует эту дату, используя клиентскую часть, 1 сентября 2025 года и 10 сентября 2025 года: 2024-08-31T00:00:00Z и 2024-09-09T00:00:00Z;

Так почему же он не генерирует дату так, как я ожидал? Мой компьютер в данный момент настроен на UTC+01:00 западная центральная Африка. Чтобы отобразить дату обратно в клиентской части, я все еще использую dayjs для этого.

export const convertDate = (params: {
  date: Date | string;
  isFortmat?: boolean;
}) => {
  const { date, isFortmat } = params;
  let converted: string = "";

  isFortmat
    ? (converted = dayjs(date).utc().format("MMM-DD-YYYY"))
    : (converted = dayjs(date).utc().format());

  return converted;
};

Сейчас это все еще на один день меньше с приведенным выше примером даты.

Ответ или решение

Информация о проблеме с датами в вашем веб-приложении

Данная проблема, связанная с неправильным отображением дат в вашем веб-приложении, вызвана сложными взаимодействиями между временными зонами, стандартами хранения времени и форматами на клиентской и серверной сторонах. Рассмотрим шаги и рекомендации для решения этой проблемы.

1. Причины проблемы

Ваше приложение управляет датами, но в текущем виде данные передаются с учетом часового пояса компьютера, что приводит к получению неправильных значений. Например, если вы выбираете дату 1 сентября 2025 года, она может интерпретироваться как 31 августа 2025 года в UTC, что создаёт несоответствие.

2. Использование UTC

Хранение дат в формате UTC является правильным подходом, так как позволяет избежать проблем с тестированием и обеспечивать совместимость при работе с пользователями из разных часовых поясов. Однако важно правильно обрабатывать и передавать эти данные на клиентской и серверной сторонах.

3. Корректная работа с dayjs

Ваши текущие функции преобразования дат используют dayjs, что является хорошим выбором для обработки дат. Однако необходимо внести изменения, чтобы гарантировать, что даты сохраняются и отображаются корректно.

4. Рекомендации по коду

На стороне клиента
  1. Измените форматирование в CustomDatePicker:
    Убедитесь, что при отправке данных на сервер вы отправляете дату в формате UTC, установив время на полночь:

    const createNewDate = (date) => {
       return dayjs(date).utc().startOf('day').toISOString();
    }
  2. Убедитесь, что состояние дат правильно обновляется:
    Убедитесь, что значения состояния имеют правильный формат:

    const handleDepositeDate = (datePara, eventType) => {
       const fullDate = createNewDate(datePara);
       setTripData(prevData => ({
           ...prevData,
       }));
    };
На стороне сервера
  1. Проверка обработки данных на сервере:
    Убедитесь, что сервер обрабатывает получаемые данные и сохраняет их в UTC:

    exports.createTrip = async (data) => {
       const startDate = dayjs(data.startDate).utc().startOf('day').toISOString();
       const endDate = dayjs(data.endDate).utc().startOf('day').toISOString();
       // Сохраните начальную и конечную дату в базе данных
    };

5. Отображение дат на клиенте

Также обратите внимание на то, как вы отображаете даты. Если пользователь на клиентской стороне находится в другом часовом поясе, перед отображением дат следует также преобразовать их в локальное время, используя dayjs:

const displayDate = (date) => {
   return dayjs(date).local().format('MMM DD, YYYY');
};

6. Итог

Следуя вышеописанным рекомендациям и сохраняя последовательность в использовании формата UTC, вы сможете избежать проблем с неправильным отображением дат. Это позволит пользователям вашего приложения видеть одни и те же даты при создании и бронировании поездок, независимо от их часовой зоны.

Убедитесь, что вы протестировали все изменения на разных устройствах и в различных часовых поясах, чтобы гарантировать, что ваша система работает корректно.

Оцените материал
Добавить комментарий

Капча загружается...