Нормализовать дату UTC - PullRequest
0 голосов
/ 19 марта 2019

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

 /**
 * To make it easy to query for the exact date, we normalize all dates that go into
 * the database to the start of the day in UTC time.
 *
 * @param date The UTC date to normalize
 *
 * @return The UTC date at 12 midnight
 */
 public static long normalizeDate(long date) {
    // Normalize the start date to the beginning of the (UTC) day in local time
    long retValNew = date / DAY_IN_MILLIS * DAY_IN_MILLIS;
    return retValNew;
}

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

Ответы [ 2 ]

2 голосов
/ 20 марта 2019

В Java и других языках программирования момент времени иногда представляется в виде количества миллисекунд, начиная с так называемой эпохи от 1 января 1970 года в 00:00:00 UTC, исключая високосные секунды. Как говорится в комментарии, ваш метод берет такое число и преобразует его в начало дня (полночь) в UTC. Например, значение long, представляющее 20 марта 2019 года в 09:22:43 UTC, будет преобразовано в значение, представляющее 20 марта 2019 года в 00:00:00 UTC. Если бы значение предназначалось только для представления даты, а не времени суток, с самого начала, я бы сказал, что описывать это как «нормализацию» имеет смысл.

Как это работает? date, переменная long, содержащая миллисекунды, сначала делится на количество миллисекунд в дне (я полагаю; я читаю DAY_IN_MILLIS как « 1 день в миллисекундах »). Это дает число дней с начала эпохи. Остаток от подразделения отбрасывается; Вы получаете только целые дни. Затем при повторном умножении на DAY_IN_MILLIS вы переводите обратно в миллисекунды. Поскольку эпоха была определена как 00:00:00 в этот день, вы получаете 00:00:00 UTC в тот же день, что и с начала. Это работает, поскольку UTC не имеет летнего времени (DST) и других временных аномалий (оно не будет работать в часовых поясах, которые имеют).

И я признаю, что бит «по местному времени» для меня тоже не имеет смысла. Я полагаю, что это никогда не имело никакого смысла.

Позвольте мне добавить, что это плохой код , хотя (даже если вы не спрашивали), что я также вижу в качестве причины, по которой вам нужно было спросить. Использование количества миллисекунд с начала эпохи, как правило, не рекомендуется, а преобразование в начало дня лучше выполнять через стандартный API. Представление момента времени в виде миллисекунды является низкоуровневым и недружественным для человека. Просматривая число, например 1553074048964, в своем отладчике или журнале, вы, как правило, понятия не имеете, верно это или нет. Вместо этого следует использовать Instant, или для даты без времени дня, а LocalDate. Instant печатает как например 2019-03-20T09:28:54.729Z. Время указано в UTC, но даже если вы находитесь в другом часовом поясе, нетрудно понять, правильно это или нет. Instant и LocalDate - это классы из java.time, современного Java-API даты и времени. Этот API также имеет методы для всех видов операций с датой и временем, включая преобразование в начало дня.

Ссылка: Обучающее руководство по Oracle: Дата и время , объясняющее, как использовать java.time.

0 голосов
/ 19 марта 2019

Я полагаю, что DAY_IN_MILLIS равен 86400000

Поскольку дата является целым числом long , при делении на DAY_IN_MILLIS вы получите взамен long integer без десятичной части.

Поэтому после умножения на DAY_IN_MILLIS вы получите другое число, округленное до кратного 86400000.

2 дат, принадлежащих одному и тому же Дню UTCбудет иметь то же значение.

пример для математики

( 1 / 10 ) * 10   => 0 

( 9 / 10 ) * 10   => 0 

( 11 / 10 ) * 10   => 10

( 19 / 10 ) * 10   => 10
...