5 причин ненавидеть то, как JavaScript работает с датами

Усі статті, обговорення, новини про Front-end — в одному місці. Підписуйтеся на телеграм-канал!

В этой статье я собрала топ-5 вещей, касающихся работы с Date, которые часто вводят JS программистов в заблуждение, недоразумение и даже ярость.

Kак мне кажется, именно по этим причинам мы продолжаем тащить в свои проекты библиотеки для работы с датами, а не пользуемся средствами нативного JS.

Есть ли свет в конце тоннеля? Есть. Новое API под названием Temporal находится на третьей стадии — экспериментальной — это значит, что вы уже можете его попробовать (хотя бы с помощью полифилов) и внести свои предложения, пока не поздно.

Так почему стандартных средств текущей версии JS недостаточно?

Причина 1. Мутабельность обьектов Date

Самая известная причина проблем с Date — мутабельность обьектов Date, а также вот такое странное поведение при попытках изменить дату:

Создадим дату, соответствующую первому января:

const d1 = new Date(2022, 0, 1) // "Sat Jan 01 2022 00:00:00 GMT+0200"

А теперь изменим месяц на 10й. И получаем второе декабря:

d1.setUTCMonth(10) // "Thu Dec 02 2021 00:00:00 GMT+0200"

И, что интересно, если мы еще раз изменим месяц на 10й — то получим второе ноября:

d1.setUTCMonth(10) // "Tue Nov 02 2021 00:00:00 GMT+0200"

Один и тот же метод, вызванный дважды, дал разный результат (facepalm).

Причина 2. Конструктор класса Date принимает на вход даже полную ерунду:

Создадим две даты:

const d1 = new Date('hello');
const d2 = new Date('world');

Все произошло без каких-либо ошибок или warning-ов. Давайте как-то этими датами поманипулируем, как будто мы собрались в коде что-то делать в зависимости от того, какая дата раньше:

if (d1 <= d2) console.log('less');
if (d1 >= d2) console.log('more');

— и снова никаких сообщений об ошибках, и в консоль ничего не вывелось — ни ’less’ ни ’more’.

А все почему? Потому что вот:

console.log(d1.valueOf()) // NaN
console.log(d2.valueOf()) // NaN
console.log(d1.getTime()) // NaN
console.log(d2.getTime()) // NaN

Эти даты — d1 и d2 — не являются валидными, но JS об этом намертво молчит. У нас происходила неприятная ситуация, когда из стороннего API начали приходить невалидные даты, а на нашей стороне обьекты Date создавались из поступающих на вход строк без дополнительной валидации, и дальше при работе с датами происходила полная несуразица.

Вывод: всегда валидируйте строки с датами, которые получаете из сторонних источников (http запросы, API, файлы), прежде чем продолжать с ними какие-либо действия или манипуляции. Иначе вы будете в коде, сами того не зная, работать с NaN и даже не заметите, что это происходит. Просто все логические условия будут срабатывать как false.

Быстро нативными средствами провалидировать можно, например, так:

const d3 = new Date(startDate);
if (isNaN(d3)) throw new Error(`Invalid date: ${startDate}`)


Причина 3. Некоторые строки трактуются как UTC, некоторые — как локальное время, и это для многих неочевидно:

Создадим объект Date двумя разными способами:

const d1 = new Date('2021-07-14');
const d2 = new Date('2021/07/14');

Казалось бы — и в первом, и во втором случае мы имеем в виду 14 июля 2021 года, но посмотрите — d1 не равно d2:

console.log(d1 > d2) // true
console.log(d1 < d2) // false
console.log(d1 - d2) // 10800000

Почему даты как бы одинаковые, но это не одна и та же дата?

Потому что:

  • если в строке поступает дата, представленная в формате YYYY-MM-DD (или в полном формате ISO 8601 YYYY-MM-DDThh:mm:ss.sssZ), то она трактуется как дата в UTC таймзоне (считается, что время в строке указано по Гринвичу);
  • во всех остальных случаях строка трактуется как дата в текущей таймзоне пользователя (Киев, Нью-Йорк и т.п.) и считается, что время в строке указано в локальной таймзоне;
  • как вы понимаете, полночь 14 июля по Киеву и полночь 14 июля по Гринвичу — это два разных момента времени с разницей в 3 часа, поэтому разница между d1 и d2 составляет 10800000 миллисекунд.

Пример строки


Трактуется как


«2021-01-01»


UTC, 00:00


«2021/01/01»


Europe/Kiev, 00:00


«2021.01.01»


Europe/Kiev, 00:00


«20210101»


NaN


«2021-01-01Z»


UTC, 00:00


«2021/01/01Z»


UTC, 00:00


«2021-01-01T17:45:00.000Z»


UTC, 17:45


«2021-01-01T17:45:00»


Europe/Kiev, 17:45


«2021-01-01 17:45Z»


UTC, 17:45


«2021/01/01 17:45»


Europe/Kiev, 17:45

Причина 4. Объект Date «не помнит» из какой строки он был создан, и не дает возможности достучаться к исходной строке:

Создадим два объекта Date разными способами:

const d1 = new Date('2022-02-08T12:00:00+03:00');
const d2 = new Date('2022-02-08T13:00:00-04:00');

Дальше начинающие джаваскриптеры часто спрашивают:

1. Каким методом объектов d1 и d2 я могу получить, например, вот те части +03:00 и -04:00 из исходных строк?

Ответ: никаким!

2. Каким методом объектов d1 и d2 мне можно получить смещение в минутах от Гринвича для этих дат (180 и −240)?

Ответ: никаким!

console.log(d1.getTimezoneOffset()) // -120
console.log(d2.getTimezoneOffset()) // -120

3. Ладно, последний вопрос — а почему .getHours() мне возвращает не 12 и 13, а 11 и 19?

Ответ: а потому!

Ладно, если серьезно — потому что метод .getHours() возвращает не часы, которые были в исходной строке, а часы в твоем локальном времени, соответствующие тому времени, что было там в строке.

const d1 = new Date('2022-02-08T12:00:00+03:00');
const d2 = new Date('2022-02-08T13:00:00-04:00');
console.log(d1.getHours()) // 11
console.log(d2.getHours()) // 19


Причина 5. Intl.DateTimeFormat — хорош, но все еще ограничен в возможностях:

Объект Intl, который дает доступ к различным классам и методам для интернационализации приложений, начали разрабатывать с 2012 года, а с 2015 — внедрять в v8.

Для работы с датами и временем нас особенно интересует конструктор Intl.DateTimeFormat который дал нам две долгожданные возможности в нативном JS.

С помощью Intl.DateTimeFormat:

1. Мы можем узнать таймзону пользователя:

const userTimeZone = Intl.DateTimeFormat().resolvedOptions().timeZone;
console.log(userTimeZone); // Europe/Kiev

2. Мы можем отформатировать дату под любую таймзону:

Сделаем вот такой helper для фоматирования даты, чтобы не дублировать код:

const formatDate = function (date, timeZone) {
  const format_options = {
    year: 'numeric',
    month: 'numeric',
    day: 'numeric',
    hour: 'numeric',
    minute: 'numeric',
    second: 'numeric',
    timeZone,
    timeZoneName: 'short'
  }
  return new Intl.DateTimeFormat('en-US', format_options).format(date);
}

И посмотрим, как мы теперь можем форматировать дату и время:

formatDate(new Date('2017-07-14'), 'America/Los_Angeles')  // 7/13/2017, 5:00:00 PM PDT
formatDate(new Date('2017-07-14'), 'America/New_York')     // 7/13/2017, 8:00:00 PM EDT
formatDate(new Date('2017-07-14'), 'Europe/Kiev')          // 7/13/2017, 3:00:00 AM GMT+3
formatDate(new Date('2017-07-14'), 'Asia/Shanghai')        // 7/14/2017, 8:00:00 AM GMT+8
formatDate(new Date('2017-07-14'), 'Australia/Sydney')     // 7/14/2017, 10:00:00 AM GMT+10

Прекрасненько!

Но у нас по-прежнему, несмотря на введение Intl.DateTimeFormat, нет возможности средствами нативного js, без библиотек:

  • Получить список всех имеющихся таймзон (для выпадающего списка при регистрации пользователя, например)
  • Получить смещение какой-либо таймзоны по ее названию (к примеру −07:00 или 420 минут для ’America/Los_Angeles’)
  • Без танцев с бубнами получить аббревиатуру часового пояса (опишу ниже)

Проблема с короткими аббревиатурами часовых поясов:

Это наименьшее из зол, но когда с ним сталкиваешься и заказчик просит, чтобы были именно аббревиатуры, то это не кажется мелочью. Часто нужно отформатировать дату и показать код часового пояса — например, EEST, EST, IST, PST — так как люди привыкли к этим аббревиатурам и хотят видеть именно их, а не смещения −08:00 или +03:00

У класса Date совсем нет методов получить эти аббревиатуры, а конструктор Intl.DateTimeFormat дает нам возможность их получить, но не всегда работает, как хотелось бы.

В примере ниже вы можете заметить, что для первых двух таймзон вернулся код (PDT, EDT), а для остальных вернулось смещение в формате GMT+N

formatDate(date, 'America/Los_Angeles')  // 7/13/2017, 5:00:00 PM PDT
formatDate(date, 'America/New_York')     // 7/13/2017, 8:00:00 PM EDT
formatDate(date, 'Europe/Kiev')          // 7/13/2017, 3:00:00 AM GMT+3
formatDate(date, 'Asia/Shanghai')        // 7/14/2017, 8:00:00 AM GMT+8
formatDate(date, 'Australia/Sydney')     // 7/14/2017, 10:00:00 AM GMT+10

Часовые пояса вернулись в виде кодов только для таймзон из США, потому что мы использовали локаль ’en-US’ вот здесь, когда создавали объект DateTimeFormat в функции-хелпере formatDate:

return new Intl.DateTimeFormat('en-US', format_options).format(date);

если использовать локаль ua-UA то код часового пояса возвращается только для Europe/Kiev:

formatDate(date, 'America/Los_Angeles')  // 7/13/2017, 17:00:00 GMT-7
formatDate(date, 'America/New_York')     // 7/13/2017, 20:00:00 GMT-4
formatDate(date, 'Europe/Kiev')          // 7/13/2017, 3:00:00 EEST
formatDate(date, 'Asia/Shanghai')        // 7/14/2017, 8:00:00 GMT+8
formatDate(date, 'Australia/Sydney')     // 7/14/2017, 10:00:00 GMT+10

если использовать локаль en-AU то код часового пояса возвращается только для Australia/Sydney:

formatDate(date, 'America/Los_Angeles')  // 7/13/2017, 17:00:00 pm GMT-7
formatDate(date, 'America/New_York')     // 7/13/2017, 20:00:00 pm GMT-4
formatDate(date, 'Europe/Kiev')          // 7/13/2017, 3:00:00 am GMT+3 
formatDate(date, 'Asia/Shanghai')        // 7/14/2017, 8:00:00 am GMT+8
formatDate(date, 'Australia/Sydney')     // 7/14/2017, 10:00:00 am AEST

если использовать локаль default то код часового пояса возвращается только для Europe/Kiev:

formatDate(date, 'America/Los_Angeles')  // 7/13/2017, 17:00:00 GMT-7
formatDate(date, 'America/New_York')     // 7/13/2017, 20:00:00 GMT-4
formatDate(date, 'Europe/Kiev')          // 7/13/2017, 3:00:00 EEST
formatDate(date, 'Asia/Shanghai')        // 7/14/2017, 8:00:00 GMT+8
formatDate(date, 'Australia/Sydney')     // 7/14/2017, 10:00:00 GMT+10

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

Я считаю это непродуманным (или, как минимум, неудобным), так как пользователь может использовать локаль ua_UA (украинский язык интерфейса), находясь в командировке в США (в часовом поясе 'America/New_York’) и из-за несовпадения локали и часового пояса он будет видеть GMT-4, а не EDT в датах, отформатированных на фронтенде.

Summary

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

Какую библиотеку для работы с датами вы сейчас предпочитаете (или используете в текущем проекте) и почему?

Полезные ссылки

  1. Why you should never mutate JavaScript Date
  2. ​​Date.Parse — описание того как строки конвертируются в даты в JS
  3. Intl.DateTimeFormat
  4. Fixing JavaScript Date — Getting Started
  5. Temporal proposal
👍ПодобаєтьсяСподобалось27
До обраногоВ обраному7
LinkedIn

Найкращі коментарі пропустити

Роботу з датами взагалі можна не ненавидіти?

Як на мене, вже ті факти, що:

  • часові пояси й переходи на літній час стрічаються у найрізноманітніших формах, і ще й час від часу змінюються відповідно до політичних забаганок;
  • часові пояси століття тому можуть відрізнятися від поточних навіть не кратно 15-и хвилинам, а взагалі на довільні інтервали (і ось чому це важливо);
  • робота з високосними роками заслуговує окремої ненависти, але там хоч алгоритм більш-менш стабільний. А от усякі високосні секунди взагалі притомно не врахувати;
  • один і той же час може бути двічі на добу, див п.1; хоч якось розрізняти це для користувачів чомусь не заведено;
  • існує зоопарк форматів дат. Окрема «дяка» американським ретроградам із їхніми місяцями попереду, тому що скрєпи й так заведено, через що будь-яка притомна евристика щодо формату дат є взагалі неможливою;
  • мало в яких мовах можна записати скорочення днів тижня одним символом. У деяких і трьох замало. Мов, де скорочення місяців влазять у символ, я взагалі не знаю;
  • дитяча мнемоніка з кісточками пальців, гадаю, коментарів не потребує? ;)
  • роки рахують від народження якогось напівміфічного дядька, причому якщо проти цього виступити, то фанатики в порох (файна гра слів, хехе) зітруть так, що лівацькій cancel culture і не сниться — особливо в Bible Belt, польській зоні LGBT-free, а в Неньці — так і взагалі повсюдно. Тож дискордианський календар або ще якась перероблена система без леґасі-костурів не мають шансів, на жаль, та й їх масове введення спричинить xkcd_про_стандарти.jpg. Приблизно через це ж англійська мова наразі є світовою lingua franca замість есперанто, а історико-політичні причини, якими це обумовлено, пропонується забути й ігнорувати.
— змушують не приступати до роботи з датами без чистої, як сльоза, свідомости і кропітливого продумування кожного нюансу. І бібліотеки тут мало чим можуть допомогти.



На тлі цього всього якісь дрібні проблеми в конкретній реалізації — це взагалі заяче (чи кроляче?) лопотіння. Але корисно, дякую. Особливо про setUTCMonth — це взагалі що таке і якого дідька? Скрєпи кривої викопної реалізації Айка за 10 ночей досі блюдуть, як баґи в MS-DOS? Чому про це на написано на MDN великими червоними літерами? Що ще подібного можете навести (поза датами)? Не про скажену систему приведення типів, це ще в дитсадочку розказують ;)

Дозволені теги: blockquote, a, pre, code, ul, ol, li, b, i, del.
Ctrl + Enter
Дозволені теги: blockquote, a, pre, code, ul, ol, li, b, i, del.
Ctrl + Enter

Коментар порушує правила спільноти і видалений модераторами.

Причина 1. Мутабельность обьектов Date

Чтобы предотвратить мутацию объектов, почему бы не использовать такие библиотеки, как ImmutableJS и Mori.js, или использовать Object.assign и Object.freeze.
Мутация может быть страшна, потому что может привести к сложно-тестируемой поломке вашего программного кода.
Учитывая то, что Object.assign и Object.freeze могут предотвращать первоуровневые свойства от мутации. Если нужно предотвратить мутацию объектов нескольких уровне вложенности, можно попробовать заюзать такие библиотеки, как assignment и deep-freeze. Кто то писал уже похожую реализацию?
Замораживание экземпляра объекта не означает, что состояние объекта становится постоянным. Например такое:

let mydate = new Date();
mydate.x = 6;
console.log(mydate.x); // 6
Object.freeze(mydate);
mydate.x = 20; //заморозиться,свойство x недоступным для записи 
mydate.y = 5; // это тоже не заюзается, т.к.замораживание гарантирует, что нельзя добавить новые свойства к объекту 
console.log(mydate.x); // 6, unchanged
console.log(mydate.y); // undefined
</code>
//Но можно добиться результата  которого хотим следующим образом: 
<code>
let mydate = (function() {
    let myactualDate = new Date();

    return Object.defineProperty({}, "value", {
        get: function() {
            return new Date(myactualDate.getTime())
        },
        enumerable: true
    });
})();

console.log(mydate.value); 
mydate.value.setTime(0);
console.log(mydate.value); 
mydate.value = null;       // fails silently
console.log(mydate.value); 
т.к.замораживание гарантирует, что нельзя добавить новые свойства к объекту

Object.seal()

можно еще так

// Чтобы сделать объект obj полностью неизменяемым, замораживаем каждый объект в объекте obj.
// Для этого воспользуемся этой функцией.
function deepFreeze(obj) {

  // Получаем имена свойств из объекта obj
  var propNames = Object.getOwnPropertyNames(obj);

  // Замораживаем свойства для заморозки самого объекта
  propNames.forEach(function(name) {
    var prop = obj[name];

    // Заморозка свойства prop, если оно объект
    if (typeof prop == 'object' && prop !== null)
      deepFreeze(prop);
  });

  // Заморозить сам объект obj (ничего не произойдёт, если он уже заморожен)
  return Object.freeze(obj);
}

obj2 = {
  internal: {}
};

deepFreeze(obj2);
obj2.internal.a = 'другоеЗначение';
obj2.internal.a; // undefined

Спасибо за ссылку, обязательно посмотрю, а то ща температура и голова какая то другая...

В большинстве случает мне хватает такого:jsfiddle.net/y3go8hm8/1
Другое дело если вы получаете дату и время от пользователя, вы, скорее всего, проводите процедуру валидации его локальной даты и времени. В джс конструктор Date может принимать дату различными способами.
Чтобы устранить любую путаницу, лучше всего создавать дату, используя новый формат даты (год, месяц, день, часы, минуты, секунды, миллисекунды), даже если у вас уже есть дата в допустимом формате для синтаксического анализа. Если все программисты в тиме будут следовать этому простому правилу, будет чрезвычайно легко поддерживать код в долгосрочной перспективе, поскольку он настолько явный, насколько это возможно с конструктором Date джс.
Сохранение даты лучше всего производить в е DateTime в формате UTC. Всегда отправляя строку даты ISO или отметку времени на серверную часть.
Сохранение локального времени в бэкенде — плохая идея, лучше позволить браузеру обрабатывать преобразование в локальное время во внешнем интерфейсе.
Юзая методы toISOString() или toJSON() объекта Date для преобразования локального DateTime в UTC.

У Java до речі клас Date теж mutable, тобто ви можете змінити його значення після створення.
На жаль, тільки в Java 8 (тобто через 20 років після виходу Java 1.0) введено immutable типи — LocalDate, LocalDateTime і т.д.

Просто потрібно скористатись момент’ом :)

Ну и пусть себе будет deprecated, главное, чтобы работал.

Подождите, но .setUTCMonth(10) ... это как вообще? Этому есть какое-то логическое объяснение?

If you do not specify the dayValue parameter, the value returned from the getUTCDate() method is used.

If a parameter you specify is outside of the expected range, setUTCMonth() attempts to update the date information in the Date object accordingly. For example, if you use 15 for monthValue, the year will be incremented by 1, and 3 will be used for month.

А, от воно що.

The parameter values are all evaluated against the local time zone, rather than UTC.

Тоді все льогічно.

> const ny = new Date(2022, 0, 1)
undefined
> ny.toString()
'Sat Jan 01 2022 00:00:00 GMT+0200 (Восточная Европа, стандартное время)'
> ny.toUTCString()
'Fri, 31 Dec 2021 22:00:00 GMT'
> ny.setUTCMonth(10)
1638396000000
> ny.toString()
'Thu Dec 02 2021 00:00:00 GMT+0200 (Восточная Европа, стандартное время)'
> ny.toUTCString()
'Wed, 01 Dec 2021 22:00:00 GMT'
> ny.setUTCMonth(10)
1635804000000
> ny.toString()
'Tue Nov 02 2021 00:00:00 GMT+0200 (Восточная Европа, стандартное время)'
> ny.toUTCString()
'Mon, 01 Nov 2021 22:00:00 GMT'
В цілому, та ж біда, що й у вищезгаданому випадку з Python: оскільки окремого обʼєкта для дати без часу і зони нема — за їх невказання підставляються дані за замовчуванням, і виходить оказія.

При цьому цей вид конструктора вказання зони взагалі не підтримує, і парсити дати з рядка теж не рекомендується через відмінности реалізації в різних оглядачах. Тож виходить, що притомного способу створення дат із коробки й нема, ліл.

~~~~
Дотепне тут ще й те, що const забороняє лише переприсвоєння, але не мутації, для яких потрібен Object.freeze() (причому const — новороб, а не леґасі з 90-х, що вдвічі ганебніше).

(причому const — новороб, а не леґасі з 90-х, що вдвічі ганебніше).

а в якій мові const відноситься не до посиланння на данні, а до її внутрішнього стану?

C++, приміром.

Причому там можна і так, і так, залежно від положення const перед чи після */&.

І що, людей така неоднозначність не конфьюзить?
stackoverflow.com/...​on-const-reference-object

в Java, наче, final теж дозволяє мутувати поля.
і в C#

І що, людей така неоднозначність не конфьюзить?

Якщо такі дрібниці конфʼюзять, то не варто й лізти до C++, це ж очевидно ;) (Туди взагалі наразі психічно здоровим людям не варто лізти).

final

Це про инше, final не дозволяє створювати нащадків класу, а на мутабельність екземплярів класу ніяк не впливає. Для JS це нерелевантне через прототипне ООП, у якому класи як окрема сутність відсутні взагалі (ті, «класи», що додані в ES6 — лишень синтаксичний цукор для прототипів).

модифікатор final може бути застосований до класу, методу або змінної. З абсолютно різними наслідками.

Так, final для обʼєктів працює в Java так же, як const у JS. Тільки до чого тут const в инших мовах? ;)

Якщо вже мета створення ES6 і пізніших стандартів — спростити життя світчерам, то варто тоді final і назвати, а не вносити ще більше плутанини. Або readonly, як у C# (чимало инших інновацій поцуплено звідти). Але Maemo, що Maemo ©

Я до сих пор не понимаю как при этом можно использовать Жабаскрипт для разработки серьезных бизнес приложений?! Когда у каждого пользователя в системе своя тайм-зона, когда важно учитывать DST. И при этом одно неверное движение — и Жабаскрипт цепляет оффсет браузера, который вообще никогда не должен влиять!
И это еще на написали про другую проблему: когда объект сериализуется в JSON — то поля с датой превращаются в строки. Когда де-сериализуется обратно: то поля так и остаются строками!
То есть после десериализации получаем совсем не то, что сериализовали!
Так же браузер с удовольствием подцепит настройки системы по формату даты. Пишите приложение для США — не удивляйтесь ошибкам если у вас на машине украинский формат даты.
Если в том же .Net поддержка глобализации, разных культур и тайм-зон встроена в каждый класс и компонент — то в Жабаскрипте она отсутствует принципиально! При этом 90% бизнес — приложений, которые я видел, хотят что бы использовались настройки пользователя из базы — а локальные настройки браузера и системы не влияли. В итоге в Жабаскрипте мы воюем с бразуером в попытках заставить его делать как нам надо!

А какие еще есть варианты для Веб Браузера? ;)

Как обычно — не работать с веб браузером! Только ассемблер и свой движок полноэкранного приложения! Или консоль!

Шутка, конечно. Сам уже давно работаю с js и перечисленные проблемы встречались, но ни разу не были критичными. Да, где-то вылезали баги, но всё фиксится без проблем.

HTML + CSS как и было задумано изначально?

И HTTP/0.9 сверху еще для большей трушности.

«Изначально» не было никакого CSS, да и появился он после JS уже :)

WebAssembly не может напрямую взаимодействовать с DOM, но может вызывать явно импортированные методы.
WebAssembly может запускать код при создании экземпляра, но должен явно экспортировать функции для внешнего вызова.
WebAssembly — подходящая цель компиляции для языков высокого уровня, таких как C, C#, Go, Rust и даже TypeScript.
Вы давно свитчернулись?

На JS? Лет 6-7 назад, а что? :)

Думаю, в этом случае вам сложно будет понять, что я ответил...

В чем это выражатеся?В том что я пишу только то как оно есть и ничего не преукрашиваю?

Та он походу верит что самый умный :)

Ладно, когда-нить разберется что вся наша жизнь — это Аксиома Эскобара ©

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

Пишите понятнее, я не гуманитарий я со 122-ой...Понабирались торабарщины...

Ты тупой™ на столько что даже не гуглишь кому пытаешься запудрить мозги...

Небось даже в ШАГ одесский не смог поступить :)

Даже и не пытался...Мне и 122-ой с головой хватает...

И это еще на написали про другую проблему: когда объект сериализуется в JSON — то поля с датой превращаются в строки. Когда де-сериализуется обратно: то поля так и остаются строками!

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

И вообще, не уверен, что JSON хоть для чего-то сложнее примитивов в принципе рассматривался как формат. Symbol, Set, Map, тоже никак не сохранить. Рекурсию не передать(про кастомные варианты формата знаю).

Symbol, Set, Map, тоже никак не сохранить

и это — прекрасно!
потому что — обмен сырыми, низкоуровневыми данными — безопасней, чем полноценная сериализация.
в Джаве сколько дыр со временем вскрылось, когда подсунуть можно выполняемый код, или такой что вызовет то что низя вызывать. в php тоже в сериализаторе такие же проблемы выявились.

Symbol — зачем передавать? Он же сделан как раз чтобы точно избежать конфликта имен, то есть — сугубо внутренний для конкретного инстанса приложения
Set — конвертнуть в массив для JSON
Map — а какие НЕстроковые ключи собрались передавать в другую систему?

JSON хоть для чего-то сложнее примитивов в принципе рассматривался как формат.

Да. Только «мертвые» данные им можно передать.
и только такие и — нужно передавать.

Если же это части системы которые доверяют друг дружке полностью — то лучше вообще использовать двоичные протоколы передачи.

Ну, я и сам не вижу в этом смысла. Просто подчеркнул, что дата в этом смысле нифига не «единственный изгой». Поддерживаю касательно «живых» и «мертвых» данных.

Я до сих пор не понимаю как при этом можно использовать Жабаскрипт для разработки серьезных бизнес приложений?!

потому что — на нем быстрее разрабатывать :)
ну питон еще есть, да.

Если в том же .Net поддержка глобализации

проблема головняка с датами — не самая важная. а нередко вообще незаметная, чтобы из-за нее переходить с Node.js на .Net

а на WebAssembly для браузера — «флаг в руки и электричка на встречу»

а на WebAssembly для браузера — «флаг в руки и электричка на встречу»

Нормально оно уже юзается просто Rust нужно знать или немного разбираться...Зато хлопцы если разбиретесь то уже все...

зачем разбираться с тем, с чем не надо разбираться?
на кой Rust если на JS лучше :)

не, отговаривать конечно незачем.
попробуйте и — пролетите по скорости разработки :)
убедитесь лично, на своем кошельке.

если же хочется типизации и каких-то гарантий от нее, то опять же проще взять TS или ReScript (ReasonML) и — опять нафик никакой дирижбабль на WebAssembly не нужен

Если у вас в команде в основном свитчернутые, вы просто это не заюзаете. Будете реализовывать проект на низком перфоменсе, не отвечающим современным тенденциям веб разработки. Но выход есть, взять нормальных прогеров и платить им нормальные деньги, и ситуация поменяется координально!

если же хочется типизации и каких-то гарантий от нее, то опять же проще взять TS или ReScript (ReasonML) и — опять нафик никакой дирижбабль на WebAssembly не нужен

Строгая типизация на системе типов, заточенной для языка с динамической типизацией уже не лучшая идея. Вот в AssemblyScript система типов адекватна задаче, это другое дело, и я за AssemblyScript, но категорически против TypeScript и вот по таким причинам т.к. не любая конструкция джаваскрипт может быть им типизирована, а то, что это надмножество — это просто маркетинговое вранье. Иногда он неправильно обрабатывает типы и находит ошибки там, где их нет, а пропускает там, где они есть.
Неудобно мне студику со 122-ой вам такие вещи писать...

современным тенденциям веб разработки

современные — это какие?

и ситуация поменяется координально!

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

нормальных прогеров

нормальный прогер на Rust пишет медленней чем нормальный прогер на JS.
доказано десятителетиями практики отрасли.

выход есть, взять нормальных прогеров и платить им нормальные деньги

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

(из контекста я понял смысл слова «нормальные» — топовые 10%, а не нормальность:
Норма (характеристика) — термин для обозначения некоторой характеристики — допустимого диапазона, усреднённой(!) или среднестатистической(!) величины
)

Строгая типизация на системе типов, заточенной для языка с динамической типизацией уже не лучшая идея

Строгая статическая типизация — вообще не лучшая идея. На практике.
Поэтому пайтон, пхп и джс — успешно применяются.

Неудобно мне студику со 122-ой вам такие вещи писать...

не скромничайте.

как я говорю
всякий второй джун — великий архитектор!

Так что поучите, расскажите о построенных вами межгалактических лайнерах, в отличие от :)

современные — это какие?

Это такие, www.youtube.com/...​tch?v=i6WKne5Pvao&t=1586s
Но разговор не закончен...

гы, аргумент да — железный — раз на ютьюбе вот! есть

на ютьюбе много чего есть.

Но разговор не закончен...

о чем? о Rust или WebAssembly?

давайте начнем с Gartner hype cycle — они там где сейчас?
можете расположить?

а потом поищем
1. желающих перейти на Rust — в новом проекте
2. желающих переписать на Rust — в старом проекте
3. аругменты что скорость разработки при переходе с JS на Rust приведут к: «ситуация поменяется координально» — если без статистики — то аналитические

потому что — на нем быстрее разрабатывать :)

Да неужели?! Разработать серьезное бизнес приложение на Ангуляре или Реакте, быстрее чем ASP.Net MVC? Да вы для начала найдите на рынке фронтенд-синьоров, которые смогут вам правильно собрать нужный «зоопарк» NPM пакетов! Настоят всю это компиляцию фронтенда вебпаками и что там сейчас модно.
Ну и возвращаясь к теме топика: что будете использовать на фронте для дат и таймзон?

Да неужели?!

ну да ж :)
перед этим потому и питон с пыхой — показали

да, если нужен эффективный машинный код, или мегамонстр монолит, который пилится сотнями программистов — то не годятся.

Разработать серьезное бизнес приложение на Ангуляре или Реакте, быстрее чем ASP.Net MVC?

это такое где UI прибит гвоздями к БД, и для надежности промазанный «моментом»?
да, тут согласен, на JSF и т.п. такое ляпается быстро.
хотя, и на рельсах с джнагами и ларавелями — ничуть не медленнее :)
один известный автор на доу, пишет о канаде — просто бешенный сейчас спрос на рубистов.
Ruby тоже, хорош скоростью разработки.

И особенно согласен если «серьезное бизнес приложение» представляет собой:
РСУБД, с ядром в виде тьмы хранимых процедур
и десятков АРМиков (автоматизированных рабочих мест) — то да, не нужны для таких ангуляры с реактами. я вообще считаю что и для большинства веба — они не нужны :) потому что есть более легковестные варианты сделать «корзину покупателя»

Другими словами — вы не совсем корректно сравниваете «ASP.Net MVC» и «Ангуляр»
Это два весьма разных — подхода. И первый давно и много где отработан и имеет тьму инструментов, а не только в .Net
В той же Джаве их кроме JSF пачка живых и используемых.

ну а пых изначально был таким подходом :)

Да вы для начала найдите на рынке фронтенд-синьоров,

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

Ну и возвращаясь к теме топика: что будете использовать на фронте для дат и таймзон?

не вникал пока, нужды не было.
на беке все в ISO. а дальше — по потребности
и везде такие проблемы. ну кроме, ходят слухи в .NETе :)

Да вы для начала найдите на рынке фронтенд-синьоров, которые смогут вам правильно собрать нужный «зоопарк» NPM пакетов! Настоят всю это компиляцию фронтенда вебпаками и что там сейчас модно.

крутое мерило сеньйорности :))

И это еще на написали про другую проблему: когда объект сериализуется в JSON — то поля с датой превращаются в строки. Когда де-сериализуется обратно: то поля так и остаются строками!

Да, это проблема :) А должно как? Чтобы обычные строки магическим способом парсились в разные объекты на основании своего содержимого? =\ Хотите магии- реализуйте ее сами для своих частных нужд. А так она там не нужна, все ровно json валидировать по схеме надо будет, вот там и распарите по своему разумению.

Так же браузер с удовольствием подцепит настройки системы по формату даты.

Ну так не передавайте время в локали ¯\_(ツ)_/¯

Если в том же .Net поддержка глобализации, разных культур и тайм-зон встроена в каждый класс и компонент — то в Жабаскрипте она отсутствует принципиально!

RTFM — Intl

JS на данний момент віддає тільки Kiev ((

Названиями таймзон занимается международная организация IANA. Эта же организация 3-4 раза в год выпускает очередную версию базы данных с таймзонами (обычно это предыдущая база с небольшими правками). Эта БД используется во всех операционных системах. Запрос в IANA по поводу переименования киевской таймзоны уже прилетал, но видимо до сих пор не обработан. Я поищу ссылку, я видела «тикет». То есть это не JS виноват а IANA

UPD: вот запрос что слали в IANA и там можно почитать ответы mm.icann.org/...​tz/2015-March/022095.html

В них Сімферополь в якій зоні зараз?

Бо в мене на убунті 16.04 у ворожій.

day.js после депрекейта moment.js

Впринципе не мешало бы статью, 5 причин любить джаваскрипт, а причин ненавидить жс и так хватает.

не мешало бы статью, 5 причин любить джаваскрипт

стільки не набереться

1. В браузере только JavaScript
2. В браузере только JavaScript
3. В браузере только JavaScript
4. В браузере только JavaScript
5. В браузере только JavaScript

Так то в браузере джаваскрипт можно и отключить. И вообще аргумент в стиле в браузере только джаваскрипт, это не причина любить его, это причина ненавидить его ещё больше.

Не надо постить хрень в которой не разбираешься... Да и в статье про запуска WASM на серваке :)

Все эти костыли с DOM и навигацией Браузера работать не умеют, и вряд ли начнут это делать без JavaScript

WebAssembly — мощная виртуальная машина, реализованная всеми популярными современными браузерами. Он обеспечивает значительные преимущества в производительности по сравнению с чистым JavaScript и позволяет разработчикам создавать веб-приложения, используя язык по своему выбору. Такие проекты, как Blazor, использующие преимущества WebAssembly. Хотя WebAssembly открыла новые возможности работы в Интернете, недавно она освободилась от ограничений браузера и теперь работает практически везде.
Системный интерфейс WebAssembly, или сокращенно WASI, — это новый стандарт для запуска WebAssembly (или сокращенно «Wasm») за пределами Интернета. Чтобы лучше понять, что и почему, я рекомендую прочитать запись в блоге Standardizing WASI. Если Wasm представляет собой концептуальную машину, то WASI представляет собой концептуальную операционную систему.
Можно создать свой модуль WASI, не выходя из персонального веб-браузера. Конечно, можно установить среды выполнения локально на свой компьютер и работать оттуда.
Васи он мультиязычный...
Если не секрет у вас базовое образование Computer Science?

бла бла бла :)

шё это значит? Если вы не знаете некоторых вещей то это не значит, что их несуществует...

Научись гуглить для начала ;)

Сделайте отдолжение, свитчернитесь назад! Нехотел бы я в будущем на проекте пересечся...

Кликни в профиль хотя бы и не позорься :)

Да знаем мы таких профильнутых!Вы позоритесь шё студенты вам простые вещи объясняют...

Онаним ваааще берега попутал :)

Ну справедливости ради, для непосредственной работы с DOM обработка дат и не нужна. Можно всю бизнес-логику считать в WA, а в JS уже отдавать только строки для представления.

Зочем городить огород если JS справляется со всем?

Он несправляется со всем! Хоть вам это будет наверное и тяжело понять, напишу попростому, может тогда хотя бы проценотов 10% и поймете...
Язык компилируется в момент исполнения кода. Каждый раз, когда вы открываете сайт, javascript код начинает компилироваться. Как минимум увеличивается время выполнения программы!
Отсутствует типизация данных. Проблема всех скриптовых языков. Пока выполнение кода не дойдет до нужной строчки, не узнаешь работает ли она. А ведь значительную часть по поиску ошибок мог бы взять на себя компилятор, если бы знал типы данных, с которыми он работает. Да и по скорости выполнения, типизированный код быстрее.Правда типы можно ему подсказывать...
Не привычная для многих программистов объектная модель. Классы и наследование классов присутствует, но оно сильно отличается от привычной многим реализаций в языках программирования C++/C#/Java.
Если уже такое не поймете то вам точно пора на перековку...

Знаешь что общего между мертвым человеком и тупым ?

Вот это твой случай :)

Я так понимаю вы себя ко вторым относите?

Я себя отношу к относительно умным. IQ 130+

Flash тоже «справляется со всем», зачем же выкидывать Flash?

Ну Жопсу так захотелось :)

Можно всю бизнес-логику считать в WA, а в JS уже отдавать только строки для представления.

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

Специально для свитчерко в WebAssembly используется статическая типизация, поэтому из него можно сразу сгенерировать машинный код. У движка V8(шё джаваскрипт) есть потоковый компилятор Wasm под названием Liftoff. Он, как и Ignition, помогает быстро подготовить и запустить неоптимизированный код. И после этого юзается всё тот же TurboFan и оптимизирует машинный код. Он будет работать быстрее, чем после компиляции Liftoff, но для его генерации потребуется больше времени. Принципиальное отличие пайплайна JavaScript от пайплайна WebAssembly: движку V8 незачем собирать информацию об объектах и типах, так как у Wasm типизация статическая и всё известно заранее. Это экономит время.

Отсутствие деоптимизации

Машинный код, который TurboFan генерирует для JavaScript, можно использовать только до тех пор, пока сохраняются предположения о типах. Допустим, TurboFan сгенерировал машинный код, например, для функции f с числовым параметром. Тогда, встретив вызов этой функции с объектом вместо числа, движок опять задействует Ignition или Sparkplug. Это называется деоптимизацией.

У WebAssembly в процессе выполнения программы типы измениться не могут. Поэтому в такой деоптимизации нет необходимости. А сами типы, которые поддерживает Wasm, органично переводятся в машинный код.
Так вам будет понятнее?Или подробнее расписать?

Распиши лучше как 3й байт DWORD взять, при этом определи мы в big-endian или little-endian памяти

Про машинный код после этого поговорим, а то задвигаешь мне сказки про V8 не понимая как воообще процессор работает :)

    Little endian - это значит, что число растет от младших разрядов к старшим. Как мы и привыкли в математике. Например, если байт = 00100100(bin), то чему он будет равен вычисляется так:     100100(bin) = 2^2 + 2^5 = 4 + 32 = 36     Если запись десятичного числа выглядит как = 10367, то эта запись = 7 + 6*10 + 3*100 + 0*1000 + 1*10000 = числу 10367.     Big endian - это от старших разрядов к младших. Применительно к байтам это означает что старшина битов растет с конца числа. Н-р, вот десятичная запись числа:     10367 = 1 + 0*10 + 3*100 + 6*1000 + 7*1000 = числу 76301     Теперь про big endian касательно байтов. У процессоров есть 2 типа данных:     word - состоит из 2-х байт     dword - состоит из 2-х word     Порядок следования байтов в word и word'ов в dword'е определяется точно также. Пример (h означает что число записано в 16-ричной системе счисления):     word = 10 3Ah = 10h + 3Ah*100h = числу 3A10h     dword = 10 3A 7B 21h = 3A10h + 217Bh*10000h = числу 217B3A10h  
На самом деле в программировании под Windows принято, что dword имеет длину 4 байта, не больше и не меньше. Но т.к. данный тип не является базовым, он может быть переопределен кем-нибудь шаловливым и иметь другую длину.
зачем в DWORD нуль-терминированную строку в три символа пихать?

WA это максимум для каких то узкоспециализированных библиотек

Ага, а JS — это максимум часики и бегущие строки на страницы встраивать. К чему эти бессмысленные стереотипы? Раз есть — можно использовать для чего угодно, нет — фолбэчить Emscripten’ом в тот же JS.

JS и так весьма производительный

Так речь в треде больше о багах и питфолах, чем о производительности.

По размеру может даже хуже оказаться, хотя простор для ужимания есть.

Ты дебил? Мы кодить начали когда ты еще не родился :)

так и кодьте, по- старому, на старых технологиях, дедовскими методами, я не против...

Я с вами культурно общаюсь, так и вы общайтесь культурно. Последний раз предупреждаю!А то забаню к чертовой матери.Для меня вы не авторитет, вы не Лисочкин, не Тимур Гафарович,ни Илья Климов...Угомоните свои таланты!

А зачем его ненавидеть или любить? не нравится — не пиши на нём. Делов-то.

Проблема не в том, чтобы на нём писать, проблема в том что он жирный, вынуждает покупать железо, чтобы полноценно использовать интернет. Это не должно так быть. Чтобы минимально комфортно использовать интернет на компьютере рядовому юзеру, тебе нужен проц на 4 ядра, и 8 гигов оперативки. Ты не можешь сейчас взять, свой нетбук с антресоли, сдуть с него пыль, зайти в интернет, и посмотреть банально новости, не говоря уже про банки, документы и прочее.

железо, чтобы полноценно использовать интернет.

спробуй шапочку з фольги зробити, може зʼєднаєшся з інтернетом

Ты не туда шапку из фольги применил.

комфортно

По меркам зажравшихся айтишников?

Работает — и ладно. Вот когда сайт на GPRS не работает из-за вхардкоженных таймаутов (нужные ресурсы тупо не успевают прогрузиться), или посылает нафиг старые браузеры, потому что хочет TLS ≥1.2 — это куда хуже, чем залезание в своп и вой кулеров.

Ну рукожопость и по***стическое отношение разработчиков это вообще бич современного мира. Точно так же, как и рост мощностей, без всякой на то причины.

Манипулировать временем и датой, как известно, сложно. Разработчикам, столкнувшимся с правилами часовых поясов, дополнительными секундами, различиями в форматировании, зависящем от локали, следует прибегнуть к популярным библиотекам для работы со временем и датой.Проблема стара как джс.Концепции, описанные в этой статье, применимы не только к JavaScript, но и к другим языкам программирования.
Являются лишь началом правильной обработки данных и вычислений DateTime. Кроме того, каждая вспомогательная библиотека будет иметь свой собственный набор костылей, что справедливо даже для возможной официальной стандартной поддержки{target="_blank"} для этих типов операций.
Главное соблюдать некоторые правила: использовать ISO на бэкенде и минимально лезть в интерфейс фронта для правильного форматирования данных у пользователя. В промышленной разработке, хлопцы конечно же будут знать о некоторых нюансах и будут использовать хорошо поддерживаемые библиотеки DateTime как на бэке, так и на фронте Встроенные функции на стороне базы данных — это отдельная история, почему автор обошел эту проблему стороной?Интересно бы было почитать за опыт практического применения для решения подобного класса задач...

Роботу з датами взагалі можна не ненавидіти?

Як на мене, вже ті факти, що:

  • часові пояси й переходи на літній час стрічаються у найрізноманітніших формах, і ще й час від часу змінюються відповідно до політичних забаганок;
  • часові пояси століття тому можуть відрізнятися від поточних навіть не кратно 15-и хвилинам, а взагалі на довільні інтервали (і ось чому це важливо);
  • робота з високосними роками заслуговує окремої ненависти, але там хоч алгоритм більш-менш стабільний. А от усякі високосні секунди взагалі притомно не врахувати;
  • один і той же час може бути двічі на добу, див п.1; хоч якось розрізняти це для користувачів чомусь не заведено;
  • існує зоопарк форматів дат. Окрема «дяка» американським ретроградам із їхніми місяцями попереду, тому що скрєпи й так заведено, через що будь-яка притомна евристика щодо формату дат є взагалі неможливою;
  • мало в яких мовах можна записати скорочення днів тижня одним символом. У деяких і трьох замало. Мов, де скорочення місяців влазять у символ, я взагалі не знаю;
  • дитяча мнемоніка з кісточками пальців, гадаю, коментарів не потребує? ;)
  • роки рахують від народження якогось напівміфічного дядька, причому якщо проти цього виступити, то фанатики в порох (файна гра слів, хехе) зітруть так, що лівацькій cancel culture і не сниться — особливо в Bible Belt, польській зоні LGBT-free, а в Неньці — так і взагалі повсюдно. Тож дискордианський календар або ще якась перероблена система без леґасі-костурів не мають шансів, на жаль, та й їх масове введення спричинить xkcd_про_стандарти.jpg. Приблизно через це ж англійська мова наразі є світовою lingua franca замість есперанто, а історико-політичні причини, якими це обумовлено, пропонується забути й ігнорувати.
— змушують не приступати до роботи з датами без чистої, як сльоза, свідомости і кропітливого продумування кожного нюансу. І бібліотеки тут мало чим можуть допомогти.



На тлі цього всього якісь дрібні проблеми в конкретній реалізації — це взагалі заяче (чи кроляче?) лопотіння. Але корисно, дякую. Особливо про setUTCMonth — це взагалі що таке і якого дідька? Скрєпи кривої викопної реалізації Айка за 10 ночей досі блюдуть, як баґи в MS-DOS? Чому про це на написано на MDN великими червоними літерами? Що ще подібного можете навести (поза датами)? Не про скажену систему приведення типів, це ще в дитсадочку розказують ;)

Як на мене, вже ті факти, що:

— в сторіччі — 100 років
— в році днів, буває по різному
— тиждень — 7 днів, з місячного календаря. початок тижня, у кого як.
— 24 години в добі, 60 хвилин, секунд — дякуємо вавілонянам :)

> 24 години в добі,

Ніт, бо є ублюдський daylight saving time

В чат призывается сантехник Вася из здания ЦК.

Ну в Java щось типу того і зробили — по-факту сторонню лібу Joda Time заімплементили в ядро.
Бачу порт під javascript існує — js-joda.

Можу помилятися, але в js також немає адекватного способу вивести дату у кастомному форматі, навіть банально український варіант: 15.02.21

Наскільки пам’ятаю, нативними засобами доводилось викликати окремо методи типу getMonth, getYear і конкатенувати замість написати щось таке date.format(’dd.mm.yy’) як у інших мовах.

навіть банально український варіант: 15.02.21

new Date().toLocaleDateString(’ru-RU’) //’15.02.2022′
Или именно неполный год?
new Date().toLocaleDateString(’ru-RU’, {day: ’numeric’, month: ’numeric’, year: ’2-digit’}) // ’15.02.22′

дякую за підказку, про другий кейс не знав.

але все ж це можливо якщо дата має більш менш стандартний вигляд)

я до того, що через умовний format можна створити будь-який рядок з датою і часом, підставляючи в потрібні місця d, m і т.д.

Наприклад, на PHP:
— echo date('jS m.Y') ; // 16th 02.2022
— echo date('H:i m.Y'); // 01:55 02.2022

А в js з таким вже починаються серйозні танці)

Плюс,

toLocaleDateString

також приведе до локалі, що не завжди потрібно.

також приведе до локалі, що не завжди потрібно.

Это когда не нужно? Чтобы для американца вывести нечто вроде ’Wednesday, 2.16.22′? Ну так этому он не обрадуется. Для железа есть new Date().toISOString(), так что с строковым представлением все вполне нормально.

тут я трохи помилився, думав, що то відразу буде і зміна таймзони, це мав на увазі.

але все одно довільний формат дозволяє робити з датою і часом що завгодно тією самою дією без перевірок і конкатенцій:
echo date('[j]-[F]-[Y]'); // [16]-[February]-[2022] :)

Два вопроса:
1. нету ли там вдруг приколов с зимним-летним временем (daylight saving time)
2. нету ли там вдруг приколов с поехавшими таймзонами (Australia/Eucla я призываю тебя)

Причина 1. Мутабельность обьектов Date
Причина 2. Конструктор класса Date принимает на вход даже полную ерунду:

Цікаво, що це саме вірно й для moment.js, а це чи не найпопулярніша бібліотека для роботи з датами/часом.

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

Юзали колись третьосторонній віджет для вибору таймзони шляхом кліку на мапі. Не пригадую всіх подробиць, але виявилося, що є дві таймзони, яким відповідає одна й та сама абревіатура, і вийшло приблизно таке: віджет віддавав абревіатуру обраної таймзони, а moment.js розпізнавав її вже як іншу таймзону.

moment.js, а це чи не найпопулярніша бібліотека для роботи з датами/часом.

moment.js уже задепрекейчен, его создатели сделали новую либу Luxon и рекомендуют для новых проектов брать его или Day.js — здесь их мнение momentjs.com/docs/#/-project-status

віджет віддавав абревіатуру обраної таймзони, а moment.js розпізнавав її вже як іншу таймзону

вау, гОдный баг!

абревіатури неунікальні бай дизайн. І не стандартизовані. Тому використовувати їх можна тільки знаючи культуру користувача.

У класса Date совсем нет методов получить эти аббревиатуры

що мав би повертнути Date чи Intl для дати в з поясом UTC-5?
маємо:
Інші часові пояси в UTC-05
ACT Амазонський Стандартний Час
CDT Північноамериканський Центральний Літній Час
COT Колумбійський Стандартний Час
CST Стандартний Час На Кубі
EASST Літній Час На Острові Пасхи
ECT Еквадорський Час
PET Cтандартний Час В Перу

Вказуючи локаль/культуру ви звужуєте список варіантів для intl, тому і отримуєте бажане. І ні, назва таймзони не говорить нічого про культуру. всього лиш якихось півтора десятки років тому геть усі місцеві мобілки жили в поясі берліну чи афін.

Вывод: всегда валидируйте строки с датами, которые получаете из сторонних источников

Завжди валідуйте ВСЕ, що отримуєте ззовні, дати тут не основне.

Дата/Час самі по собі попаболь, навіть без js

«Наймасовіша» — це точно. Але чи свідомо для нових проектів — ні. Купа старих живих проектів її використовують для якихось потреб і це їх не ламає. Тож лічільники NPM’а продовжуть крутитися. До того ж, не у кожному проекті необхідні складні операції з часом. Або маніпулювання з зонами. А може, немає потреби зменшити розмір бандла. У кожного проекта свої умови. Не всім треба за хлібом на Ferrari. Хтось і на тракторі зможе. ;)

Щодо таймзон, то там інші проблеми. Державно-локаційні. Для початку, стандарти таймзон інколи змінюються. Наприклад, Україна з того року знаходиться у EET (Eastern European Time), хоча зону у документах задекларували раніше. Тож тут нічого дивного з визначеням зони. До того ж, та сама `географічна тайм зона` у сусідніх державах може бути ... різною. Наприклад, той же EET (північ) та CAT (Central Africa Time, південь): обидві мають UTC+02:00. Але EET переходить на `літній час` (EET -> EEST, UTC+02:00 -> UTC+03:00), а CAT — ні. Дублювання скорочень — непоодинокий випадок. Навіть, є 3 таймзони з тим самим скороченням. Там різниця у повній назві та не зберігаємому зміщенні до UTC.
Запрогати всі таймзони у словник можна. Але буде потрібна логіка та інструментарій для визначення. І одним locale тут не обійтись. Буде потрібен location, який не всі дозволяють...

Підписатись на коментарі