- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我在与Elastic Search查询有关的问题中发现了此问题,但是由于ES date format documentation链接到API documentation for the java.time.format.DateTimeFormatter类,因此该问题并不是真正针对ES的。
简短摘要:我们遇到的问题是9999年以后的日期,更确切地说是4位以上的年份。
ES中存储的文档具有日期字段,该日期字段在索引描述符中使用“日期”格式定义,该格式使用DateTimeFormatter中的模式语言对应于“yyyy-MM-dd”。我们正在获取用户输入,使用org.apache.commons.validator.DateValidator.isValid并使用模式“yyyy-MM-dd”验证输入,如果有效,我们将使用用户输入创建ES查询。如果用户输入类似20202-12-03的内容,则执行失败。搜索词可能不是故意的,但是预期的行为是不会找到任何东西,也不是软件咳嗽了一个异常(exception)。
问题是org.apache.commons.validator.DateValidator在内部使用较旧的SimpleDateFormat类来验证输入是否符合模式,并且SimpleDateFormat解释的“yyyy”含义类似于:使用至少4位数字,但如果需要,则允许更多位数。因此,使用模式“yyyy-MM-dd”创建SimpleDateFormat既可以解析“20202-07-14”之类的输入,又可以类似地格式化年份超过9999的Date对象。
新的DateTimeFormatter类更加严格,意味着“yyyy”正好是四个数字。它将无法解析“20202-07-14”之类的输入字符串,也无法格式化年份超过9999的Temporal对象。值得注意的是,DateTimeFormatter本身具有处理可变长度字段的能力。常量DateTimeFormatter.ISO_LOCAL_DATE例如不等同于“yyyy-MM-dd”,但是符合ISO8601的年份允许多于四位数字,但将至少使用四位数字。使用DateTimeFormatterBuilder而不是使用模式字符串以编程方式创建此常量。
ES无法配置为使用DateTimeFormatter中定义的常量(例如ISO_LOCAL_DATE),而只能使用模式字符串。 ES还知道预定义模式的列表,文档中有时还会引用ISO标准,但是它们似乎是错误的,并且忽略了有效的ISO日期字符串可以包含五位数字的年份。
我可以使用多个允许的日期模式列表来配置ES,例如“yyyy-MM-dd || yyyyy-MM-dd”。这将允许一年中的四位数和五位数,但在六位数的年份中会失败。我可以通过添加另一个允许的模式来支持六位数字的年份:“yyyy-MM-dd || yyyyy-MM-dd || yyyyyy-MM-dd”,但是它将失败七位数的年份,依此类推。
我是在监督什么,还是真的无法将ES(或使用模式字符串的DateTimeFormatter实例)配置为具有ISO标准所使用的至少四位数(但可能更多)的Year字段?
最佳答案
编辑
ISO 8601
由于您的要求是要符合ISO 8601,所以我们首先来看一下ISO 8601的内容(引自底部的链接):
To represent years before 0000 or after 9999, the standard alsopermits the expansion of the year representation but only by prioragreement between the sender and the receiver. An expanded yearrepresentation [±YYYYY] must have an agreed-upon number of extra yeardigits beyond the four-digit minimum, and it must be prefixed with a +or − sign instead of the more common AD/BC (or CE/BCE) notation; …
20202-12-03
在ISO 8601中不是有效的日期。如果您明确告知用户您接受(例如,最长6位数字的年份),则
+20202-12-03
和
-20202-12-03
是有效的,并且仅带有
+
或
-
符号。
uuuu-MM-dd
格式并根据ISO 8601解析日期,该年份也是具有四位数以上的年份。例如:
DateTimeFormatter dateFormatter = DateTimeFormatter.ofPattern("uuuu-MM-dd");
LocalDate date = LocalDate.parse("+20202-12-03", dateFormatter);
System.out.println("Parsed: " + date);
System.out.println("Formatted back: " + date.format(dateFormatter));
输出:
Parsed: +20202-12-03
Formatted back: +20202-12-03
yyyy-MM-dd||yyyyy-MM-dd||yyyyyy-MM-dd||yyyyyyy-MM-dd||yyyyyyyy-MM-dd||yyyyyyyyy-MM-dd
就像我说的那样,这与ISO 8601不同。我也同意您的看法,这并不好。很显然它将失败10位或更多位数字,但是无论如何都会失败:java.time处理-999 999 999到+999 999 999区间内的年份。因此尝试
yyyyyyyyyy-MM-dd
(10位数年)将使您满意除了在极端情况下(用户输入的年份前导零),这会带来严重的麻烦。
DateTimeFormatter
格式模式不支持您所要求的所有内容。没有(单个)模式可以为您提供0000到9999范围内的四位数年份,在此之后的年份中可以提供更多位数。
DateTimeFormatter
的文档中介绍了有关格式和解析年份的信息:
Year: The count of letters determines the minimum field width below which padding is used. If the count of letters is two, then areduced two digit form is used. For printing, this outputs therightmost two digits. For parsing, this will parse using the basevalue of 2000, resulting in a year within the range 2000 to 2099inclusive. 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 isexceeded, as perSignStyle.EXCEEDS_PAD
.
u-MM-dd
模式。示范:
String formatPattern = "u-MM-dd";
DateTimeFormatter dateFormatter = DateTimeFormatter.ofPattern(formatPattern);
LocalDate normalDate = LocalDate.parse("2020-07-14", dateFormatter);
String formattedAgain = normalDate.format(dateFormatter);
System.out.format("LocalDate: %s. String: %s.%n", normalDate, formattedAgain);
LocalDate largeDate = LocalDate.parse("20202-07-14", dateFormatter);
String largeFormattedAgain = largeDate.format(dateFormatter);
System.out.format("LocalDate: %s. String: %s.%n", largeDate, largeFormattedAgain);
输出:
LocalDate: 2020-07-14. String: 2020-07-14.
LocalDate: +20202-07-14. String: 20202-07-14.
y
和
u
之间的区别,请参阅底部的链接。
M
和/或一个
d
接受
2020-007-014
,但是同样,这将导致小于10的数字仅格式化为1位数字,例如
2020-7-14
,这可能不是您想要的,并且再次与ISO不一致。
DateTimeFormatter
uuuu
versus yyyy
in DateTimeFormatter
formatting pattern codes in Java? 关于java - 弹性搜寻和Y10k(超过4位数字的年份),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62541394/
我刚刚编写了这些代码,但输出不同。第二个代码的输出符合我的预期,但第一个代码的输出不正确。但为什么呢? def fib(n): x = 0 y = 1 print x
#include #include #define CUBE(y)y*(y*y) main() { int j; j = CUBE(-2+4);
这个问题在这里已经有了答案: Multiple assignment and evaluation order in Python (11 个答案) 关闭 1 年前。 我看到下面的代码,但不知道它做
我正在阅读 book , 并讲了 typeclass Eq 的定义 有两个功能== , /=在等式中,它们被实现为: x == y = not (x /= y) x /= y = not (
我最近参加了一个代码力量竞赛。在比赛的编辑部分,我看到了按位运算符之间的一种美妙关系,即 x + y = x & y + x |是的我还不知道证据。我拿了几个数字来看看这个等式是否正确。我很高兴知道这
我使用 CGRectMake(x,x,x,x) 在我的 View 中放置了一个按钮,当然 x 是位置和大小。当我使用 -(BOOL)shouldAutoRotate... 旋转 View 时,我想将按
this.x = (Math.random()*canvasWidth); this.y = (Math.random()*canvasHeight); (1) this.shift = {x: th
我想将此代码运行为“if 'Britain' or 'UK' in string do stuff, but don't do stuff if "Ex UK" 在字符串中": #Case insen
早上好,我是新来的,我带来了一个小问题。我无法针对以下问题开发有效的算法:我需要找到三个正数 x、y 和 z 的组合,以便 x + y、x - y、y + z、y - z、x + z 和 x - z
我现在正在使用 C++ 编写方案的解释器。我有一个关于定义和 lambda 的问题。 (define (add x y) (+ x y)) 扩展为 (define add (lambda (x y)
我正在尝试使用一台主机通过 FTP 将内容上传到另一台主机。 “我不会打开到 172.xxx.xxx.xxx(仅到 54.xxx.xxx.xxx)的连接”甚至不相关,因为我没有连接到那个主持人。这是托
在 Python 中,使用 [] 解包函数调用有什么区别? , 与 ()还是一无所有? def f(): return 0, 1 a, b = f() # 1 [a, b] = f() # 2
给定方程 z = z(x,y) 2 个表面 I和 II : z_I(x, y) = a0 + a1*y + a2*x + a3*y**2 + a4*x**2 + a5*x*y z_II(x, y)
几年前我有这个面试问题,但我还没有找到答案。 x 和 y 应该是什么才能形成无限循环? while (x = y && x != y) { } 我们尝试了 Nan,infinity+/-,null f
我正在尝试使用 Camel FTP Producer 将文件发送到第三方 ftp 服务器(似乎由 Amazon 托管),但遇到了一个问题,写入文件失败,并显示:文件操作失败...主机尝试数据连接 x.
关闭。这个问题需要details or clarity .它目前不接受答案。 想改进这个问题吗? 通过 editing this post 添加细节并澄清问题. 关闭 8 年前。 Improve t
我正在使用 torch.tensor.repeat() x = torch.tensor([[1, 2, 3], [4, 5, 6]]) period = x.size(1) repeats = [1
#include int main() { int x = 9; int y = 2; int z = x - (x / y) * y; printf("%d", z
我很难理解先有定义然后有两个异或表达式的含义。这个定义的作用是什么? 我尝试发送 x=8, y=7,结果是 x=15 和 y=8为什么会这样? 这是程序: #define FUNC(a,b) a^=b
我正在尝试使用 SIMD 优化此功能,但我不知道从哪里开始。 long sum(int x,int y) { return x*x*x+y*y*y; } 反汇编函数如下所示: 4007a0
我是一名优秀的程序员,十分优秀!