summaryrefslogtreecommitdiffstats
path: root/intl/icu-patches/bug-1856290-ICU-20548-dateinterval-timezone.diff
blob: 8d2762b48ae46fb064ee6763b1c23bf0360781be (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
# Handle 'O' time zone skeleton in DateIntervalFormat.
# Keep time zone skeleton field widths in DateIntervalFormat.
#
# ICU bug: https://unicode-org.atlassian.net/browse/ICU-20548

diff --git a/intl/icu/source/i18n/dtitv_impl.h b/intl/icu/source/i18n/dtitv_impl.h
--- a/intl/icu/source/i18n/dtitv_impl.h
+++ b/intl/icu/source/i18n/dtitv_impl.h
@@ -84,16 +84,19 @@
 #define CAP_W             ((char16_t)0x0057)
 #define CAP_Y             ((char16_t)0x0059)
 #define CAP_Z             ((char16_t)0x005A)
 
 //#define MINIMUM_SUPPORTED_CALENDAR_FIELD    UCAL_MINUTE
 
 #define MAX_E_COUNT      5
 #define MAX_M_COUNT      5
+#define MAX_z_COUNT      4
+#define MAX_v_COUNT      4
+#define MAX_O_COUNT      4
 //#define MAX_INTERVAL_INDEX 4
 #define MAX_POSITIVE_INT  56632
 
 
 #endif /* #if !UCONFIG_NO_FORMATTING */
 
 #endif 
 //eof
diff --git a/intl/icu/source/i18n/dtitvfmt.cpp b/intl/icu/source/i18n/dtitvfmt.cpp
--- a/intl/icu/source/i18n/dtitvfmt.cpp
+++ b/intl/icu/source/i18n/dtitvfmt.cpp
@@ -1061,16 +1061,17 @@ DateIntervalFormat::getDateTimeSkeleton(
     // timeSkeleton follows the sequence of hm*[v|z]?
     int32_t ECount = 0;
     int32_t dCount = 0;
     int32_t MCount = 0;
     int32_t yCount = 0;
     int32_t mCount = 0;
     int32_t vCount = 0;
     int32_t zCount = 0;
+    int32_t OCount = 0;
     char16_t hourChar = u'\0';
     int32_t i;
 
     for (i = 0; i < skeleton.length(); ++i) {
         char16_t ch = skeleton[i];
         switch ( ch ) {
           case CAP_E:
             dateSkeleton.append(ch);
@@ -1123,16 +1124,20 @@ DateIntervalFormat::getDateTimeSkeleton(
           case LOW_Z:
             ++zCount;
             timeSkeleton.append(ch);
             break;
           case LOW_V:
             ++vCount;
             timeSkeleton.append(ch);
             break;
+          case CAP_O:
+            ++OCount;
+            timeSkeleton.append(ch);
+            break;
           case LOW_A:
           case CAP_V:
           case CAP_Z:
           case LOW_J:
           case LOW_S:
           case CAP_S:
           case CAP_A:
           case LOW_B:
@@ -1174,20 +1179,41 @@ DateIntervalFormat::getDateTimeSkeleton(
     /* generate normalized form for time */
     if ( hourChar != u'\0' ) {
         normalizedTimeSkeleton.append(hourChar);
     }
     if ( mCount != 0 ) {
         normalizedTimeSkeleton.append(LOW_M);
     }
     if ( zCount != 0 ) {
-        normalizedTimeSkeleton.append(LOW_Z);
+        if ( zCount <= 3 ) {
+            normalizedTimeSkeleton.append(LOW_Z);
+        } else {
+            for ( int32_t j = 0; j < zCount && j < MAX_z_COUNT; ++j ) {
+                 normalizedTimeSkeleton.append(LOW_Z);
+            }
+        }
     }
     if ( vCount != 0 ) {
-        normalizedTimeSkeleton.append(LOW_V);
+        if ( vCount <= 3 ) {
+            normalizedTimeSkeleton.append(LOW_V);
+        } else {
+            for ( int32_t j = 0; j < vCount && j < MAX_v_COUNT; ++j ) {
+                 normalizedTimeSkeleton.append(LOW_V);
+            }
+        }
+    }
+    if ( OCount != 0 ) {
+        if ( OCount <= 3 ) {
+            normalizedTimeSkeleton.append(CAP_O);
+        } else {
+            for ( int32_t j = 0; j < OCount && j < MAX_O_COUNT; ++j ) {
+                 normalizedTimeSkeleton.append(CAP_O);
+            }
+        }
     }
 }
 
 
 /**
  * Generate date or time interval pattern from resource,
  * and set them into the interval pattern locale to this formatter.
  *
@@ -1732,18 +1758,23 @@ DateIntervalFormat::adjustFieldWidth(con
         findReplaceInPattern(adjustedPtn, UnicodeString(u"a\u202F",-1), UnicodeString());
         findReplaceInPattern(adjustedPtn, UnicodeString(LOW_A), UnicodeString());
         // adjust interior double spaces, remove exterior whitespace
         findReplaceInPattern(adjustedPtn, UnicodeString("  "), UnicodeString(" "));
         adjustedPtn.trim();
     }
     if ( differenceInfo == 2 ) {
         if (inputSkeleton.indexOf(LOW_Z) != -1) {
+             bestMatchSkeletonFieldWidth[(int)(LOW_Z - PATTERN_CHAR_BASE)] = bestMatchSkeletonFieldWidth[(int)(LOW_V - PATTERN_CHAR_BASE)];
              findReplaceInPattern(adjustedPtn, UnicodeString(LOW_V), UnicodeString(LOW_Z));
          }
+         if (inputSkeleton.indexOf(CAP_O) != -1) {
+             bestMatchSkeletonFieldWidth[(int)(CAP_O - PATTERN_CHAR_BASE)] = bestMatchSkeletonFieldWidth[(int)(LOW_V - PATTERN_CHAR_BASE)];
+             findReplaceInPattern(adjustedPtn, UnicodeString(LOW_V), UnicodeString(CAP_O));
+         }
          if (inputSkeleton.indexOf(CAP_K) != -1) {
              findReplaceInPattern(adjustedPtn, UnicodeString(LOW_H), UnicodeString(CAP_K));
          }
          if (inputSkeleton.indexOf(LOW_K) != -1) {
              findReplaceInPattern(adjustedPtn, UnicodeString(CAP_H), UnicodeString(LOW_K));
          }
          if (inputSkeleton.indexOf(LOW_B) != -1) {
              findReplaceInPattern(adjustedPtn, UnicodeString(LOW_A), UnicodeString(LOW_B));
diff --git a/intl/icu/source/i18n/dtitvinf.cpp b/intl/icu/source/i18n/dtitvinf.cpp
--- a/intl/icu/source/i18n/dtitvinf.cpp
+++ b/intl/icu/source/i18n/dtitvinf.cpp
@@ -582,19 +582,20 @@ DateIntervalInfo::getBestSkeleton(const 
 
     // hack for certain alternate characters
     // resource bundles only have time skeletons containing 'v', 'h', and 'H'
     // but not time skeletons containing 'z', 'K', or 'k'
     // the skeleton may also include 'a' or 'b', which never occur in the resource bundles, so strip them out too
     UBool replacedAlternateChars = false;
     const UnicodeString* inputSkeleton = &skeleton;
     UnicodeString copySkeleton;
-    if ( skeleton.indexOf(LOW_Z) != -1 || skeleton.indexOf(LOW_K) != -1 || skeleton.indexOf(CAP_K) != -1 || skeleton.indexOf(LOW_A) != -1 || skeleton.indexOf(LOW_B) != -1 ) {
+    if ( skeleton.indexOf(LOW_Z) != -1 || skeleton.indexOf(CAP_O) != -1 || skeleton.indexOf(LOW_K) != -1 || skeleton.indexOf(CAP_K) != -1 || skeleton.indexOf(LOW_A) != -1 || skeleton.indexOf(LOW_B) != -1 ) {
         copySkeleton = skeleton;
         copySkeleton.findAndReplace(UnicodeString(LOW_Z), UnicodeString(LOW_V));
+        copySkeleton.findAndReplace(UnicodeString(CAP_O), UnicodeString(LOW_V));
         copySkeleton.findAndReplace(UnicodeString(LOW_K), UnicodeString(CAP_H));
         copySkeleton.findAndReplace(UnicodeString(CAP_K), UnicodeString(LOW_H));
         copySkeleton.findAndReplace(UnicodeString(LOW_A), UnicodeString());
         copySkeleton.findAndReplace(UnicodeString(LOW_B), UnicodeString());
         inputSkeleton = &copySkeleton;
         replacedAlternateChars = true;
     }