-1

From DateTimeFormatter javadoc:

If the count of letters is less than four (but not two), then the sign is only output for negative years as per SignStyle.NORMAL. Otherwise, the sign is output if the pad width is exceeded, as per SignStyle.EXCEEDS_PAD.

From what I understand, if the pad width is not exceeded and the count of letters is four, the minus sign (for negative years) should not be printed during formatting.

So I wrote such a snippet of code (figuring that I cannot use 'y' because then the year will always be positive):

    var negativeDate = LocalDate.now().minus(2021, ChronoUnit.YEARS);
    var formatter = DateTimeFormatter.ofPattern("ppppuuuu");
    var text = negativeDate.format(formatter);
    System.out.println("formatted string: " + text);

This code throws DateTimeException: "Cannot print as output of 5 characters exceeds pad width of 4".

So my question is basically how to see this last sentence from the javadoc work.

4

3 回答 3

1

您所询问的句子中的否则是指字母数为4或更多的情况。令人困惑的是,这里的焊盘宽度与填充的图案字母无关p。它是指要打印的位数。回到段落的第一句,字母的数量决定了使用填充的最小字段宽度。

因此,要查看这项工作,请使用 4 个或更多模式字母,并使用位数多于模式字母数的年份。它适用于u,yY

    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

于 2020-10-27T16:45:45.057 回答
0

此模式"ppppuuuu"定义padWidth了 4 应用于以下格式uuuu,它适用SignStyle.EXCEEDS_PAD(根据javadoc forDateTimeFormatBuilder)。

也就是说,-由于 current ,总是会打印SignStyle

因此,当格式化程序尝试打印负年份时,它使用 4 位数字和一个符号,因此超出了可用的padWidth.

同样,在使用或图案时始终打印标志,因为在这些情况下应用。uuuuSignStyle.NORMAL

uu因此,只有在使用格式时才会打印标志。

为避免出现负数异常,填充应超过位数,例如,"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=%5d\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]
于 2020-10-25T21:28:09.767 回答
0

如果字母数少于四个(但不是两个),则仅根据 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-40001DateTimeFormatter.ofPattern("pppppuuuu")DateTimeException

于 2020-10-25T21:12:45.353 回答