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