Объединить дату и время без UTC

Я изо всех сил пытаюсь обрабатывать даты и время в среде Javascript. Мы используем два поля ввода для получения даты и времени события. Событие должно отображать и вычислять все даты в пределах местного часового пояса. Например. если событие происходит в Мельбурне, Австралия, то я вижу местное время в Мельбурне.

Мы используем flatpickr для ввода даты и времени (2 отдельных поля).

Дата возвращает: 2022-11-18T00:00:00.000Z (т.е. нас интересует только часть даты. Время всегда 00:00:00. Оно хранится в Mongo как "date" : ISODate("2022-11-18T00:00:00.000+0000"))

Время возвращается: 09:00 AM

Я хотел бы сохранить это в нашей MongoDB как 2022-11-18T09:00:00.000.

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

Я пробовал момент и дату-fns: однако я не могу найти согласованность между серверами и браузерами. Все, что я пробовал на SO, всегда конвертирует UTC.

Любая помощь приветствуется.

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

RobG 18.11.2022 05:09

Спасибо @RobG. Чтобы это сработало, мне понадобится часовой пояс места события. В некоторых случаях мы не будем знать местоположение. Мы получили бы дату и время от местоположения пользователя (который публикует данные).

papawheelie 18.11.2022 06:26
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
0
2
55
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

В MongoDB/JavaScript Date объекты имеют время UTC - всегда и только!

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

Почти в любой функции «дата-в-строку» вы можете предоставить информацию о часовом поясе для желаемого вывода.

Это имеет смысл, однако применительно к моему сценарию я этого не испытываю. например Я использую следующее для объединения: новая дата (${savedEvent.date.toISOString().slice(0, -1).substring(0, 10)} ${savedEvent.deliveryTime}) Локально: преобразуется во время UTC, как и ожидалось. AWS (EB): использует местный часовой пояс. Я могу точно указать это на новую дату, но не знаю, как решить

papawheelie 18.11.2022 13:01

Поэтому, когда я возвращаюсь к основам и сохраняю новую дату(), она работает, как и ожидалось, на обоих серверах. Поэтому это связано с манипуляциями со строками при объединении двух полей (данные и время) - я буду продолжать, пока не получу результат

papawheelie 18.11.2022 13:39

Чтобы разобрать строку в объект Date, я предлагаю готовые библиотеки, такие как moment.js , Luxon или Day.js. Обычно они намного лучше нативных Date методов JavaScript.

Wernfried Domscheit 18.11.2022 14:39
new Intl.DateTimeFormat().resolvedOptions().timeZone возвращает представительное местоположение IANA для хоста, чтобы вы могли его использовать (при условии, что оно согласуется с датой и временем, которые предоставляет пользователь).
RobG 19.11.2022 08:36
Ответ принят как подходящий

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

Одна проблема заключается в том, как получить UTC в первую очередь.

При условии, что на устройстве пользователя установлены соответствующие региональные настройки, создайте дату из входных данных даты и времени (вероятно, это требует ручного анализа, не используйте встроенный анализатор). Затем сгенерируйте временную метку, используя toISOString, которая будет эквивалентна UTC.

Чтобы затем получить правильную информацию о смещении, вы можете использовать:

new Intl.DateTimeFormat().resolvedOptions().timeZone

который вернет местоположение представителя IANA, на которое настроена система, что, мы надеемся, соответствует дате и времени местного события. Если нет (например, пользователь может создать событие для другого часового пояса), вам потребуется поддержка библиотеки для создания подходящей отметки времени UTC (см. Расчет смещения часового пояса только для одного конкретного часового пояса).

Сохраните временную метку UTC (или объект даты) в базе данных вместе с часовым поясом события. Таким образом, вы можете сгенерировать дату и время для места события, а также эквивалентную дату и время на основе системных настроек пользователя или любого часового пояса, который вам нравится.

Например.

// Create a Date for New Year's Eve party starting
// at 8:00pm based on the user's current system settings
let event = new Date(2022,11,31, 20);

// Generate UTC timestamp
let ts = event.toISOString();

// Get the (assumed) event offset data
let tz = new Intl.DateTimeFormat().resolvedOptions().timeZone;

// Data to store:
console.info(
  `Store\n` +
  `UTC timestamp: ${ts}\n` +
  `IANA timezone: ${tz}`
); 

console.info(
  `Event local date and time\n` +
  new Date(ts).toLocaleString('en-ca', {
    timeZone: tz,
    timeZoneName: 'long'
  })
); 

// Equivalent for user in Somalia
console.info(
  `Mogadishu equivalent\n` +
  new Date(ts).toLocaleString('en-ca', {
    timeZone:'Africa/Mogadishu',
    timeZoneName: 'long'
  })
);

Вышеприведенное демонстрирует, что если у вас есть временная метка UTC и часовой пояс IANA, вы можете создать временную метку для любого часового пояса, в том числе для самого события.

Другие вопросы по теме