LANG-1680 Add support for standalone month formats (#892)
This commit is contained in:
parent
a2ed219fb8
commit
127869e88f
|
@ -22,6 +22,7 @@ import java.util.Calendar;
|
|||
import java.util.Date;
|
||||
import java.util.Iterator;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.NoSuchElementException;
|
||||
import java.util.TimeZone;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
@ -1831,4 +1832,40 @@ public class DateUtils {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets full standalone month names as used in "LLLL" date formatting.
|
||||
* @param locale Locale
|
||||
* @return Long names of months
|
||||
*/
|
||||
static String[] getStandaloneLongMonths(final Locale locale) {
|
||||
return getMonthNames(locale, Calendar.LONG_STANDALONE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets short standalone month names as used in "LLLL" date formatting.
|
||||
* @param locale Locale
|
||||
* @return Short names of months
|
||||
*/
|
||||
static String[] getStandaloneShortMonths(final Locale locale) {
|
||||
return getMonthNames(locale, Calendar.SHORT_STANDALONE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets month names in the requested style.
|
||||
* @param locale Locale
|
||||
* @param style Must be a valid {@link Calendar#getDisplayNames(int, int, Locale)} month style.
|
||||
* @return Styled names of months
|
||||
*/
|
||||
private static String[] getMonthNames(final Locale locale, final int style) {
|
||||
// Unfortunately standalone month names are not available in DateFormatSymbols,
|
||||
// so we have to extract them.
|
||||
final Calendar calendar = Calendar.getInstance(locale);
|
||||
Map<String, Integer> displayNames = calendar.getDisplayNames(Calendar.MONTH, style, locale);
|
||||
final String[] monthNames = new String[displayNames.size()];
|
||||
for (Map.Entry<String, Integer> entry: displayNames.entrySet()) {
|
||||
monthNames[entry.getValue()] = entry.getKey();
|
||||
}
|
||||
return monthNames;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -606,6 +606,7 @@ public class FastDateParser implements DateParser, Serializable {
|
|||
case 'K': // Hour in am/pm (0-11)
|
||||
return HOUR_STRATEGY;
|
||||
case 'M':
|
||||
case 'L':
|
||||
return width >= 3 ? getLocaleSpecificStrategy(Calendar.MONTH, definingCalendar) : NUMBER_MONTH_STRATEGY;
|
||||
case 'S':
|
||||
return MILLISECOND_STRATEGY;
|
||||
|
|
|
@ -233,6 +233,17 @@ public class FastDatePrinter implements DatePrinter, Serializable {
|
|||
rule = UnpaddedMonthField.INSTANCE;
|
||||
}
|
||||
break;
|
||||
case 'L': // month in year (text and number)
|
||||
if (tokenLen >= 4) {
|
||||
rule = new TextField(Calendar.MONTH, DateUtils.getStandaloneLongMonths(mLocale));
|
||||
} else if (tokenLen == 3) {
|
||||
rule = new TextField(Calendar.MONTH, DateUtils.getStandaloneShortMonths(mLocale));
|
||||
} else if (tokenLen == 2) {
|
||||
rule = TwoDigitMonthField.INSTANCE;
|
||||
} else {
|
||||
rule = UnpaddedMonthField.INSTANCE;
|
||||
}
|
||||
break;
|
||||
case 'd': // day in month (number)
|
||||
rule = selectNumberRule(Calendar.DAY_OF_MONTH, tokenLen);
|
||||
break;
|
||||
|
|
|
@ -1694,5 +1694,43 @@ public class DateUtilsTest {
|
|||
now.add(Calendar.DATE, 1);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetStandaloneLongMonthNames() {
|
||||
Locale testLocale = Locale.GERMAN;
|
||||
String[] standaloneShortMonths = DateUtils.getStandaloneLongMonths(testLocale);
|
||||
assertEquals(12, standaloneShortMonths.length);
|
||||
assertEquals("Januar", standaloneShortMonths[0]);
|
||||
assertEquals("Februar", standaloneShortMonths[1]);
|
||||
assertEquals("M\u00e4rz", standaloneShortMonths[2]);
|
||||
assertEquals("April", standaloneShortMonths[3]);
|
||||
assertEquals("Mai", standaloneShortMonths[4]);
|
||||
assertEquals("Juni", standaloneShortMonths[5]);
|
||||
assertEquals("Juli", standaloneShortMonths[6]);
|
||||
assertEquals("August", standaloneShortMonths[7]);
|
||||
assertEquals("September", standaloneShortMonths[8]);
|
||||
assertEquals("Oktober", standaloneShortMonths[9]);
|
||||
assertEquals("November", standaloneShortMonths[10]);
|
||||
assertEquals("Dezember", standaloneShortMonths[11]);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetStandaloneShortMonthNames() {
|
||||
Locale testLocale = Locale.GERMAN;
|
||||
String[] standaloneShortMonths = DateUtils.getStandaloneShortMonths(testLocale);
|
||||
assertEquals(12, standaloneShortMonths.length);
|
||||
assertEquals("Jan", standaloneShortMonths[0]);
|
||||
assertEquals("Feb", standaloneShortMonths[1]);
|
||||
assertEquals("M\u00e4r", standaloneShortMonths[2]);
|
||||
assertEquals("Apr", standaloneShortMonths[3]);
|
||||
assertEquals("Mai", standaloneShortMonths[4]);
|
||||
assertEquals("Jun", standaloneShortMonths[5]);
|
||||
assertEquals("Jul", standaloneShortMonths[6]);
|
||||
assertEquals("Aug", standaloneShortMonths[7]);
|
||||
assertEquals("Sep", standaloneShortMonths[8]);
|
||||
assertEquals("Okt", standaloneShortMonths[9]);
|
||||
assertEquals("Nov", standaloneShortMonths[10]);
|
||||
assertEquals("Dez", standaloneShortMonths[11]);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -26,6 +26,9 @@ import java.text.FieldPosition;
|
|||
import java.text.Format;
|
||||
import java.text.ParsePosition;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.time.Instant;
|
||||
import java.time.LocalDate;
|
||||
import java.time.ZoneId;
|
||||
import java.util.Date;
|
||||
import java.util.Locale;
|
||||
import java.util.TimeZone;
|
||||
|
@ -49,6 +52,9 @@ public class FastDateFormatTest {
|
|||
|
||||
private static final int NROUNDS = 10000;
|
||||
|
||||
final Locale FINNISH = Locale.forLanguageTag("fi");
|
||||
final Locale HUNGARIAN = Locale.forLanguageTag("hu");
|
||||
|
||||
private AtomicLongArray measureTime(final Format printer, final Format parser) throws InterruptedException {
|
||||
final ExecutorService pool = Executors.newFixedThreadPool(NTHREADS);
|
||||
final AtomicInteger failures = new AtomicInteger(0);
|
||||
|
@ -319,4 +325,36 @@ public class FastDateFormatTest {
|
|||
assertEquals(FastDateFormat.getTimeInstance(FastDateFormat.LONG),
|
||||
FastDateFormat.getTimeInstance(FastDateFormat.LONG, TimeZone.getDefault(), Locale.getDefault()));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testStandaloneShortMonthForm() {
|
||||
final TimeZone utc = FastTimeZone.getGmtTimeZone();
|
||||
Instant testInstant = LocalDate.of(1970, 9, 15).atStartOfDay(ZoneId.of("UTC")).toInstant();
|
||||
final Date date = Date.from(testInstant);
|
||||
|
||||
String dateAsString = FastDateFormat.getInstance("yyyy-LLL-dd", utc, Locale.GERMAN).format(date);
|
||||
assertEquals("1970-Sep-15", dateAsString);
|
||||
|
||||
dateAsString = FastDateFormat.getInstance("yyyy-LLL-dd", utc, FINNISH).format(date);
|
||||
assertEquals("1970-syys-15", dateAsString);
|
||||
|
||||
dateAsString = FastDateFormat.getInstance("yyyy-LLL-dd", utc, HUNGARIAN).format(date);
|
||||
assertEquals("1970-szept.-15", dateAsString);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testStandaloneLongMonthForm() {
|
||||
final TimeZone utc = FastTimeZone.getGmtTimeZone();
|
||||
Instant testInstant = LocalDate.of(1970, 9, 15).atStartOfDay(ZoneId.of("UTC")).toInstant();
|
||||
final Date date = Date.from(testInstant);
|
||||
|
||||
String dateAsString = FastDateFormat.getInstance("yyyy-LLLL-dd", utc, Locale.GERMAN).format(date);
|
||||
assertEquals("1970-September-15", dateAsString);
|
||||
|
||||
dateAsString = FastDateFormat.getInstance("yyyy-LLLL-dd", utc, FINNISH).format(date);
|
||||
assertEquals("1970-syyskuu-15", dateAsString);
|
||||
|
||||
dateAsString = FastDateFormat.getInstance("yyyy-LLLL-dd", utc, HUNGARIAN).format(date);
|
||||
assertEquals("1970-szeptember-15", dateAsString);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -204,7 +204,7 @@ public class FastDatePrinterTest {
|
|||
assertEquals("-04:00", fdf.format(cal2));
|
||||
assertEquals("-04:00", fdf.format(millis2));
|
||||
|
||||
final String pattern = "GGGG GGG GG G yyyy yyy yy y MMMM MMM MM M" +
|
||||
final String pattern = "GGGG GGG GG G yyyy yyy yy y MMMM MMM MM M LLLL LLL LL L" +
|
||||
" dddd ddd dd d DDDD DDD DD D EEEE EEE EE E aaaa aaa aa a zzzz zzz zz z";
|
||||
fdf = getInstance(pattern);
|
||||
sdf = new SimpleDateFormat(pattern);
|
||||
|
|
Loading…
Reference in New Issue