1<!-- 2© 2019 and later: Unicode, Inc. and others. 3License & terms of use: http://www.unicode.org/copyright.html 4--> 5 6FormattedValue 7============== 8 9FormattedValue is an abstraction for localized strings with attributes 10returned by a number of ICU formatters. APIs for FormattedValue are available 11in Java, C++, and C. For more details and a list of all implementing classes, 12refer to the API docs: 13 14- [C++ FormattedValue](http://icu-project.org/apiref/icu4c/classicu_1_1FormattedValue.html) 15- [C UFormattedValue](http://icu-project.org/apiref/icu4c/globals_u.html) -- search for "resultAsValue" 16- [Java FormattedValue](http://www.icu-project.org/apiref/icu4j/com/ibm/icu/text/FormattedValue.html) 17 18## Nested Span Fields 19 20Certain ICU formatters, like FormattedList and FormattedDateInterval, use 21*span fields* to return information about which spans of a string correspond 22to different input parameters. In C and C++, span fields are implemented 23using a field category, with the field being set to the input index; in Java, 24they are implemented by associating an Integer value with a SpanField 25subclass. 26 27For example, in C++, here is how you can determine which region in a formatted 28date interval corresponds to the 2nd argument (index 1) in the input date 29interval (the "to" date): 30 31```cpp 32// Let fmt be a DateIntervalFormat for locale en-US and skeleton dMMMMy 33// Let input1 be July 20, 2018 and input2 be August 3, 2018: 34FormattedDateInterval result = fmt->formatToValue(*input1, *input2, status); 35assertEquals("Expected output from format", 36 u"July 20 \u2013 August 3, 2018", result.toString(status)); 37ConstrainedFieldPosition cfpos; 38cfpos.constrainField(UFIELD_CATEGORY_DATE_INTERVAL_SPAN, 0); 39if (result.nextPosition(cfpos, status)) { 40 assertEquals("Expect start index", 0, cfpos.getStart()); 41 assertEquals("Expect end index", 7, cfpos.getLimit()); 42} else { 43 // No such span: can happen if input dates are equal. 44} 45assertFalse("No more than one occurrence of the field", 46 result.nextPosition(cfpos, status)); 47``` 48 49In C, the code looks very similar, except you use the equivalent C types. 50 51In Java, use the `constrainFieldAndValue` method: 52 53```java 54// Let fmt be a DateIntervalFormat for locale en-US and skeleton dMMMMy 55// Let input1 be July 20, 2018 and input2 be August 3, 2018: 56FormattedDateInterval result = fmt.formatToValue(input1, input2); 57assertEquals("Expected output from format", 58 "July 20 \u2013 August 3, 2018", result.toString()); 59ConstrainedFieldPosition cfpos = new ConstrainedFieldPosition(); 60cfpos.constrainFieldAndValue(DateIntervalFormat.SpanField.DATE_INTERVAL_SPAN, 0); 61if (result.nextPosition(cfpos)) { 62 assertEquals("Expect start index", 0, cfpos.getStart()); 63 assertEquals("Expect end index", 7, cfpos.getLimit()); 64} else { 65 // No such span: can happen if input dates are equal. 66} 67assertFalse("No more than one occurrence of the field", 68 result.nextPosition(cfpos)); 69``` 70 71A span may cover multiple primitive fields; in the above example, the span 72contains both a month and a date. Using FormattedValue, those primitive 73fields will also be present, and you can check their start and end indices to 74see if they are contained within a desired span. 75