Почему Java.Time.Year произвольно ограничен менее чем примитивными пределами? - PullRequest
0 голосов
/ 11 декабря 2018

На странице документа Java 8 для Java.Time.Year указано, что минимальный и максимальный поддерживаемые годы составляют -999 999 999 и 999 999 999 соответственно.

Сводка по полю

static intMAX_VALUE Максимальный поддерживаемый год, '+999,999,999'.

static int MIN_VALUE Минимальный поддерживаемый год, '-999,999,999'.


Однакопеременная примитивного типа, в которой хранится значение года, представляет собой int , которая должна сохранять от -2 147 483 648 до 2 147 483 647.

/**
 * The year being represented.
 */
private final int year;

Почему существуют эти произвольные ограничения?

1 Ответ

0 голосов
/ 12 декабря 2018

Причина использования 999 999 999 не связана с какой-либо конкретной проблемой с реализацией синтаксического анализа в коде.

Вероятно, он был выбран, поскольку это максимальное значение любого числа, которое состоит из 1 до 9 цифр.Мы не можем хранить полный набор лет до 10 цифр с помощью INT, поскольку 9 999 999 999 (и, честно говоря, еще 79% возможных 10-значных чисел) не могут быть сохранены в целом числе.Важно отметить, что сам форматтер может беспрепятственно поддерживать отдельные номера длиной до 64 цифр и использует только MIN / MAX для проверки ошибок.Если бы Min / Max были повышены до INT_MIN и INT_MAX, он все равно работал бы без проблем.Значения, превышающие INT_MAX, будут корректно генерировать ошибку и предотвращать любые проблемы, связанные с целочисленным переполнением, поэтому нет никаких проблем в отношении какого-либо сбоя синтаксического анализа.

    ISO_LOCAL_DATE = new DateTimeFormatterBuilder()
            .appendValue(YEAR, 4, 10, SignStyle.EXCEEDS_PAD)
            .appendLiteral('-')
            .appendValue(MONTH_OF_YEAR, 2)
            .appendLiteral('-')
            .appendValue(DAY_OF_MONTH, 2)
            .toFormatter(ResolverStyle.STRICT, IsoChronology.INSTANCE);

Год - это либо 4 числа для традиционного ISO, то есть 0-9999или имеет +/-, т. е. +999999 для 999999 года.

Следует отметить, что средство форматирования ISO_LOCAL_DATE принимает 10-значные годы по умолчанию, исключая знак +/-, поэтому значение +9,876,543,210 равнофактически правильно проанализирован, но превышает допустимые значения для MAX_YEAR.

Text '+9876543210-10-31' could not be parsed: Invalid value for Year (valid values -999999999 - 999999999): 9876543210

Все в DateTimeFormatterBuilder поддерживает до 64 цифр, анализируя цифру за раз.Все эти значения безопасно анализируются как BigIntegers и тщательно умножаются на 10 при перемещении индекса вправо, а по завершении преобразуются и сохраняются в контексте синтаксического анализа, состоящем из имен полей и длинных значений, даже если поля Месяцы и Дни могут быть явно сохраненыкак INTS.Позднее они преобразуются обратно в связанные с ними примитивы.

На практике DateTimeFormatterBuilder определенно может использовать 2,147,483,647 в качестве допустимого минимального / максимального года без разрывов.

Реально говоря, описание "Java"принимает любое значение года до 9 цифр "представляет конкретный барьер, в котором нет шансов переполнения целых чисел или путаницы при сложении двух лет вместе, и уменьшает любую возможную путаницу черного ящика в отношении того, почему год 2 100 000 000 работает, но 2 200 000 000 прекращается.

...