ICU-20741 Adding tests for C/C++ API into DateFormatTests
diff --git a/icu4c/source/test/intltest/dtfmttst.cpp b/icu4c/source/test/intltest/dtfmttst.cpp
index 46f4be2..93aa951 100644
--- a/icu4c/source/test/intltest/dtfmttst.cpp
+++ b/icu4c/source/test/intltest/dtfmttst.cpp
@@ -128,6 +128,7 @@
     TESTCASE_AUTO(TestDayPeriodParsing);
     TESTCASE_AUTO(TestParseRegression13744);
     TESTCASE_AUTO(TestAdoptCalendarLeak);
+    TESTCASE_AUTO(Test20741_ABFields);
 
     TESTCASE_AUTO_END;
 }
@@ -5570,6 +5571,46 @@
     sdf.adoptCalendar(Calendar::createInstance(status));
 }
 
+/**
+ * Test that 'a' and 'B' fields are not duplicated in the field position iterator.
+ */
+void DateFormatTest::Test20741_ABFields() {
+    IcuTestErrorCode status(*this, "Test20741_ABFields");
+
+    const char16_t timeZone[] = u"PST8PDT";
+
+    UnicodeString skeleton = u"EEEEEBBBBB"; 
+    int32_t count = 0;
+    const Locale* locales = Locale::getAvailableLocales(count);
+    for (int32_t i = 0; i < count; i++) {
+        if (quick && (i % 17) != 0) { continue; }
+
+        const Locale locale = locales[i];
+        LocalPointer<DateTimePatternGenerator> gen(DateTimePatternGenerator::createInstance(locale, status));
+        UnicodeString pattern = gen->getBestPattern(skeleton, status);
+
+        SimpleDateFormat dateFormat(pattern, locale, status);
+        FieldPositionIterator fpositer;
+        UnicodeString result;
+        LocalPointer<Calendar> calendar(Calendar::createInstance(TimeZone::createTimeZone(timeZone), status));
+        calendar->setTime(UDate(0), status);
+        dateFormat.format(*calendar, result, &fpositer, status);
+
+        FieldPosition curFieldPosition;
+        FieldPosition lastFieldPosition;
+        lastFieldPosition.setBeginIndex(-1);
+        lastFieldPosition.setEndIndex(-1);
+        while(fpositer.next(curFieldPosition)) {
+            if (curFieldPosition.getBeginIndex() == lastFieldPosition.getBeginIndex() && curFieldPosition.getEndIndex() == lastFieldPosition.getEndIndex()) {
+                if (logKnownIssue("20741")) continue;
+                assertEquals("Different fields at same position", 'B', PATTERN_CHARS[lastFieldPosition.getField()]);   
+            }
+
+            lastFieldPosition = curFieldPosition;
+        }
+    }
+}
+
 #endif /* #if !UCONFIG_NO_FORMATTING */
 
 //eof
diff --git a/icu4c/source/test/intltest/dtfmttst.h b/icu4c/source/test/intltest/dtfmttst.h
index fd07b5a..ac36919 100644
--- a/icu4c/source/test/intltest/dtfmttst.h
+++ b/icu4c/source/test/intltest/dtfmttst.h
@@ -263,6 +263,7 @@
     void TestDayPeriodParsing();
     void TestParseRegression13744();
     void TestAdoptCalendarLeak();
+    void Test20741_ABFields();
 
 private:
     UBool showParse(DateFormat &format, const UnicodeString &formattedString);
diff --git a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/format/DateFormatTest.java b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/format/DateFormatTest.java
index 735d45d..5b28a76 100644
--- a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/format/DateFormatTest.java
+++ b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/format/DateFormatTest.java
@@ -49,6 +49,7 @@
 import com.ibm.icu.text.DateFormat;
 import com.ibm.icu.text.DateFormat.BooleanAttribute;
 import com.ibm.icu.text.DateFormatSymbols;
+import com.ibm.icu.text.DateTimePatternGenerator;
 import com.ibm.icu.text.DisplayContext;
 import com.ibm.icu.text.NumberFormat;
 import com.ibm.icu.text.SimpleDateFormat;
@@ -5458,4 +5459,34 @@
             assertEquals("Format pattern", cas[1], pattern);
         }
     }
+
+    @Test
+    public void test20741_ABFields() {
+        ULocale[] locales = ULocale.getAvailableLocales();
+        for (int i = 0; i < locales.length; i++) {
+            ULocale locale = locales[i];
+            if (isQuick() && (i % 17 != 0)) continue;
+
+            DateTimePatternGenerator gen = DateTimePatternGenerator.getInstance(locale);
+            String pattern = gen.getBestPattern("EEEEEBBBBB");
+            SimpleDateFormat dateFormat = new SimpleDateFormat(pattern, locale);
+            Calendar calendar = Calendar.getInstance(TimeZone.getTimeZone("PST8PDT"));
+            calendar.setTime(new Date(0));
+
+            FieldPosition pos_c = new FieldPosition(DateFormat.Field.DAY_OF_WEEK);
+            dateFormat.format(calendar, new StringBuffer(""), pos_c);
+            assertFalse("'Day of week' field was not found", pos_c.getBeginIndex() == 0 && pos_c.getEndIndex() == 0);
+
+            FieldPosition pos_B = new FieldPosition(DateFormat.Field.FLEXIBLE_DAY_PERIOD);
+            dateFormat.format(calendar, new StringBuffer(""), pos_B);
+            assertFalse("'Flexible day period' field was not found", pos_B.getBeginIndex() == 0 && pos_B.getEndIndex() == 0);
+
+            FieldPosition pos_a = new FieldPosition(DateFormat.Field.AM_PM);
+            dateFormat.format(calendar, new StringBuffer(""), pos_a);
+            if (pos_B.getBeginIndex() == pos_a.getBeginIndex() && pos_B.getEndIndex() == pos_a.getEndIndex()) {
+                if (logKnownIssue("20741", "Format Fields reports same field position as \"a\" and \"B\"")) continue;
+                fail("Duplicated field found");
+            }
+        }
+    }
 }