Evolcom.ru

Бытовая техника
0 просмотров
Рейтинг статьи
1 звезда2 звезды3 звезды4 звезды5 звезд
Загрузка...

Как получить текущий часовой пояс и отобразить его в ячейке Excel?

Разбираемся в часовыми поясами. Инструкция по безопасной работе со временем

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

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

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

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

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

Разработка велась в Лондоне, и зона не учитывалась, поэтому код писался без ее учета. В результате разработчик с зоной +3 столкнулся с тем, что ни один из его тестов не прошел, так как планируемое время не включало его зону. В результате коллега сидел с прибитыми часами целый год. В итоге оказалось проще локально изменить зону, чем исправлять код.

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

В нашем проекте руководитель проекта решил, что он умнее системы и должен помочь клиенту перевести местное время в UTC. И при этом он заложил в систему подлый жучок. Когда объект Date отправляется с помощью Ajax, первый автоматически обновляется до глобального времени. Затем был активирован приятельский куратор, также корректирующий часовой пояс. Оказалось, что мы дважды вычитали местное время на клиенте и таким образом испортили любую дату на сервере.

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

Количество времени, доступного для фронтендеров, очень плохое. Из-за того, что время — это скорее серверный компонент приложения, оно требует определенной подготовки и продуманности. Чаще всего виноваты ошибки на стороне клиента.

Читайте так же:
Как перемещать ячейки из горизонтального положения в вертикальное или наоборот?

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

Хорошей практикой является избегание преобразований на месте в бизнес-логике. Лучше создать отдельный модуль и наполнить его вспомогательным кодом. Логично, что если окажется, что где-то интервал нужно было убрать, а не добавить, то проще будет исправить одну функцию, чем анализировать весь проект.

Лучше сразу получить достойную библиотеку стороннего производителя, чем ждать. Концепция времени настолько сложна, что лишь немногие языки могут похвастаться качественной реализацией, которую можно было бы упаковать в коробку. В Javascript нет ничего пошлого в объекте Date. В Java класс java.util. Date был устаревшим с версии 1.1, почти сразу же. Родной datetime в Python приемлем только для базовых задач.

Нет причин думать: «Я просто хочу написать обертку», но не нужно быть зависимым. Время — это важно. Пусть будут зависимости, но меньше ошибок.

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

Линии между часовыми поясами не проходят точно по прямой, как полосы на арбузе. Несколько лет назад Россия изменила свои часовые пояса, объединив и разделив соседние. Так, благодаря усилиям Медведева, в моем родном городе Чите зимой в 4 часа дня уже было темно как ночью. Но для простоты предположим, что зоны распределены равномерно).

Следовательно, «позвони мне в три часа» глобально ничего не значит. Чье время 3:00? Московское? Нью-Йоркское? Необходим специальный маркер, чтобы указать, откуда взято это время. Для перевода времени из одной метки в другую можно использовать простые вычисления. Эта метка называется часовым поясом.

Это может быть смещение в часах (+03:00), название города с косой чертой (Europe/Berlin) или аббревиатура (CET, Central European Time), но это уже тонкости стандартов кодирования. Важно то, что время теперь зависит от местоположения и может быть преобразовано в универсальное время UTC.

UTC — Universal Time Coordinated — это современный стандарт отсчета времени, который пришел на смену GMT. Мы не будем здесь обсуждать его характеристики, но достаточно сказать, что он действует как ноль на шкале зон: от него отсчитываются отрицательные (западные) и положительные (восточные) зоны.

Читайте так же:
Как посчитать количество ячеек с комментариями в Excel?

Например, я живу в Воронеже, мой пояс — третий восточный, поэтому я могу написать в резюме «при звонке учитывайте мой часовой пояс +3 UTC» или просто «мой TZ — +3». Прибавив 3 часа к своему времени, клиент из Лондона, у которого нулевая зона, получит мое местное время.

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

Даты хранятся на сервере и в базе данных. Современные базы данных (далее PostgreSQL) предоставляют два типа полей: timestamp with timezone и timestamp without timezone. Если вы введете дату в первое поле с часовым поясом, база данных преобразует ее в UTC, так как это удобнее. Когда эта дата отображается в утилитах, она будет соответствовать местному времени пользователя, который в данный момент ее просматривает.

Я создал таблицу с двумя полями: время с часовым поясом и без него. Затем я вписал в поле часового пояса время с часовым поясом Нью-Йорка. В базе данных он будет храниться как 2017-12-13 15:00:00 UTC . Но при выходе я увижу в консоли время по моему местному времени. Это правильно, мой часовой пояс +3, дата была указана правильно.

А в поле ts нужно вводить только время UTC, иначе произойдет ошибка:

Это второе поле неверно: оно должно быть 15 часов вместо 18 по UTC. Вот как это должно было быть сделано:

Об этой и других ошибках речь пойдет ниже.

Различные библиотеки и ORM используют эту технику для восстановления таких дат в языковых объектах с часовым поясом (tz, zone, tzinfo и т.д.). ).

Даты без зон имеют право на существование, и это, конечно, проще, на мой взгляд. Вы просто соглашаетесь хранить все даты как местное время UTC в команде. Библиотека должна иметь методы и функции для работы с таким временем, например, такие как datetime.utcnow() в Python, moment.utc() в JS и т.д.

Клиент и сервер должны обмениваться друг с другом только датами UTC. Универсальное время конвертируется в местное время на стороне клиента на основе местного смещения от главного меридиана. Это значение можно определить с помощью метода .getTimezoneOffset() объекта Date на клиенте.

Чтобы отправить даты клиенту, вы кодируете их в формате ISO с указанием зоны. Z — это обозначение UTC. Таким образом, текстовое представление времени, отправляемое клиенту, будет выглядеть следующим образом:

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

Читайте так же:
Как предотвратить сохранение, если конкретная ячейка в Excel пуста?

Библиотека не может добавлять Z в конец даты, если у нее нет зоны, что может вызвать путаницу у клиента. Помните: добавьте в модуль функцию, которая добавляет Z к строке, и вызывайте только эту функцию (см. выше об унификации кодовой базы для времени).

На данный момент вы можете видеть только посредственность формата JSON: он не позволяет передавать даты и не является расширяемым.

В обратном направлении от клиента к серверу даты отправляются в том же формате: строка ISO в UTC с Z на конце в качестве зоны.

Примите во внимание, что клиент должен сделать с полученной строкой. Самый простой способ восстановить ее в объект — использовать библиотеку moment.js:

Мы видим, что все правильно: мой ремень +3, часы продвинулись на эту разницу, и индикатор в конце показывает +03:00.

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

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

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

При отправке тела JSON на сервер объект Data не нужно вручную преобразовывать в строку ISO. Для этого существует метод .toJSON(), который автоматически вызывается при кодировании внешнего словаря. Например:

Здесь рассмотрены основные ошибки при обработке времени и способы их устранения. Давайте начнем с сервера.

  • Тип поля — timestamp with time zone, но вы перемещаете временной объект без зоны.

В этом случае сервер подставит текущую зону, то есть ту, в которой находится сервер. Если пользователь находится далеко, например, на другом континенте, это может вызвать значительные неудобства. Пользователь в Нью-Йорке (-5 UTC) отправляет на сервер время «2017-12-12T14:20:00Z». (+1 UTC) Сервер находится в Швейцарии. Часовой пояс был отброшен, поэтому вместо «2017-12-12T23:20:00 UTC» (оригинал плюс 5 часов) было написано «2017-12-12T13:20:00 UTC» (оригинал минус 1 час). Ошибка в 10 часов! Это похоже на напоминания в путешествиях или СМС.

  • Поле типа timestamp без временной зоны, но в базе данных хранится на сервере локального времени.
Читайте так же:
Как переместить определенные файлы из одной папки в другую в Excel?

Для получения текущего времени обязательно используйте функцию с utc в названии, например, datetime.utcnow() вместо datetime.now() и аналогичных функций в других языках. В PostgreSQL все аналогично: вы должны указывать поле UTC почти для всех вызовов функции времени. Сравнить

Для перемещения зоны из одной базы данных в другую можно использовать следующий оператор:

Функции Google Таблиц для работы с датой и временем

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

Во втором столбце скриншота показан результат работы формулы, а в третьем — текст формулы.

Далее я рассмотрю каждую функцию отдельно. В качестве альтернативы можно указать дату непосредственно в формуле в формате «01.02.2015» или ссылку на ячейку, содержащую единицу в качестве даты.

Функция TODAY (СЕГОДНЯ)

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

Функция СЕЙЧАС (TDATA).

Возвращает текущее время и дату. Аргументы также отсутствуют. При отсутствии форматирования ячейка отобразит оба значения:

2

А если в качестве формата используется время, ячейка содержит только текущее время:

3

Вверху — неформатированная ячейка, внизу — отформатированная по времени.

Функция NETWORKDAYS (ЧИСТРАБДНИ)

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

Первое октября 2015 и 18 февраля 2016 — 101 рабочий день.

Кроме того, даты можно устанавливать в формулах, но этот метод менее гибкий, чем изменение дат в ячейках — потому что его можно сделать быстрее:

Вы можете указать TODAY в качестве второго аргумента, и каждый день вы будете видеть текущее количество рабочих дней с заданной даты (аналогично, вы можете указать TODAY в качестве первого аргумента и отслеживать количество рабочих дней ДО заданной даты):

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

Самый простой способ сделать это — задать их в диапазоне, а затем ссылаться на этот диапазон в функции. Диапазон может выглядеть следующим образом:

8

Число рабочих дней увеличилось до 95.

Функция NETWORKDAYS.INTL (ЧИСТРАБДНИ.INTL)

Предыдущий вариант — определить нестандартную рабочую неделю. Это третий аргумент, который определяется как «0000011», где нули — дни недели, а единицы — выходные. Например, для шведской четырехдневной недели формула будет выглядеть следующим образом:

10

Продолжительность рабочего дня стала 77.

Функция рабочего дня

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

Читайте так же:
Как подсчитать совпадение ячеек с X или Y в Excel?

В данном примере мы обращаемся к ячейке B7, в которой указана дата 01.10.2015. Через 155 рабочих дней после этой даты наступит 5 мая.

Функции ДЕНЬ, МЕСЯЦ, ГОД

Вернуть соответствующий параметр из даты, которая является единственным аргументом функции:

В примере аргументом является сегодняшняя дата, которая задается функцией TODAY.

Функция WEEKNUM (НОМНЕДЕЛИ)

Возвращает номер недели. Первым аргументом является дата, а вторым, необязательным, — тип. По умолчанию тип равен 1, что означает, что воскресенье является первым днем недели; если вы установите тип аргумента равным 2, то первым днем недели будет понедельник.

13

Функция DATEDIF (РАЗНДАТ)

Она позволяет рассчитать количество дней, месяцев и лет между двумя датами.

14

Первые два аргумента — это начальная дата и конечная дата. Третий аргумент — это параметр, он имеет следующие опции:

М — это целый месяц;

Y — полные годы. В примере мы находим разницу между 1 октября 2015 года и 18 февраля 2016 года:

Хотя полный год еще не прошел, можно вычислить десятичную дробь года с помощью функции YEARFRAC (ЛЕТОФРАК).

Существует еще три варианта последнего аргумента D ATEDIF:

MD — количество дней после вычета целых месяцев (в примере это 17 дней между 01.01.2013 и 18.02.2016);

Y M — количество месяцев после вычитания полных лет (в примере — 1 месяц между 01.01.2013 и 18.02.2016)

YD — количество дней

После вычитания полных лет (в примере 48 дней с 01/01/2013 по 18/02/2016)

15

Функция ЭОМОНТ

Возвращает последнюю дату месяца, следующего за заданной датой через заданное количество месяцев. Например

Возвращается 30 апреля 2016 года в февраль (апрель — это два месяца после февраля):

16

Если к общей формуле добавить единицу, то получится первый день следующего месяца, что также может быть полезным:

17

Функция «Недельный день

Возвращает индексный номер дня недели указанной даты (первый аргумент). Этот аргумент также имеет тот же тип, что и WEEKNUM. В случае недели, начинающейся в понедельник, тип = 2:

18

Если аргумент type = 1, четверг станет пятым днем недели, как показано на снимке экрана:

четверг

Последний набор функций включает в себя работу со временем. ВРЕМЯ

Преобразует заданные часы, минуты и секунды (это ее аргументы) во время. Аргументы, конечно, могут быть указаны внутри функции или в виде ссылок на ячейки.

Секунда, минута и время

Возвращает эквивалентное значение из даты. На скриншоте выше видно, что я поймал его в 22 часа, 22 минуты и 27 секунд — потому что все три функции имеют в качестве аргумента текущее время — NOW().

голоса
Рейтинг статьи
Ссылка на основную публикацию
Adblock
detector