简体   繁体   English

解析 2 位数年份:使用未知日期模式设置枢轴日期

[英]Parsing 2-digit years: Setting the pivot date with an unknown date pattern

The user will input dates in different patterns to my application.用户将以不同的模式向我的应用程序输入日期。 For 2-digit years, he must also determine the pivot date.对于两位数的年份,他还必须确定枢轴日期。


Example:例子:
pattern = yy-MM-dd模式 = yy-MM-dd
pivot date = 70 (I add the current millennium and the last century for more dynamics programmatically => 1970 )枢轴日期 = 70 (我以编程方式添加了当前的千禧年和上个世纪以获得更多动态 => 1970

69-04-22 becomes 2069-04-22 69-04-22变成2069-04-22
70-04-22 becomes 1970-04-22 70-04-22变成1970-04-22


Like described in this answer it's easy to build a DateTimeFormatter when the date pattern (here ddMMyy ) is known.就像在这个答案中描述的那样,当日期模式(这里是ddMMyy )已知时,很容易构建一个DateTimeFormatter
But since the user inputs the pattern, I'm not sure how to build the DateTimeFormatterBuilder properly.但是由于用户输入了模式,我不确定如何正确构建DateTimeFormatterBuilder I can't hard code it.我无法对其进行硬编码。

Do I have to parse the pattern by myself and call appendPattern() and appendValueReduced() in the right order?我必须自己解析模式并以正确的顺序调用appendPattern()appendValueReduced()吗? Or is there a built-in solution?或者是否有内置解决方案?

Here the Java-8-solution (it rather looks like a hack):这里是 Java-8 解决方案(它看起来更像是一个 hack):

String pattern = "MM/dd/yy 'US'"; // user-input
String text = "10/04/69 US"; // user-input
Locale locale = Locale.US; // user-input, too?

int yy = pattern.indexOf("yy");
DateTimeFormatter dtf;

if (
    (yy != -1) // explanation: condition ensures exactly two letters y
    && ((yy + 2 >= pattern.length()) || pattern.charAt(yy + 2) != 'y')
) {
    DateTimeFormatterBuilder builder = new DateTimeFormatterBuilder();
    String part1 = pattern.substring(0, yy);
    if (!part1.isEmpty()) {
        builder.appendPattern(part1);
    }
    builder.appendValueReduced(ChronoField.YEAR, 2, 2, 1970);
    String part2 = pattern.substring(yy + 2);
    if (!part2.isEmpty()) {
        builder.appendPattern(part2);
    }
    dtf = builder.toFormatter(locale);
} else {
    dtf = DateTimeFormatter.ofPattern(pattern, locale);
}

LocalDate ld = LocalDate.parse(text, dtf);
System.out.println("user-date: " + ld); // 2069-10-04

There is only one tiny caveat: If any user gets the crazy idea to define two times separately "yy" in the pattern then the proposed solution will fail.只有一个小小的警告:如果任何用户有疯狂的想法在模式中分别定义两次“yy”,那么提议的解决方案将失败。 The correct solution would then require some kind of iterating over the pattern chars but I think that is overkill, so I leave it out here.正确的解决方案将需要对模式字符进行某种迭代,但我认为这是矫枉过正,所以我把它留在这里。

Just for comparison, using my external library Time4J enables following short solution because its parse engine also has the concept of setting any suitable format attributes:只是为了比较,使用我的外部库 Time4J 可以实现以下简短的解决方案,因为它的解析引擎还具有设置任何合适格式属性的概念:

LocalDate ld = 
  ChronoFormatter.ofDatePattern(pattern, PatternType.CLDR, locale)
  .with(Attributes.PIVOT_YEAR, 2070).parse(text).toTemporalAccessor();

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM