To get the absolute value of time, use the TimesSpan Duration() method.
Let’s say the following is our TimeSpan.
TimeSpan ts = new TimeSpan(-7, -50, -25);
Now to get the absolute value.
TimeSpan duration = ts.Duration();
Let us see the complete code.
Example
Live Demo
using System;
using System.Linq;
public class Demo {
public static void Main() {
TimeSpan ts = new TimeSpan(-7, -50, -25);
TimeSpan duration = ts.Duration();
Console.WriteLine(duration);
}
}
Output
07:50:25
От переводчика
Однажды каждый разработчик коснется работы с часовыми поясами и будет фрустрирован необходимостью съесть слона для реализации, казалось бы, минорной задачи. Оказавшись в такой ситуации я нашел эту статью, которая дала ответы на все мои вопросы.
В моем случае она была столь полезной, что я решил перевести ее, чтобы запомнить получше и дебютировать с переводом на хабре.
Статья немаленькая и делится логически на две части:
-
Детальная информация о принятом сегодня стандарте времени и часовых поясов, которая будет полезна для разработчика на любом языке
-
Обзор подхода к работе со временем, принятого в JS, объекта Date, его методов и лучших практик в клиент-серверной разработке, и вывод почему для полноценной работы с датой вам не обойтись без задействования специальных библиотек.
Поехали!
Обработка часового пояса в JavaScript
Недавно я работал над задачей добавления функции часового пояса в TOAST UI Calendar, библиотеку календарей JavaScript, созданную моей командой. Я хорошо знал, что поддержка часовых поясов в JavaScript довольно таки слабая и надеялся, что абстрагирование существующих инструментов легко решило бы многие проблемы.
Однако моя надежда не оправдалась, и продвигаясь в решении задачи, я все больше осознавал, насколько непросто обрабатывать часовой пояс в JavaScript. Реализация функций часовых поясов помимо простого форматирования времени и вычисления временных данных с помощью сложных операций (например, календаря) была поистине сложной задачей. По этой причине я приобрел бесценный опыт решения проблемы, который привел к возникновению новых проблем.
Цель это статьи — обсудить проблемы и решения, связанные с особенностями применения часовых поясов в JavaScript.. В процессе написания этой объемной статьи, я внезапно понял, что корень моей проблемы кроется в моем плохом понимании концепции часовых поясов. Поэтому я сначала подробно рассмотрю определение и стандарты, относящиеся к часовому поясу, а затем расскажу о JavaScript.
Что такое часовой пояс (time zone)?
Часовой пояс — это регион, который использует единый, законодательно установленный стандарт времени. У многих стран свой уникальный часовой пояс, а в некоторых крупных странах, таких как США или Канада, даже несколько часовых поясов. Интересно, что хотя Китай достаточно велик, чтобы иметь несколько часовых поясов, он использует только один часовой пояс. По этой причине солнце встает в западной части Китая около 10:00 утра.
GMT, UTC и Offset
GMT (время по Гринвичу)
Местное время в Корее обычно GMT+09:00. GMT — это сокращение от среднего времени по Гринвичу, которое является временем на часах Королевской Обсерватории в Гринвиче, Великобритания, расположенной на долготе 0. Система GMT начала распространяться 5 февраля 1925 года и была мировым стандартом времени до 1 января 1972 года.
UTC (универсальное глобальное время)
Многие считают GMT и UTC одним и тем же, и во многих случаях они взаимозаменяемы, но на самом деле у них есть существенные отличия. UTC было создано в 1972 году для компенсации проблемы замедления вращения Земли. Эта система времени основана на Международном атомном времени, которое использует атомную частоту цезия для установки стандарта времени. Другими словами, UTC — более точная система. Хотя фактическая разница во времени между ними мала, UTC является более точным выбором для разработчиков программного обеспечения.
Когда система еще находилась в разработке, англоязычное население хотело назвать систему CUT (всемирное координированное время), а франкоязычное население хотело назвать ее TUC (Мировое время). Однако ни одна из сторон не выиграла бой, поэтому они пришли к соглашению об использовании аббревиатуры UTC, поскольку она содержала все основные буквы (C, T и U).
Offset (смещение часового пояса относительно часового пояса UTC)+09:00 в UTC+09:00 означает, что местное время на 9 часов опережает стандартное время UTC. Это означает, что когда в Корее 21:00, в регионе UTC+00:00 — полдень, 12:00. Разница во времени между стандартным временем UTC и местным временем называется смещением (offset), которое выражается следующим образом: +09:00, -03:00 и т. д.
Часто страны называют свои часовые пояса своими уникальными именами. Например, часовой пояс Кореи называется KST (стандартное время Кореи) и имеет определенное значение смещения, которое выражается как KST = UTC+09:00. Однако смещение +09:00 также используется не только Кореей, но и Японией, Индонезией и многими другими, что означает, что отношение между смещениями и именами часовых поясов не 1:1, а 1:N. Список стран со смещением +09:00 можно найти в википедии на странице UTC+09:00.
Некоторые смещения не производятся строго на почасовой основе. Например, в Северной Корее в качестве стандартного времени используется +08:30, а в Австралии +08:45 или +09:30, в зависимости от региона.
Полный список смещений UTC и их названия можно найти здесь: Список смещений времени UTC.
Time zone !== offset?
Как я уже упоминал ранее, мы используем названия часовых поясов (KST, JST) взаимозаменяемо со смещением, не различая их. Но это неправильно рассматривать время и смещение в определенном регионе одинаково, по следующим причинам:
Летнее время (DST)
Хотя это понятие может быть неизвестно в некоторых странах, во многих странах летнее время официально принято — в частности, в США, Великобритании и странах Европы. На международном уровне летнее время обычно называется Daylight Saving Time (DST). Во время перехода на DST мы переводим стрелки часов на один час вперед от стандартного времени в летнее время.
Например, в Калифорнии в США зимой используется PST (стандартное тихоокеанское время, UTC-08:00), а летом — PDT (тихоокеанское летнее время, UTC-07:00). Регионы Северной Америки, в которых используются два часовых пояса, вместе называются Тихоокеанским временем (PT), и это название принято во многих регионах США и Канады.
Теперь самое интересное: когда именно начинается и заканчивается лето? На самом деле, даты начала и окончания летнего времени остаются на собственное усмотрение каждой страны. Это раз. А два — страна может поменять время и до изменения мы должны будем учитывать одно время, а после изменения — другое.
Например, до 2006 года в США и Канаде летнее время начиналось с первого воскресенья апреля в 02:00 и длилось до последнего воскресенья октября в 12:00, а с 2007 года стало начинаться во второе воскресенье марта с 02:00 и длиться до 2:00 первого воскресенья ноября. В европейских странах летнее время применяется единовременно по всей стране, в то время как в США летнее время поочередно применяется к часовым поясам.
Меняется ли часовой пояс?
Как я вкратце упомянул ранее, каждая страна имеет собственное право определять, какой часовой пояс использовать, а это означает, что ее часовой пояс может быть изменен по любым политическим или экономическим причинам. Например, в штатах период перехода на летнее время был изменен в 2007 году, поскольку президент Джордж Буш подписал энергетическую политику в 2005 году. Египет и Россия использовали летнее время, но перестали его использовать с 2011 года.
В некоторых случаях страна может изменить не только летнее время, но и стандартное время. Например, Самоа использовало смещение UTC-10:00, но позже перешло на UTC+14:00, чтобы уменьшить потери в торговле, вызванные разницей во времени между Самоа и Австралией и Новой Зеландией. Это решение привело к тому, что страна пропустила весь день 30 декабря 2011 года, и об этом сообщили газеты по всему миру.
Нидерланды использовали смещение +0:19:32.13, которое является излишне точным с 1909 года, но изменили его на смещение +00:20 в 1937 году, а затем снова изменили на смещение +01:00 в 1940 году, и придерживаются его до сих пор.
1 часовой пояс : N смещений
Подводя итог: один часовой пояс может иметь одно или несколько смещений. Какое смещение страна будет использовать в качестве стандартного времени в определенный момент, может варьироваться по политическим или экономическим причинам.
Это не большая проблема в повседневной жизни, но эта проблема возникает при попытке систематизировать работу со временем на основе определённых правил. Представим, что вы хотите установить стандартное время для своего смартфона с помощью смещения (offset). Если вы живете в регионе, где применяется летнее время, время на вашем смартфоне следует корректировать всякий раз, когда летнее время начинается и заканчивается. В этом случае вам понадобится концепция, которая объединяет стандартное время и летнее время в один часовой пояс (например, Тихоокеанское время).
Но это не может быть реализовано с помощью пары простых правил. Например, поскольку штаты изменили даты начала и окончания летнего времени в 2007 г., 31 мая 2006 г. вам следовало жить по PDT (тихоокеанское летнее время, UTC-07:00), а после 31 марта 2007 г. уже по PST (стандартное тихоокеанское время, UTC-08:00). Это означает, что для обращения к определенному часовому поясу вы должны знать все исторические данные о стандартных часовых поясах или момент времени, когда правила летнего времени были изменены.
Вы не можете просто сказать: «Часовой пояс Сан-Франциско — PST, UTC-08:00». Вы должны быть более конкретными и сказать: «Сан-Франциско в настоящее время использует PST как стандартное время».
Пример, как страны Северной Америки стандартизировали эти расхождения для себя — это объединение PST и PDT в PT, учитывающее текущее стандартное время и его летнее время. Однако, это только североамериканская практика и перед нами продолжает стоять задача работы с датами в прошлом и будущем, на которые влияют произошедшие и ожидаемые изменения в правилах, во всех часовых поясах. Хорошо бы чтобы все это было оформлено в международный стандарт.
База данных часовых поясов IANA
По правде говоря, часовые пояса — это скорее база данных, чем набор правил, потому что они должны содержать все соответствующие исторические изменения. Существует несколько стандартных баз данных, предназначенных для обработки проблем с часовыми поясами, и наиболее часто используемой из них является База данных часовых поясов IANA. База данных часовых поясов IANA, также называемая базой данных tz (или tzdata), содержит исторические данные о местном стандартном времени по всему миру и изменениях летнего времени. Эта база данных организована так, чтобы содержать все исторические данные, которые в настоящее время можно проверить, чтобы гарантировать точность времени, начиная со времени Unix (1970.01 / 01 00:00:00). В ней также есть данные до 1970 года, но их точность не гарантируется.
Соглашение об именовании соответствует правилу Area/Location. Area обычно относится к названию континента или океана (Азия, Америка, Тихий океан), в то время как Location — к названию крупных городов, таких как Сеул и Нью-Йорк, а не к названию стран (это потому, что продолжительность жизни страны намного короче, чем города). Например, часовой пояс Кореи — Азия / Сеул, а часовой пояс Японии — Азия / Токио. Хотя эти две страны находятся географически в регионе, где принят стандартный offset UTC+09:00, они имеют разную историю изменений часовых поясов. Вот почему в этом стандарте они обрабатываются с использованием разных часовых поясов.
База данных часовых поясов IANA поддерживается многочисленными сообществами разработчиков и историков. Новые исторические факты и политические решения сразу же попадают в базу данных, что делает ее наиболее надежным источником. Более того, многие ОС на базе UNIX, включая Linux и macOS, а также популярные языки программирования, включая Java и PHP, используют эту базу данных.
Обратите внимание, что Windows отсутствует в приведенном выше списке поддержки. Это потому, что Windows использует собственную базу данных под названием Microsoft Time Zone Database. Однако эта база данных неточно отражает исторические изменения и поддерживается только Microsoft. Следовательно, она менее точна и надежна, чем IANA.
JavaScript и База данных часовых поясов IANA
Как я вкратце упомянул ранее, поддержка часового пояса в JavaScript довольно плохая. Поскольку по умолчанию он следует часовому поясу определенного региона (точнее, часовому поясу, выбранному во время установки ОС), возможности изменить его на новый часовой пояс нет. Кроме того, его спецификация для стандарта баз данных так же плохо определена, вы заметите это, если внимательно ознакомитесь с документацией ES2015. В отношении местного часового пояса и доступности летнего времени существует лишь несколько неопределенных заявлений. Например, летнее время определяется следующим образом: ECMAScript 2015 — Настройка летнего времени.
В зависимости от реализации, алгоритм использует наилучшую доступную информацию о часовых поясах для определения местной поправки на летнее время DaylightSavingTA (t), измеряемой в миллисекундах. Ожидается, что реализация ECMAScript сделает все возможное, чтобы определить местное летнее время.
Похоже, он просто говорит: «Эй, ребята, попробуйте и сделайте все возможное, чтобы это сработало». Это создает проблемы в кроссбраузерности. Вы можете подумать: «Это небрежно!», и тогда вы заметите еще одну строчку прямо под ним:
ПРИМЕЧАНИЕ. рекомендуется использовать информацию о часовых поясах из базы данных часовых поясов IANA http://www.iana.org/time-zones/.
Спецификации ECMA признается, что не имеет специальной стандартной базы данных в JavaScript и рекомендует использовать базу данных часовых поясов IANA. В результате разные браузеры используют свои собственные решения для расчета часовых поясов, и они часто несовместимы друг с другом. Позже в ECMA-402 добавили возможность использовать часовой пояс IANA в виде Intl.DateTimeFormat для ECMAScript Internationalization API. Однако этот вариант по-прежнему гораздо менее надежен, чем в других языках программирования.
Часовой пояс в серверно-клиентской среде
Мы предположим простой сценарий, в котором необходимо учитывать часовой пояс. Допустим, мы собираемся разработать простое приложение-календарь, которое будет обрабатывать информацию о времени. Когда пользователь вводит дату и время в поле на странице реестра в клиентской среде, данные передаются на сервер и сохраняются в БД. Затем клиент получает зарегистрированные данные расписания с сервера и отображает их на экране.
Однако здесь есть то, что нужно учесть. Что, если некоторые из клиентов, обращающихся к серверу, находятся в разных часовых поясах? Расписание, зарегистрированное на 11 марта 2017 г. в 11:30 в Сеуле, должно отображаться как 10 марта 2017 г. в 21:30 при просмотре расписания в Нью-Йорке. Чтобы сервер поддерживал клиентов из разных часовых поясов, расписание, хранимое на сервере, должно иметь абсолютные значения, на которые не влияют часовые пояса. Каждый сервер имеет свой способ хранения абсолютных значений, и это выходит за рамки данной статьи, поскольку все зависит от сервера или среды базы данных. Однако для того, чтобы это работало, дата и время, передаваемые от клиента на сервер, должны быть значениями, основанными на том же смещении (обычно в формате UTC) или значениями, которые также включают данные часового пояса клиентской среды.
Обычно такие данные передаются в форме времени Unix на основе UTC или ISO-8601, содержащего информацию о смещении. В приведенном выше примере, если 11:30 утра 11 марта 2017 г. в Сеуле необходимо преобразовать во время Unix, это будет целочисленный тип со значением 1489199400. В соответствии с ISO-8601 это будет строковый тип, значение которого: 2017-03-11T11:30:00+09:00.
Если вы работаете с этим с помощью JavaScript в среде браузера, вы должны преобразовать введенное значение, как описано выше, а затем преобразовать его обратно в соответствии с часовым поясом пользователя. Необходимо учитывать обе эти две задачи. В языке программирования первый называется «синтаксическим анализом», а второй «форматированием». Теперь давайте выясним, как это обрабатывается в JavaScript.
Даже когда вы работаете с JavaScript в серверной среде с использованием Node.js, возможно вам может потребоваться проанализировать данные, полученные от клиента. Однако, поскольку серверы обычно синхронизируют свой часовой пояс с базой данных, а задача форматирования обычно предоставляется клиентам, вам нужно учитывать меньше факторов, чем в среде браузера. В этой статье мы будем рассматривать примеры в среде браузера.
Объект даты в JavaScript
В JavaScript задачи, связанные с датой или временем, обрабатываются с помощью объекта Date. Это собственный объект, определенный в ECMAScript, также, как Array или Object. Он в основном реализован в собственном коде, таком как C++. Его API хорошо описан в документации MDN. На это большое влияние оказывает класс Java java.util.Date. В результате он наследует некоторые нежелательные черты, такие как характеристики изменяемых данных и месяц, начинающийся с 0.
Объект Date в JavaScript внутренне управляет данными времени, используя абсолютные значения, такие как время Unix. Однако конструкторы и методы, такие как функции parse(), getHour(), setHour() и т.д. находятся под влиянием местного часового пояса клиента (точнее, часовой пояса операционной системы, в которой запущен браузер). Следовательно, если вы создаете объект Date с использованием данных, вводимых пользователем, данные будут напрямую отражать местный часовой пояс клиента.
Как я упоминал ранее, JavaScript не предоставляет произвольного способа изменения часового пояса. Поэтому я предполагаю здесь ситуацию, когда можно напрямую использовать настройку часового пояса браузера.
Создание объекта даты с пользовательским вводом
Вернемся к первому примеру. Предположим, что пользователь вошел в 11:30 11 марта 2017 г. на устройстве, которое соответствует часовому поясу Сеула. Эти данные хранятся в 5 целых числах 2017, 2, 11, 11 и 30, каждое из которых представляет год, месяц, день, час и минуту соответственно. (Поскольку месяц начинается с 0, значение должно быть 3–1 = 2.) С помощью конструктора вы можете легко создать объект Date, используя числовые значения.
const d1 = new Date(2017, 2, 11, 11, 30);
d1.toString(); // Sat Mar 11 2017 11:30:00 GMT+0900 (KST)
Если вы посмотрите на значение, возвращаемое d1.toString(), то узнаете, что абсолютное значение созданного объекта составляет 11:30 11 марта 2017 г. на основе смещения +09:00 (KST).
Вы также можете использовать конструктор вместе со строковыми данными. Если вы передаете строку при создании Date, он внутренне вызывает Date.parse() и вычисляет правильное значение. Эта функция поддерживает спецификации RFC2888 и ISO-8601. Однако, как описано в документе MDN Date.parse(), возвращаемое значение этого метода варьируется от браузера к браузеру, и формат типа строки может повлиять на предсказание точного значения. Таким образом, рекомендуется не использовать этот метод.
Например, строка вида 2015-10-12 12:00:00 возвращает NaN в Safari и Internet Explorer, в то же время эта строка возвращает местный часовой пояс в Chrome и Firefox. В некоторых случаях она возвращает значение, основанное на стандарте UTC.
Создание объекта даты с использованием данных сервера
Предположим теперь, что вы собираетесь получать данные с сервера. Если данные имеют числовое значение времени Unix, вы можете просто использовать конструктор для создания объекта Date. Когда конструктор Date получает единственный числовой параметр, он распознается, как значение времени Unix в миллисекундах. (Внимание: JavaScript обрабатывает время Unix в миллисекундах. Это означает, что стандартное числовое значение времени Unix необходимо умножить на 1000) Результат выполнения следующего кода будет таким же, как и в предыдущем примере.
const d1 = new Date(1489199400000);
d1.toString(); // Sat Mar 11 2017 11:30:00 GMT+0900 (KST)
Что если вместо времени Unix использовать строковый тип, такой как ISO-8601? Как я объяснил в предыдущем абзаце, метод Date.parse() ненадежен, и его лучше не использовать. Однако, поскольку в ECMAScript 5 и более поздних версиях указана поддержка ISO-8601, вы можете использовать строки в формате, указанном в ISO-8601, для конструктора Date в Internet Explorer 9.0 или более поздней версии, который поддерживает ECMAScript 5 при осторожном использовании.
Если вы поддерживаете старые браузеры, не забудьте добавить букву Z в конце. Без неё старые браузеры иногда интерпретируют строку на основе вашего местного времени, а не UTC. Ниже приведен пример запуска в Internet Explorer 10.
const d1 = new Date('2017-03-11T11:30:00');
const d2 = new Date('2017-03-11T11:30:00Z');
d1.toString(); // "Sat Mar 11 11:30:00 UTC+0900 2017"
d2.toString(); // "Sat Mar 11 20:30:00 UTC+0900 2017"
Согласно техническим характеристикам результирующие значения в обоих случаях должны быть одинаковыми. Однако, как вы можете видеть, результирующие значения отличаются как d1.toString() и d2.toString(). В последней версии браузера эти два значения будут одинаковыми. Чтобы избежать проблем такого рода, всегда следует добавлять Z в конце строки, если нет данных о часовом поясе.
Создание данных для передачи на сервер
Теперь используя созданный ранее объект Date, вы можете свободно добавлять или вычитать время в зависимости от местных часовых поясов. Но не забудьте преобразовать данные обратно в предыдущий формат в конце обработки, прежде чем передавать их обратно на сервер.
Если это время Unix, вы можете просто использовать метод getTime() для выполнения этого. (Обратите внимание на использование миллисекунд.)
const d1 = new Date(2017, 2, 11, 11, 30);
d1.getTime(); // 1489199400000
А как насчет строк формата ISO-8601? Как объяснялось ранее, Internet Explorer 9.0 или выше, который поддерживает ECMAScript 5 или выше, поддерживает формат ISO-8601. Вы можете создавать строки формата ISO-8601, используя метод toISOString() или toJSON(). toJSON() может использоваться для рекурсивных вызовов с JSON.stringify() или другими. Оба метода дают одинаковые результаты, за исключением случая, когда они обрабатывают недопустимые данные:
const d1 = new Date(2017, 2, 11, 11, 30);
d1.toISOString(); // "2017-03-11T02:30:00.000Z"
d1.toJSON(); // "2017-03-11T02:30:00.000Z"
const d2 = new Date('Hello');
d2.toISOString(); // Error: Invalid Date
d2.toJSON(); // null
Вы также можете использовать метод toGMTString() или toUTCString() для создания строк в формате UTC. Поскольку они возвращают строку, удовлетворяющую стандарту RFC-1123, вы можете использовать это по мере необходимости.
Объекты Date включают toString(), toLocaleString() и их методы расширения. Однако, поскольку они в основном используются для возврата строки, основанной на местном часовом поясе, и возвращают различные значения в зависимости от используемого браузера и ОС, они не очень полезны.
Изменение местного часового пояса
Теперь вы можете видеть, что в JavaScript слабая поддержка часовых поясов. Что делать, если вы хотите изменить настройку местного часового пояса в своем приложении, не соблюдая настройки часового пояса вашей ОС? Или что, если вам нужно отображать несколько часовых поясов одновременно в одном приложении? Как я уже говорил несколько раз, JavaScript не позволяет вручную изменять местный часовой пояс. Единственное решение этой проблемы — добавить или удалить значение смещения от даты при условии, что вы уже знаете значение смещения часового пояса. Но пока не расстраивайтесь. Посмотрим, есть ли какое-нибудь решение, чтобы обойти это.
Давайте продолжим предыдущий пример, предполагая, что часовой пояс браузера установлен на Сеул. Пользователь входит в 11:30 11 марта 2017 г. по сеульскому времени, но хочет видеть местное время Нью-Йорка. Сервер передает данные времени Unix в миллисекундах и вы можете преобразовать их, если знаете смещение местного часового пояса, а мы знаем, что для Нью-Йорка это -05:00
Для вычисления смещений вы можете использовать метод getTimeZoneOffset(). Этот метод — единственный API в JavaScript, который можно использовать для получения информации о местном часовом поясе. Он возвращает значение смещения текущего часового пояса в минутах относительно часового пояса UTC.
const seoul = new Date(1489199400000);
seoul.getTimeZoneOffset(); // -540
Возвращаемое значение -540 означает, что часовой пояс Сеула опережает UTC на 540 минут. Обратите внимание, что знак минус перед значением противоположен знаку плюса в стандартном обозначении смещения (+09:00). Не знаю почему, но вот так это отображается. Если мы вычислим смещение Нью-Йорка с помощью этого метода, мы получим 60 * 5 = 300. Преобразуйте разницу 840 в миллисекунды и создайте новый объект Date. Затем вы можете использовать get-методы этого объекта для преобразования значения в любой формат по вашему выбору. Давайте создадим простую функцию форматирования для сравнения результатов.
function formatDate(date) {
return date.getFullYear() + '/' +
(date.getMonth() + 1) + '/' +
date.getDate() + ' ' +
date.getHours() + ':' +
date.getMinutes();
}
const seoul = new Date(1489199400000);
const ny = new Date(1489199400000 - (840 * 60 * 1000));
formatDate(seoul); // 2017/3/11 11:30
formatDate(ny); // 2017/3/10 21:30
formatDate() показывает правильную дату и время в соответствии с разницей часовых поясов между Сеулом и Нью-Йорком. Похоже, мы нашли простое решение. Тогда можем ли мы преобразовать его в местный часовой пояс, если мы знаем смещение региона? К сожалению, ответ отрицательный. Помните, что я сказал ранее? Что данные часового пояса — это своего рода база данных, содержащая историю всех изменений смещения? Чтобы получить правильное значение часового пояса, вы должны знать значение смещенияна момент даты (а не на текущую дату).
Проблема преобразования местного часового пояса
Если вы продолжите работать с приведенным выше примером еще немного, вы скоро столкнетесь с проблемой. Пользователь хочет проверить время по местному времени Нью-Йорка, а затем изменить дату с 10-го на 15-е. Если вы используете метод setDate() объекта Date, вы можете изменить дату, не изменяя другие значения.
ny.setDate(15);
formatDate(ny); // 2017/3/15 21:30
Выглядит достаточно просто, но здесь есть ловушка. Что бы вы сделали, если бы вам пришлось передать эти данные обратно на сервер? Поскольку данные были изменены, вы не можете использовать такие методы, как getTime() или getISOString(). Следовательно, вы должны отменить преобразование, прежде чем отправлять его обратно на сервер.
const time = ny.getTime() + (840 * 60 * 1000); // 1489631400000
Некоторые из вас могут задаться вопросом, почему я добавил использование преобразования данных, когда мне все равно нужно преобразовать их обратно перед возвратом. Выглядит так, будто я могу просто обработать их без преобразования и временно создать преобразованный объект Date только при форматировании. Однако не все так просто. Если вы измените дату объекта Date по сеульскому времени с 11-го на 15-е, добавляются 4 дня (24 * 4 * 60 * 60 * 1000). Однако по местному времени Нью-Йорка, поскольку дата была изменена с 10-го на 15-е, в результате было добавлено 5 дней (24 * 5 * 60 * 60 * 1000). Это означает, что для получения корректного результата вы должны рассчитывать даты на основе местного смещения часового пояса относительно часового пояса UTC.
Проблемы на этом не заканчиваются. Вот еще одна, где вы не получите желаемое значение, просто добавив или вычтя смещения часового пояса. Поскольку 12 марта является датой начала летнего времени по местному времени Нью-Йорка, смещение часового пояса 15 марта 2017 г. должно быть -04:00, а не -05:00. Поэтому, когда вы отключаете преобразование, вы должны добавить 780 минут, что на 60 минут меньше, чем раньше.
const time = ny.getTime() + (780 * 60 * 1000); // 1489627800000
Напротив, если местным часовым поясом пользователя является Нью-Йорк и он хочет узнать время в Сеуле, нет необходимости применять летнее время, что вызывает другую проблему.
Проще говоря, вы не можете использовать только полученное смещение для выполнения точных операций в зависимости от выбранного вами часового пояса. Если вы вспомните то, что мы обсуждали в предыдущей части этого документа, вы поймете, что в этом преобразовании все еще есть дыра, при условии что вы помните правила летнего времени. Чтобы получить точное значение, вам нужна база данных, содержащая всю историю изменений смещения часового пояса, например База данных часовых поясов IANA.
Чтобы решить эту проблему, необходимо сохранить всю базу данных часовых поясов и всякий раз, когда данные о дате или времени извлекаются из объекта Date, найти дату и соответствующее смещение часового пояса, а затем преобразовать значение, используя описанный выше процесс. Теоретически это возможно. Но на самом деле это требует слишком больших усилий, и проверка целостности преобразованных данных также будет сложной задачей. Но пока не расстраивайтесь. До сих пор мы обсуждали некоторые проблемы JavaScript и способы их решения. Теперь мы готовы использовать хорошо созданную библиотеку.
Moment timezone
Moment — это хорошо зарекомендовавшая себя библиотека JavaScript, которая является почти стандартом для обработки даты. Предоставляя различные API-интерфейсы для дат и форматирования, в последнее время многие пользователи признают moment стабильным и надежным. И есть модуль расширения Moment Timezone, который решает все проблемы, описанные выше. Этот модуль расширения содержит данные базы данных часовых поясов IANA для точного расчета смещений и предоставляет различные API-интерфейсы, которые можно использовать для изменения и форматирования часового пояса.
В этой статье я не буду подробно обсуждать, как использовать библиотеку или структуру библиотеки. Я просто покажу вам, насколько просто решить проблемы, которые я обсуждал ранее. Если кому-то интересно, см. Документацию Moment Timezone.
Давайте решим проблему, показанную на картинке, с помощью Moment Timezone.
const seoul = moment(1489199400000).tz('Asia/Seoul');
const ny = moment(1489199400000).tz('America/New_York');
seoul.format(); // 2017-03-11T11:30:00+09:00
ny.format(); // 2017-03-10T21:30:00-05:00
seoul.date(15).format(); // 2017-03-15T11:30:00+09:00
ny.date(15).format(); // 2017-03-15T21:30:00-04:00
Как вы видите в результате, смещение seoul останется прежним, в то время как смещение ny было изменено с -05:00 на -04:00. И если вы используете функцию format(), вы можете получить строку в формате ISO-8601, которая точно применила смещение. Видите насколько это просто по сравнению с тем, что мы делали ранее.
Заключение
До сих пор мы обсуждали API-интерфейсы часовых поясов, поддерживаемые JavaScript, и их проблемы. Если вам не нужно вручную изменять местный часовой пояс, вы можете реализовать необходимый функционал даже с помощью базовых API-интерфейсов при условии, что вы используете Internet Explorer 9 или выше. Однако, если вам нужно вручную изменить местный часовой пояс, все становится очень сложным. В регионе, где нет летнего времени и политика часовых поясов практически не меняется, вы можете частично реализовать ее, используя getTimezoneOffset() для преобразования данных. Но если вам нужна полная поддержка часовых поясов, не создавайте ее с нуля. Лучше используйте такую библиотеку, как Moment Timezone.
Я сам пытался реализовать часовой пояс, но у меня ничего не вышло, что неудивительно. Вывод здесь после нескольких неудач — лучше использовать библиотеку. Когда я впервые начал писать эту статью, я не знал, о каком выводе собираюсь написать, и вот мы здесь. В заключение я бы сказал, что слепое использование внешних библиотек без знания того, какие функции они поддерживают в JavaScript и какие у них проблемы, плохая идея. Как всегда, важно выбрать правильный инструмент для вашей ситуации. Надеюсь, эта статья помогла вам принять собственное решение.
Заключение от переводчика
Очевидно, здесь повествование обрывается, и хотелось бы углубиться в особенности различных библиотек для работы с датами в JS, в частности в Moment.JS, Luxon и Date FNS. Возможно в дальнейшем здесь появится ссылка на статью посвященную этим библиотекам.
Благодарю за помощь в подготовке перевода Степана Омельченко и Марию Пилипончик. Это было не просто, но мы смогли!
← →
Ega23 ©
(2005-06-01 17:19)
[0]
Можно ли получить значение DateTime (или другого типа) более точное, чем одна миллисекунда?
Например, завязаться на такты процессора?
Задача такая: с внешнего устройства приходит событие. Нужно чётко определить его время в рамках операционки.
← →
Kerk ©
(2005-06-01 17:22)
[1]
rdtsc или GetTickCount ?
← →
Суслик ©
(2005-06-01 17:24)
[2]
Посмотри
QueryPerformanceCounter и QueryPerformanceFrequency
может чем поможет
← →
Ega23 ©
(2005-06-01 17:25)
[3]
GetTickCount — это с точностью до миллисекунды. А точнее можно?
Пусть даже не на WinAPI, а на уровне ядра?
← →
Ega23 ©
(2005-06-01 17:26)
[4]
rdtsc — это чьё? Как ей пользоваться, например на asm-е?
← →
Kerk ©
(2005-06-01 17:27)
[5]
Ega23 © (01.06.05 17:26) [4]
так и пользоваться
asm
rdtsc
end;
возвращает в edx:eax кол-во тактов с момента старта процессора
← →
REA
(2005-06-01 17:34)
[6]
Таймер все равно кривой абсолютный — сползет. И тот что в биосе получше, но тоже сползет. Лучше внешние железные часы. И опять же 1мс довольно сложно обеспечить в течение длительного промежутка времени даже с термокомпенсацией. А в чем задача в целом?
← →
ferr ©
(2005-06-01 17:37)
[7]
function RDTSC:int64;
asm
RDTSC;
end;
var
c1,c2:int64;
q:integer;
begin
C1:=RDTSC;
sleep(1000);
c2:=RDTSC;
writeln((c2-c1)/Mhz);
readln;
Может и наврал 
← →
raidan ©
(2005-06-01 17:40)
[8]
>ferr © (01.06.05 17:37) [7]
rdtsc — крут, но если у мя A64 и включен Q»n»Q?
Частота процессора плавает в зависимости от нагрузки…
← →
ferr ©
(2005-06-01 17:53)
[9]
А я чё, я Kerk»a дополнил.
← →
pasha_golub ©
(2005-06-01 17:58)
[10]
Юзать QNX ;0)
← →
Ega23 ©
(2005-06-02 10:00)
[11]
Вообще задача следующая (это папик ко мне за советом обратился):
Есть внешняя измерительная установка — всякие детекторы, предусилители и т.п. Ожидаемое количество событий (интенсивность излучения) — порядка 20 — 30 событий в секунду. Т.к. измерение проходит в низко-энергетической области, то начинает наводки давать микрофоника (висит провод, по нему ток идёт, между проводом и землёй — ёмкость получается. При малейшем колебании провода имеем изменение ёмкости).
Микрофонику можно «отсечь», поскольку известны характеристики сигнала. Но для этого надо привязаться ко времени и сделать достаточно быструю дискретизацию сигнала. Вот здесь и встаёт вопрос о каком-то генераторе отсчётов. В принципе, у бати есть внешний генератор, как раз для CAMAC-а. Беда в том, что этот гад сам микрофонику свою дополнительную даёт. Поэтому надо попробовать привязаться к компу — может так лучше получится?
← →
Jeer ©
(2005-06-02 10:13)
[12]
Платформа w2k дает возможность работать в режиме «мягкого» real-time на уровне системного кванта 10 ms.
В случае твоего «папика» имеет смысл использование PCI-карты АЦП или внешнего АЦП.
В этом случае буферится массив измерений, а из операционки с дискретом 10-20 мс он считывается по необходимости.
Если уйти на уровень DOS, то можно работать спокойно с прерываниями.
← →
REA
(2005-06-02 11:34)
[13]
QNX неплохо справляется с real-time задачами. Я под него систему сбора информации писал. А обязательно этот провод, который между землей висит делать? Может железную схему компенсации сигнала сделать?
← →
Ega23 ©
(2005-06-02 11:37)
[14]
QNX неплохо справляется с real-time задачами. Я под него систему сбора информации писал. А обязательно этот провод, который между землей висит делать? Может железную схему компенсации сигнала сделать?
Это любой провод так работать будет. Шлейф в компе, например. Малейшая вибрация корпуса (топнул в комнате кто-то сильно) — провод задёргался — пошла наводка. Экранирование, конечно, помогает, но всё не заэкранируешь.
Про QNX знаю, сами используем. Но там — не прокатит.
← →
REA
(2005-06-02 12:27)
[15]
Ну есть мультимедийные еще таймера — можно попробовать их использовать. А нельзя измеритель без проводов подключить? Или это другой провод какой то не связанный с измерениями. Насчет быстрой дискретизации — тоже выход. Мы недавно делали съем данных с L-Card АЦП — втыкается в USB порт, пример работы есть на Delphi, буфер там приличный, время нарезанное по внутреннему таймеру.
← →
Ega23 ©
(2005-06-02 12:46)
[16]
А нельзя измеритель без проводов подключить?
А как ты себе это представляешь? В любой установке — масса проводов.
← →
Jeer ©
(2005-06-02 12:59)
[17]
Ega23 © (02.06.05 12:46) [16]
Значит надо переходить на передачу более мощным аналоговым сигналом или вооще переходить на цифру,например, использовать ШИМ- или ЧИМ- сигнал.
← →
REA
(2005-06-02 13:10)
[18]
Ну как представляю: плата с АЦП размером с коробок с микроконтроллером. Можно даже с аккумулятором, чтобы питание не тащить. А от нее уже сигнал в цифре, можно по радиоканалу. Думаю готовых таких тоже навалом со стандартными протоколами.
← →
Ega23 ©
(2005-06-02 13:17)
[19]
Ну как представляю: плата с АЦП размером с коробок с микроконтроллером. Можно даже с аккумулятором, чтобы питание не тащить. А от нее уже сигнал в цифре, можно по радиоканалу. Думаю готовых таких тоже навалом со стандартными протоколами.
Есть такая штука — CAMAC — фактически внешняя шина. В него контроллеры пихать можно. Всё это к компу подсоединяется.
← →
REA
(2005-06-02 14:37)
[20]
Кинь ссылочку плз. — авось пригодится. А часов у нее нет своих?
← →
REA
(2005-06-02 14:38)
[21]
Если это вот это:
http://www.lecroy.com/lrs/appnotes/introcam/introcam.htm
то не надо кидать, я ядреной физикой не занимаюсь (к сожалению).
← →
Ega23 ©
(2005-06-02 14:40)
[22]
Кинь ссылочку плз. — авось пригодится. А часов у нее нет своих?
Да это крейт здоровый, в пол-комнаты. Туда блоки вставляешь. Есть блок — счётчик (фактически — часы). Но, как я уже писал выще, сам этот блок производит довольно большую наводку, которая в рамках данного эксперимента неприемлема.
Поэтому ищутся обходные пути. Один из вариантов — в качестве генератора использовать процессор компа.
← →
Jeer ©
(2005-06-02 15:06)
[23]
Ega23 © (02.06.05 14:40) [22]
Комп тоже не слабо фонит.
Я использовал PCI-карты ADLink с гальванической развязкой.
← →
Ega23 ©
(2005-06-02 15:15)
[24]
2 Jeer © (02.06.05 15:06) [23]
Да комп-то может достаточно далеко от установки стоять…
В общем, батя ветку посмотрел, сказал, что
Kerk © (01.06.05 17:27) [5] — именно то, что ему нужно.
← →
REA
(2005-06-02 16:19)
[25]
Да ну нафиг — какие такты?: когда твоему потоку процессор время даст, тогда и засечешь. А если он отвлекся на свапование, то извини подвинься.
← →
Jeer ©
(2005-06-02 17:32)
[26]
Ega23 © (02.06.05 15:15) [24]
Неверно.
← →
Ega23 ©
(2005-06-02 19:10)
[27]
2 Jeer © (02.06.05 17:32) [26]
Пушшай сам разбирается.
← →
Jeer ©
(2005-06-02 19:27)
[28]
Как-что, так бате отдуваться ?:)
← →
Ega23 ©
(2005-06-02 19:33)
[29]
Как-что, так бате отдуваться ?:)
Есть у меня некоторое подозрение, что всё это будет под DOS-ом реализовано…
← →
Просто Джо ©
(2005-06-02 19:34)
[30]
> [29] Ega23 © (02.06.05 19:33)
> Есть у меня некоторое подозрение, что всё это будет под
> DOS-ом реализовано…
Да оно и к лучшему, имхо.
← →
Jeer ©
(2005-06-02 19:47)
[31]
Вечный DOS.:)
← →
Ega23 ©
(2005-06-02 19:50)
[32]
Вечный DOS.:)
Там прерывания захватить можно :о)
Время — это величина различных измерений, использующаяся для обозначения последовательности событий, например, чтобы сравнить их продолжительность или интервалы между ними. Время также нужно для количественной оценкой скорости изменения в количествах материальной реальности и сознательном опыте. Оно часто упоминается как четвертое измерение наряду с тремя другими.
Время в разных науках
Время очень долго было важным предметом изучения религией, философией и физикой, но оно имеет такое определение, что применимо ко всем областям без циркулярности. Тем не менее, различные сферы деятельности человека, такие как бизнес, промышленность, спорт, наука и исполнительское искусство включают некоторое понятие времени в свои соответствующие измерительные системы.
Время в физике однозначно определяется как «то, что читают часы». Оно является одной из семи фундаментальных физических величин как в Международной системе единиц (СИ), так и в Международной системе количеств.
Время используется для определения других величин, таких как скорость, поэтому определение в терминах приведет к цикличности. Обычное определение времени гласит, что за одну стандартную единицу времени можно зафиксировать циклическое событие, такое, как колебание маятника. Оно очень полезно как в повседневной жизни, так и в разных экспериментах.
Временное измерение и история
В целом методы временного измерения, или хронометрия принимают две различные формы: календарь — математический инструмент для организации интервалов времени, а также часы — физический механизм, который считает ход времени.
В повседневной жизни часы стандартно учитываются в течение периодов, которые меньше суток, а календарь — в течение периодов, превышающих один день. Персональные электронные устройства все чаще отображают и календари, и часы одновременно.
Число (как на циферблате часов или календаре), которое отмечает возникновение определенного события относительно часа или даты, получается путем подсчета с проверочной эпохи — центральной контрольной точки.
История приборов измерения времени
Для измерения времени было изобретено большое количество разных устройств. Исследование этих устройств называется хорологией.
Египетское устройство, которое датируется 1500 г. до н. э., похоже по форме на изогнутый Т-квадрат. Оно измеряло ход времени от тени, отбрасываемой перекладиной по нелинейному правилу. «Т» был ориентирован на восток по утрам. В полдень устройство располагалось так, что оно могло отбрасывать свою тень в вечернем направлении.
Положение тени отмечает час по местному времени. Идея разделить день на более мелкие части приписывается египтянам благодаря их солнечным часам, которые действовали по двенадцатеричной системе. Важность числа 12 была обусловлена количеством лунных циклов в году и количеством звезд, используемых для подсчета прохождения ночи.
Абсолютное время
Абсолютное пространство и время — это понятие в физике и в философии о свойствах вселенной. В физике абсолютное пространство и время могут быть предпочтительной структурой.
До Ньютона вариант концепции абсолютного пространства (предпочтительной системы отсчета) можно видеть в физике Аристотеля.
Роберт С. Вестман пишет, что понятие абсолютного времени можно наблюдать в классической работе Коперника De revolutionibus orbium coelestium, где тот использует концепцию неподвижной сферы звезд.
Ньютон
Изначально представленные сэром Исааком Ньютоном в Philosophiæ Naturalis Principia Mathematica концепции абсолютного времени и пространства послужили теоретической основой. Она облегчила ньютоновскую механику.
Согласно Ньютону, абсолютное пространство и время являются независимыми аспектами объективной реальности.
Абсолютное и относительное время из-за своей собственной природы течет одинаково независимо от чего-либо внешнего и по-другому называется продолжительностью: относительное, кажущееся и общее время — это некая разумная и внешняя (точная или нечеткая) мера продолжительности, которая обычно используется вместо истинного времени.
Отличия от относительного времени
Также Ньютон ввел понятие абсолютного времени. Оно существует независимо от любого воспринимающего и прогрессирует с постоянной скоростью по всей Вселенной. В отличие от относительного времени, Ньютон считал, что абсолютное время незаметно и может быть понято только математически.
Согласно Ньютону, люди способны воспринимать только относительное время. Оно является измерением воспринимаемых объектов в движении (например, Луны или Солнца). Из этих движений можно вывести ход времени.
Абсолютное пространство по своей природе, независимо от чего-либо внешнего, всегда остается подобным и неподвижным. Относительное пространство — это некоторая подвижная размерность или мера абсолютных пространств, которые наши чувства определяют своим положением по отношению к телам и которые вульгарно воспринимаются как неподвижное пространство… Абсолютное движение — это перевод тела из одного абсолютного места в другое, а относительное движение — перевод из одного относительного места в другое.
Исаак Ньютон
Что подразумевал Ньютон?
Эти понятия подразумевают, что абсолютное пространство и время не зависят от физических событий, но являются фоном, или сценой, в которой они и происходят. Таким образом, каждый объект имеет абсолютное состояние движения относительно абсолютного пространства, так что объект должен находиться либо в состоянии абсолютного покоя, либо двигаться с некоторой абсолютной скоростью. Чтобы поддержать свои взгляды, Ньютон привел несколько эмпирических примеров.
Согласно Ньютону, можно предположить, что вращающаяся одиночная сфера вращается вокруг своей оси относительно абсолютного пространства, наблюдая выпуклость ее экватора, и одиночная пара сфер, связанных между собой, вращается вокруг своего центра тяжести (барицентр), наблюдая за натяжением каната.
Абсолютное время и пространство продолжают использоваться в классической механике, но современные формулировки авторов, таких как Уолтер Нолл и Клиффорд Трусделл выходят за рамки линейной алгебры и упругих модулей для использования топологии и функционального анализа для нелинейных теорий.
Иные взгляды
Исторически сложились разные взгляды на концепцию абсолютного пространства и времени. Готфрид Лейбниц считал, что пространство не имеет смысла, кроме как относительное расположение тел, а время не имеет смысла, кроме как относительно движения тел.
Джордж Беркли предположил, что, не имея какой-либо точки отсчета, сфера в пустой Вселенной не может быть представлена как вращающаяся, а пара сфер может быть представлена так, чтобы вращаться относительно друг друга, но не вращаться вокруг своего центра. Гравитация — пример, поднятый позже Альбертом Эйнштейном в его развитии общей теории относительности.
Более свежая форма этих возражений была высказана Эрнстом Махом. Принцип Маха предполагает, что механика целиком связана с относительным движением тел, и, в частности, масса является выражением такого относительного движения. Например, одна частица во Вселенной без других тел будет иметь нулевую массу. Согласно Маху, примеры Ньютона просто иллюстрируют относительное вращение сфер и объем Вселенной.
Информация вращается вокруг времени, как живой организм. То, что важно в этом году, будет не настолько весомо через несколько лет. Поэтому важно присоединять к контенту временные метки. Но если вы будете использовать неправильный формат, то пользователям будет затруднительно их использовать.
Абсолютные и относительные временные отметки
Большинство сайтов использует два типа временных меток. Относительные метки отображают сколько минут, часов, дней, недель, или лет назад пост был опубликован. Абсолютные метки отображают точное время и дату его публикации.
Оба формата по-разному полезны. Но когда и какой стоит использовать? И как их отображать? Это определяет юзабельность ваших временных меток.
Когда использовать Абсолютные временные отметки
Иногда пользователям нужно поискать информацию в старом контенте. В этом случае, без абсолютных меток, пользователь не сможет выделить определенный период.
Сайты, на которых размещены фотографии, документы, сообщения, задачи, события — должны использовать абсолютные метки. В случае, если пользователь может извлекать выгоду из старого контента, нужно использовать абсолютные временные метки.
Дружественное форматирование
Преимущество абсолютных меток, над относительными заключается в том, что они показывают точные время и дату. Но эту информацию сложно интерпретировать, поскольку не все пользователи живут в одной временной зоне. Поэтому важно отображать абсолютные метки в дружественном формате.
Конвертирование временных зон
Проблема абсолютных меток заключается в том, что пользователям приходится конвертировать время контента в свое, местное. Это сбивает тех, кто живет в отличной, от времени вашего сервера временной зоне. Пользователи должны иметь возможность видеть правильное время без необходимости совершать дополнительные вычисления.
Представьте пользователя, который планирует событие, и не замечает разницу во временных зонах, или допускает ошибку при конвертации. Пользователь пропустит это событие, что может привести к неудобным последствиям. В этом контексте очень важно чтобы ваши абсолютные временные метки дружили с временными зонами. Этого можно добиться, оптимизируя ваш код таким образом, чтобы он определял, и отображал время пользователя, а не время сервера.
Начните с сохранения абсолютных меток на сервере в формате UTC. Для отображения времени пользователя вам понадобится знать смещение его временной зоны, чтобы вы могли добавить его значение в свою базу данных. Эти данные можно получить автоматически, используя Javascript Timezone Function.
Конвертирование суточного времени
Если ваши пользователи разбросаны по всему миру, то не все они используют одинаковые форматы времени. На заставляйте их конвертировать время в то, которое используют они.
Большинство англоговорящих стран используют 12-часовой формат времени в письменной и устной речи. Другие, используют 12-часовой в устной, и 24-часовой в письменной речи. Но большинство людей в странах, использующих 24 формат, настолько привыкли к обоим, что не испытывают трудностей с переходом.
Из-за этого, вам стоит по умолчанию использовать 12-часовой формат. Но если множество ваших пользователей предпочитают 24-часовой формат, то его можно показывать в качестве эффекта наведения указателя на временную отметку.
Чтение числовых форматов даты
Форматы времени — это не единственная проблема, с которой сталкиваются пользователи при чтении абсолютных отметок. Даты также могут причинить неудобство, если их отображать в числовом формате.
В разных странах порядок чисел в дате интерпретируется по-разному. Некоторые сначала используют день, некоторые — месяц, а некоторые сначала пишут год. Попытка в этом разобраться повышает когнитивную нагрузку, и может привести к ошибке.
Избегайте этого, используя прописной формат даты. Пропишите название месяца в полной форме, или в виде аббревиатуры, но не сокращайте год. Сокращенный год может быть спутан с датой. Со всем этим вам поможет Javascript Date Library.
Когда не стоит использовать абсолютные временные отметки
Вам не придется иметь дело со всеми этими проблемами, если вам не придется использовать абсолютные временные метки. Иногда относительные подходят лучше.
Если контент вашего сайта часто обновляется, или если на нем наблюдается высокая пользовательская активность, то стоит использовать относительные временные отметки. Сайты, публикующие новости, или на которых есть форумы, где пользователи постят ссылки и комментарии должен показывать непосредственность. Это позволяет пользователям быть в курсе новой информации по мере ее поступления.
Когда использовать относительные временные отметки
В относительных метках важна не точность, а сиюминутность. Когда пользователь хочет знать, когда был опубликован пост, он предпочитает прописную форму времени. Таким образом им не приходится в уме вычислять дату, время, и отсчитывать назад, от настоящего времени. Также, при использовании относительных отметок, пользователям не приходится ориентироваться по временным зонам.
Дружественное форматирование
Вам стоит знать о нескольких проблемах форматирования относительных меток. Если в случае, с абсолютными метками мы имеем дело с проблемами интерпретации, то в случае, с относительными, мы имеем дело с умственной работой.
Адаптивные единицы времени
Проблемы с относительными временными метками начинаются, когда формат единиц времени не адаптируется под продолжительность. Вместо этого он показывает только небольшое количество временных единиц.
Например, сайт может отображать относительные отметки в виде минут, часов и дней. Но после дней ничего не следует. Пользователям может не понравится исчислять дни сотнями.
Ваши относительные метки всегда должны адаптироваться под продолжительность и отображаемые единицы времени. После 30 дней нужно показывать месяцы, после 12 месяцев — годы.
Точные единицы времени
Если ваш сайт публикует контент не в порядке представления, то пользователям будет сложно определить разницу, между временем публикаций. В этом случае вам следует либо использовать абсолютные отметки, либо включить в свои относительные отметки точные единицы времени.
Точные единицы времени объединяют разные единицы времени. Вместо того, чтобы округлять, отобразите часы и минуты. Это позволит пользователю лучше ощущать время, пройденное между публикацией постов.
Сокращения единиц времени
Относительные отметки, иногда, могут занимать больше места, чем вы для них можете выделить. Если вы отображаете их в ограниченном пространстве, вроде контентной карточки или мобильного сайта, то вам стоит использовать сокращения.
Используйте стандартные сокращения, которые пользователь сможет распознать. Вот таблица стандартных сокращений для каждой временной единицы.
Автоматическое обновление
Когда пользователь впервые просматривает веб-страницу, то может понять, как давно был опубликован каждый пост. Но только что проставленная временная метка «2 минуты назад», со временем будет утрачивать свою актуальность.
Это происходит потому, что большинство относительных временных меток не обновляются автоматически. Чтобы получить точную отметку пользователям приходится обновлять страницу. Если вы хотите предоставить пользователям точные относительные отметки времени, то используйте этот jQuery Plugin.
Когда не стоит использовать относительные временные отметки
В некоторых случаях относительные отметки не так эффективны, как абсолютные. Когда пользователь хочет сослаться на пост, это проще сделать с абсолютной отметкой, поскольку она отображает определенное время.
Еще один недостаток относительных отметок заключается в том, они усложняют измерение разницы во времени. Пользователь не сможет посмотреть сколько времени прошло между публикацией разных постов. Это важно в контексте месседжинга, вроде чата, e-mail, и т.п.
Когда нужно комбинировать относительные и абсолютные временные отметки
У каждого типа временных отметок есть свои преимущества, и вы можете получить все эти преимущества комбинируя их. Если ваш сайт часто обновляется, и вы к тому же, публикуете старые архивы, то вам стоит комбинировать временные отметки.
Дружественное форматирование
Проблема комбинирования заключается в определении правильного момента их конвертирования и выделения необходимого для них экранного пространства.
Линейное отображение
Простой способ комбинирования — выстраивание их в одну линию. В первую очередь можно отобразить абсолютную отметку, а рядом, в скобках, разместить относительную.
Абсолютная отметка включает в себя время и дату. Линейное отображение может занять много места. Сохранить его можно показывая то, что важно в данный момент, убрав лишнее.
Чтобы сохранить место, сначала отобразите время, но по прошествии 24 часов, замените его на дату. Чтобы сохранить еще больше места, исключите год, и отобразите полную дату только по его прошествии.
Автоматическая конверсия
Еще один способ заключается в конвертировании относительных отметок в абсолютные по прошествии времени. Вы можете настроить сайт таким образом, чтобы абсолютная отметка заменяла относительную, когда возраст поста переходит определенную границу.
Например, если пост старше четырех недель, то будет отображаться время и дата публикации. Это позволяет изящную самоархивацию контента, которая будет полезна для больших сайтов.
Подсказки во временных отметках
Если вы хотите отобразить оба формата отметок, но при этом хотите сохранить место — используйте подсказки. Когда пользователь будет наводить указатель мыши на относительную отметку, абсолютная будет появляться в подсказке.
Но пользователь не сможет понять, что если он наведет мышь на время, то увидит абсолютное значение до тех пор, пока вы не дадите ему визуальную подсказку. Можно использовать пунктирное подчеркивание, чтобы это обозначить. Или можно рядом со временем разместить значок часов, при наведении на который будет отображаться подсказка.
Заключение
Время — это универсальная концепция, стоящая над культурными барьерами. Каждый пользователь понимает время, но не каждый поймет вашу временную отметку, если она использует неподходящий формат. Практики и техники этой статьи должны помочь вам найти подходящий. Пора начать обращаться с временными отметками не просто как с отметками.















