2

I have some HR records whose dates are formatted as dd/MM/yy, and I am normalizing them to dd-MM-yyyy using Joda-Time. So for example, the following records are normalized as follows

  Input        Output
30/01/14 --> 30-01-2014
15/07/99 --> 15-07-1999
24/03/84 --> 24-03-1984

Based on various criteria (average length of human lifespan, when company has been around, ... ), I can assume what year 99 might refer to.

However, if I wanted to specify that 99 refers to 1899 or some other year ending in 99, how would I do this?

I am reading over the docs for the DateTimeFormatter patterns, as well as the explanations here, and it looks like CenturyOfEra field C might be what I want to use, but it isn't obvious how I would use it.

MxLDevs
  • 19,048
  • 36
  • 123
  • 194

2 Answers2

2

If I understand the question correctly, it is referred as "Pivot Year": http://joda-time.sourceforge.net/apidocs/org/joda/time/format/DateTimeFormatter.html#withPivotYear%28int%29

The CenturyOfEra is just our current century - XXI, the one which so many sci-fi authors dreamed about few decades back.

kan
  • 28,279
  • 7
  • 71
  • 101
1

java.time

By default, 2000 is used as the base value for the year. You can change this behaviour by specifying the base value for the year in the following method:

DateTimeFormatterBuilder appendValueReduced(TemporalField field,
                                                   int width,
                                                   int maxWidth,
                                                   int baseValue)

Demo:

import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeFormatterBuilder;
import java.time.temporal.ChronoField;
import java.util.Locale;

public class Main {
    public static void main(String[] args) {
        // Test
        System.out.println(LocalDate.parse("01/30/14", dateTimeFormatterWithBaseYear("M/d/", 1900, null)));
        System.out.println(LocalDate.parse("30/01/14", dateTimeFormatterWithBaseYear("d/M/", 1800, Locale.ENGLISH)));
        System.out.println(LocalDate.parse("1/30/14", dateTimeFormatterWithBaseYear("M/d/", 1800, null)));
        System.out.println(LocalDate.parse("30/1/14", dateTimeFormatterWithBaseYear("d/M/", 1700, Locale.ENGLISH)));
        System.out.println(LocalDate.parse("01/30/1914", dateTimeFormatterWithBaseYear("M/d/", 1900, null)));
        System.out.println(LocalDate.parse("30/01/2014", dateTimeFormatterWithBaseYear("d/M/", 1800, Locale.ENGLISH)));
    }

    public static DateTimeFormatter dateTimeFormatterWithBaseYear(String dayMonPattern, int baseYear, Locale locale) {
        return new DateTimeFormatterBuilder()
                .appendPattern(dayMonPattern)
                .appendValueReduced(ChronoField.YEAR, 2, 4, baseYear)
                .toFormatter(locale == null ? Locale.getDefault() : locale);
    }
}

Output:

1914-01-30
1814-01-30
1814-01-30
1714-01-30
1914-01-30
2014-01-30

Learn more about the the modern date-time API* from Trail: Date Time.


* For any reason, if you have to stick to Java 6 or Java 7, you can use ThreeTen-Backport which backports most of the java.time functionality to Java 6 & 7. If you are working for an Android project and your Android API level is still not compliant with Java-8, check Java 8+ APIs available through desugaring and How to use ThreeTenABP in Android Project.

Arvind Kumar Avinash
  • 71,965
  • 6
  • 74
  • 110