如何在 DateTimeFormatter 中以四个字母的数量打印年份标志?

huangapple go评论109阅读模式
英文:

How to print year sign in DateTimeFormatter when the count of letters is four?

问题

根据DateTimeFormatterjavadoc

如果字母的数量少于四个(但不是两个),则根据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中的最后一句话正常工作

英文:

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.

答案1

得分: 1

以下是翻译好的部分:

句子中的 Otherwise 指的是您所询问的情况,其中 Otherwise 指的是字母计数为4或更多的情况。令人困惑的是,这里的 pad width 与填充的模式字母 p 无关,而是指要打印的数字位数。它与段落的第一句话相呼应,即 The count of letters determines the minimum field width below which padding is used.(字母的计数确定了在其下使用填充的最小字段宽度。)

因此,要查看它的工作原理,使用4个或更多的模式字母,并使用比模式字母的数量更多的位数的年份。它适用于 uyY

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 的文档说明如下:

> … A negative value will always output the '-' sign.

文档链接: SignStyle.EXCEEDS_PAD

英文:

The Otherwise in the sentence you are asking about refers to the situation where the count of letters is 4 or greater. Confusingly the pad width here has nothing to do with pattern letter p for padding. It refers to the number of digits to be printed. It refers back to the first sentence of the paragraph, The count of letters determines the minimum field width below which padding is used.

So to see that work, use 4 or more pattern letters and use a year that takes a greater number of digits than the number of pattern letters. It works with both u, y and 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));

Output:

> +12345
> +12345
> +12345

The minus sign is printed regardless of the number of characters to be printed. The documentation of SignStyle.EXCEEDS_PAD says:

> … A negative value will always output the '-' sign.

Documentation link: SignStyle.EXCEEDS_PAD

答案2

得分: 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

我在formatter1中使用了uu(字母数量为两个),因此它不显示负号。然而,如果字母数量少于四个但不是两个,您需要提供足够的填充,例如对于年份-1,您至少需要2个填充(即pp),一个用于负号-,一个用于1。如果提供的填充少于2个,将会得到DateTimeException,如果提供的填充超过2个,在-1之前会有空格。

因此,在格式为uuuu的情况下,对于负年份,您需要至少5个填充(即ppppp),一个用于-,另外4个用于年份(0001),即您需要使用DateTimeFormatter.ofPattern("pppppuuuu")来避免DateTimeException

英文:

> 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.

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);
	}
}

Output:

formatted string: year01
formatted string: year-1

I have used uu (count of letters as two) in formatter1 and therefore it does not show a negative sign. However, if the count of letters is is less than four, but not two, you need to provide enough padding e.g. for the year, -1, you need padding of at least 2 (i.e. pp), one for the - sign and one for 1. If you provide less number of padding, you will get DateTimeException and if you provide more than 2 padding, you will get space before -1.

Thus, in case of the format uuuu, you need a padding of at least 5 (i.e. ppppp) for a negative year, one for - and 4 for years (0001) i.e. you need to use DateTimeFormatter.ofPattern("pppppuuuu") to avoid DateTimeException.

答案3

得分: 0

这个模式 "ppppuuuu" 定义了 padWidth 为 4,应用于格式 uuuu,其中使用了 SignStyle.EXCEEDS_PAD(根据javadoc for DateTimeFormatBuilder)。

也就是说,由于当前的 SignStyle- 总是会被打印出来。

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

类似地,当使用 uuuu 模式时,符号始终会被打印出来,因为在这些情况下应用了 SignStyle.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]
英文:

This pattern "ppppuuuu" defines padWidth of 4 applied to the following format uuuu, which applies SignStyle.EXCEEDS_PAD (according to javadoc for DateTimeFormatBuilder).

That is, the - is always printed due to current SignStyle.

Thus, when the formatter tries to print a negative year, it uses 4 digits and a sign thus exceeding the available padWidth.

Similarly, the sign is always printed when using u or uuu patterns because SignStyle.NORMAL is applied in these cases.

So, the sign won't be printed only when uu format is used.

To avoid the exception for a negative number, the padding should exceed the number of digits, for example, "ppppu" or "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);  
    }
}

Output:

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]

huangapple
  • 本文由 发表于 2020年10月26日 03:44:20
  • 转载请务必保留本文链接:https://go.coder-hub.com/64528038.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定