#java #datetime-format #java-time #datetimeformatter
#java #datetime-формат #java-время #datetimeformatter
Вопрос:
Из DateTimeFormatter
javadoc:
Если количество букв меньше четырех (но не двух), то знак выводится только для отрицательных лет в соответствии с SignStyle.NORMAL. В противном случае знак выводится, если ширина поля превышена, согласно SignStyle.EXCEEDS_PAD.
Насколько я понимаю, если ширина поля не превышена, а количество букв равно четырем, знак минус (для отрицательных лет) не должен печататься во время форматирования.
Итак, я написал такой фрагмент кода (полагая, что я не могу использовать « y
потому что тогда год всегда будет положительным):
var negativeDate = LocalDate.now().minus(2021, ChronoUnit.YEARS);
var formatter = DateTimeFormatter.ofPattern("ppppuuuu");
var text = negativeDate.format(formatter);
System.out.println("formatted string: " text);
Этот код выдает DateTimeException
: «Невозможно напечатать, поскольку вывод 5 символов превышает ширину 4«.
Итак, мой вопрос в основном заключается в том, как увидеть это последнее предложение из работы javadoc.
Ответ №1:
Иначе в предложении, о котором вы спрашиваете, относится к ситуации, когда количество букв равно 4 или больше. Как ни странно, ширина поля здесь не имеет ничего общего с шаблонной буквой p
для заполнения. Это относится к количеству цифр, которые нужно напечатать. Это относится к первому предложению абзаца, количество букв определяет минимальную ширину поля, ниже которой используется заполнение.
Итак, чтобы увидеть эту работу, используйте 4 или более букв шаблона и используйте год, который содержит большее количество цифр, чем количество букв шаблона. Он работает с обоими u
, y
и Y
.
DateTimeFormatter uuuu = DateTimeFormatter.ofPattern("uuuu");
DateTimeFormatter yyyy = DateTimeFormatter.ofPattern("yyyy");
DateTimeFormatter uppercaseYyyy = DateTimeFormatter.ofPattern("YYYY");
LocalDate ld = LocalDate.of(12345, Month.OCTOBER, 23);
System.out.println(ld.format(uuuu));
System.out.println(ld.format(yyyy));
System.out.println(ld.format(uppercaseYyyy));
Вывод:
12345 12345 12345
Знак минус печатается независимо от количества печатаемых символов. В документации SignStyle.EXCEEDS_PAD
говорится:
… Отрицательное значение всегда будет выводить знак «-«.
Ссылка на документацию: SignStyle.EXCEEDS_PAD
Ответ №2:
Если количество букв меньше четырех (но не двух), то знак выводится только для отрицательных лет в соответствии с SignStyle.NORMAL.
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.time.temporal.ChronoUnit;
public class Main {
public static void main(String[] args) {
var negativeDate = LocalDate.now().minus(2021, ChronoUnit.YEARS);
var formatter1 = DateTimeFormatter.ofPattern("ppuu");
var formatter2 = DateTimeFormatter.ofPattern("ppu");
var text1 = negativeDate.format(formatter1);
var text2 = negativeDate.format(formatter2);
System.out.println("formatted string: year" text1);
System.out.println("formatted string: year" text2);
}
}
Вывод:
formatted string: year01
formatted string: year-1
Я использовал uu
(количество букв как два) в formatter1
, и поэтому он не показывает отрицательный знак. Однако, если количество букв меньше четырех, но не двух, вам необходимо предоставить достаточное заполнение, например, для года, -1
, вам нужно заполнение, по крайней мере 2
, (т.Е. pp
), один для -
знака и один для 1
. Если вы предоставите меньшее количество отступов, вы получите DateTimeException
, а если вы предоставите больше, чем 2
отступы, вы получите пробел раньше -1
.
Таким образом, в случае формата uuuu
вам нужно дополнение не менее 5
(т. Е. ppppp
) для отрицательного года, один для -
и 4
для лет ( 0001
), т. Е. Вам нужно использовать DateTimeFormatter.ofPattern("pppppuuuu")
, чтобы избежать DateTimeException
.
Комментарии:
1. это не отвечает на мой вопрос («как увидеть это последнее предложение из работы javadoc») — так что случай «в противном случае» с 4 буквами
Ответ №3:
Этот шаблон "ppppuuuu"
определяет padWidth
значение 4, применяемое к следующему формату uuuu
, который применяется SignStyle.EXCEEDS_PAD
(в соответствии с javadoc для DateTimeFormatBuilder
).
То -
есть всегда печатается из-за текущего SignStyle
.
Таким образом, когда форматировщик пытается напечатать отрицательный год, он использует 4 цифры и знак, таким образом, превышающий доступный padWidth
.
Аналогично, знак всегда печатается при использовании u
uuu
шаблонов или, потому SignStyle.NORMAL
что применяется в этих случаях.
Таким образом, знак не будет печататься только при uu
использовании format .
Чтобы избежать исключения для отрицательного числа, заполнение должно превышать количество цифр, например, "ppppu"
или "pppppuuuu"
.
var onlyU = DateTimeFormatter.ofPattern("uuuu");
var padded = DateTimeFormatter.ofPattern("ppppu");
var padded5 = DateTimeFormatter.ofPattern("pppppuuuu");
for (LocalDate d = LocalDate.now().minus(2421, ChronoUnit.YEARS); d.getYear() < 2200; d = d.plus(400, ChronoUnit.YEARS)) {
try {
var uuuu = d.format(onlyU);
var ppppu = d.format(padded);
var pppppuuuu = d.format(padded5);
System.out.printf("formatted year=]tuuuu=[%s] tppppu=[%s]tpppppuuuu=[%s]%n", d.getYear(), uuuu, ppppu, pppppuuuu);
} catch (DateTimeException e) {
System.out.println("error: " e);
}
}
Вывод:
formatted year= -401 uuuu=[-0401] ppppu=[-401] pppppuuuu=[-0401]
formatted year= -1 uuuu=[-0001] ppppu=[ -1] pppppuuuu=[-0001]
formatted year= 399 uuuu=[0399] ppppu=[ 399] pppppuuuu=[ 0399]
formatted year= 799 uuuu=[0799] ppppu=[ 799] pppppuuuu=[ 0799]
formatted year= 1199 uuuu=[1199] ppppu=[1199] pppppuuuu=[ 1199]
formatted year= 1599 uuuu=[1599] ppppu=[1599] pppppuuuu=[ 1599]
formatted year= 1999 uuuu=[1999] ppppu=[1999] pppppuuuu=[ 1999]
Комментарии:
1. спасибо, но ваш ответ на самом деле не объясняет разницу между количеством букв меньше четырех и четыре или более («иначе» в вопросе)
2. Извините, мой ответ прекрасно объясняет причину использования формата
DateTimeException
whenppppuuuu
из-за примененияSignStyle.EXCEED_PAD
. Принятый в настоящее время ответ не содержит никаких шаблонов с заполнением. Неважно…3. да! но, пожалуйста, подумайте, каков был мой первоначальный вопрос! Я начал играть с этим p в шаблоне только потому, что неправильно понял объяснение из последнего цитируемого предложения . Я ценю ваши усилия, просто это не то, что я искал — и это было настолько сложно для меня, что я даже забыл, что я имел в виду изначально 🙂 только этот сегодняшний ответ напомнил мне. может быть, кто-то еще найдет это полезным. приветствия