1 /* 2 * Copyright (C) 2013 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package libcore.libcore.icu; 18 19 import android.icu.util.Calendar; 20 import android.icu.util.TimeZone; 21 import android.icu.util.ULocale; 22 23 import android.icu.util.VersionInfo; 24 import java.util.function.BiFunction; 25 26 import static android.icu.util.TimeZone.GMT_ZONE; 27 import static android.icu.util.ULocale.ENGLISH; 28 import static libcore.icu.DateIntervalFormat.formatDateRange; 29 import static libcore.icu.DateUtilsBridge.*; 30 31 public class DateIntervalFormatTest extends junit.framework.TestCase { 32 private static final long MINUTE = 60 * 1000; 33 private static final long HOUR = 60 * MINUTE; 34 private static final long DAY = 24 * HOUR; 35 private static final long MONTH = 31 * DAY; 36 private static final long YEAR = 12 * MONTH; 37 38 // These are the old CTS tests for DateIntervalFormat.formatDateRange. test_formatDateInterval()39 public void test_formatDateInterval() throws Exception { 40 // Require min ICU version 70 to provide the expected locale data. 41 if (VersionInfo.ICU_VERSION.getMajor() < 70) { 42 return; 43 } 44 TimeZone tz = TimeZone.getTimeZone("America/Los_Angeles"); 45 46 Calendar c = Calendar.getInstance(tz, ULocale.US); 47 c.set(Calendar.MONTH, Calendar.JANUARY); 48 c.set(Calendar.DAY_OF_MONTH, 19); 49 c.set(Calendar.HOUR_OF_DAY, 3); 50 c.set(Calendar.MINUTE, 30); 51 c.set(Calendar.SECOND, 15); 52 c.set(Calendar.MILLISECOND, 0); 53 long timeWithCurrentYear = c.getTimeInMillis(); 54 55 c.set(Calendar.YEAR, 2009); 56 long fixedTime = c.getTimeInMillis(); 57 58 c.set(Calendar.MINUTE, 0); 59 c.set(Calendar.SECOND, 0); 60 long onTheHour = c.getTimeInMillis(); 61 62 long noonDuration = (8 * 60 + 30) * 60 * 1000 - 15 * 1000; 63 long midnightDuration = (3 * 60 + 30) * 60 * 1000 + 15 * 1000; 64 65 ULocale de_DE = new ULocale("de", "DE"); 66 ULocale en_US = new ULocale("en", "US"); 67 ULocale es_ES = new ULocale("es", "ES"); 68 ULocale es_US = new ULocale("es", "US"); 69 70 assertEquals("Monday", formatDateRange(en_US, tz, fixedTime, fixedTime + HOUR, FORMAT_SHOW_WEEKDAY)); 71 assertEquals("January 19", formatDateRange(en_US, tz, timeWithCurrentYear, timeWithCurrentYear + HOUR, FORMAT_SHOW_DATE)); 72 assertEquals("3:30 AM", formatDateRange(en_US, tz, fixedTime, fixedTime, FORMAT_SHOW_TIME)); 73 assertEquals("January 19, 2009", formatDateRange(en_US, tz, fixedTime, fixedTime + HOUR, FORMAT_SHOW_YEAR)); 74 assertEquals("January 19", formatDateRange(en_US, tz, fixedTime, fixedTime + HOUR, FORMAT_NO_YEAR)); 75 assertEquals("January", formatDateRange(en_US, tz, timeWithCurrentYear, timeWithCurrentYear + HOUR, FORMAT_NO_MONTH_DAY)); 76 assertEquals("3:30 AM", formatDateRange(en_US, tz, fixedTime, fixedTime, FORMAT_12HOUR | FORMAT_SHOW_TIME)); 77 assertEquals("03:30", formatDateRange(en_US, tz, fixedTime, fixedTime, FORMAT_24HOUR | FORMAT_SHOW_TIME)); 78 assertEquals("3:30 AM", formatDateRange(en_US, tz, fixedTime, fixedTime, FORMAT_12HOUR /*| FORMAT_CAP_AMPM*/ | FORMAT_SHOW_TIME)); 79 assertEquals("12:00 PM", formatDateRange(en_US, tz, fixedTime + noonDuration, fixedTime + noonDuration, FORMAT_12HOUR | FORMAT_SHOW_TIME)); 80 assertEquals("12:00 PM", formatDateRange(en_US, tz, fixedTime + noonDuration, fixedTime + noonDuration, FORMAT_12HOUR | FORMAT_SHOW_TIME /*| FORMAT_CAP_NOON*/)); 81 assertEquals("12:00 PM", formatDateRange(en_US, tz, fixedTime + noonDuration, fixedTime + noonDuration, FORMAT_12HOUR /*| FORMAT_NO_NOON*/ | FORMAT_SHOW_TIME)); 82 assertEquals("12:00 AM", formatDateRange(en_US, tz, fixedTime - midnightDuration, fixedTime - midnightDuration, FORMAT_12HOUR | FORMAT_SHOW_TIME /*| FORMAT_NO_MIDNIGHT*/)); 83 assertEquals("3:30 AM", formatDateRange(en_US, tz, fixedTime, fixedTime, FORMAT_SHOW_TIME | FORMAT_UTC)); 84 assertEquals("3 AM", formatDateRange(en_US, tz, onTheHour, onTheHour, FORMAT_SHOW_TIME | FORMAT_ABBREV_TIME)); 85 assertEquals("Mon", formatDateRange(en_US, tz, fixedTime, fixedTime + HOUR, FORMAT_SHOW_WEEKDAY | FORMAT_ABBREV_WEEKDAY)); 86 assertEquals("Jan 19", formatDateRange(en_US, tz, timeWithCurrentYear, timeWithCurrentYear + HOUR, FORMAT_SHOW_DATE | FORMAT_ABBREV_MONTH)); 87 assertEquals("Jan 19", formatDateRange(en_US, tz, timeWithCurrentYear, timeWithCurrentYear + HOUR, FORMAT_SHOW_DATE | FORMAT_ABBREV_ALL)); 88 89 assertEquals("1/19/2009", formatDateRange(en_US, tz, fixedTime, fixedTime + 3 * HOUR, FORMAT_SHOW_YEAR | FORMAT_NUMERIC_DATE)); 90 assertEquals("1/19/2009 – 1/22/2009", formatDateRange(en_US, tz, fixedTime, fixedTime + 3 * DAY, FORMAT_SHOW_YEAR | FORMAT_NUMERIC_DATE)); 91 assertEquals("1/19/2009 – 4/22/2009", formatDateRange(en_US, tz, fixedTime, fixedTime + 3 * MONTH, FORMAT_SHOW_YEAR | FORMAT_NUMERIC_DATE)); 92 assertEquals("1/19/2009 – 2/9/2012", formatDateRange(en_US, tz, fixedTime, fixedTime + 3 * YEAR, FORMAT_SHOW_YEAR | FORMAT_NUMERIC_DATE)); 93 94 assertEquals("19.1.2009", formatDateRange(de_DE, tz, fixedTime, fixedTime + HOUR, FORMAT_SHOW_YEAR | FORMAT_NUMERIC_DATE)); 95 assertEquals("19.–22.01.2009", formatDateRange(de_DE, tz, fixedTime, fixedTime + 3 * DAY, FORMAT_SHOW_YEAR | FORMAT_NUMERIC_DATE)); 96 assertEquals("19.01. – 22.04.2009", formatDateRange(de_DE, tz, fixedTime, fixedTime + 3 * MONTH, FORMAT_SHOW_YEAR | FORMAT_NUMERIC_DATE)); 97 assertEquals("19.01.2009 – 09.02.2012", formatDateRange(de_DE, tz, fixedTime, fixedTime + 3 * YEAR, FORMAT_SHOW_YEAR | FORMAT_NUMERIC_DATE)); 98 99 assertEquals("19/1/2009", formatDateRange(es_US, tz, fixedTime, fixedTime + HOUR, FORMAT_SHOW_YEAR | FORMAT_NUMERIC_DATE)); 100 assertEquals("19/1/2009–22/1/2009", formatDateRange(es_US, tz, fixedTime, fixedTime + 3 * DAY, FORMAT_SHOW_YEAR | FORMAT_NUMERIC_DATE)); 101 assertEquals("19/1/2009–22/4/2009", formatDateRange(es_US, tz, fixedTime, fixedTime + 3 * MONTH, FORMAT_SHOW_YEAR | FORMAT_NUMERIC_DATE)); 102 assertEquals("19/1/2009–9/2/2012", formatDateRange(es_US, tz, fixedTime, fixedTime + 3 * YEAR, FORMAT_SHOW_YEAR | FORMAT_NUMERIC_DATE)); 103 104 assertEquals("19/1/2009", formatDateRange(es_ES, tz, fixedTime, fixedTime + HOUR, FORMAT_SHOW_YEAR | FORMAT_NUMERIC_DATE)); 105 assertEquals("19/1/2009 – 22/1/2009", formatDateRange(es_ES, tz, fixedTime, fixedTime + 3 * DAY, FORMAT_SHOW_YEAR | FORMAT_NUMERIC_DATE)); 106 assertEquals("19/1/2009 – 22/4/2009", formatDateRange(es_ES, tz, fixedTime, fixedTime + 3 * MONTH, FORMAT_SHOW_YEAR | FORMAT_NUMERIC_DATE)); 107 assertEquals("19/1/2009 – 9/2/2012", formatDateRange(es_ES, tz, fixedTime, fixedTime + 3 * YEAR, FORMAT_SHOW_YEAR | FORMAT_NUMERIC_DATE)); 108 109 // These are some random other test cases I came up with. 110 111 assertEquals("January 19 – 22, 2009", formatDateRange(en_US, tz, fixedTime, fixedTime + 3 * DAY, 0)); 112 assertEquals("Jan 19 – 22, 2009", formatDateRange(en_US, tz, fixedTime, fixedTime + 3 * DAY, FORMAT_SHOW_DATE | FORMAT_ABBREV_ALL)); 113 assertEquals("Mon, Jan 19 – Thu, Jan 22, 2009", formatDateRange(en_US, tz, fixedTime, fixedTime + 3 * DAY, FORMAT_SHOW_WEEKDAY | FORMAT_ABBREV_ALL)); 114 assertEquals("Monday, January 19 – Thursday, January 22, 2009", formatDateRange(en_US, tz, fixedTime, fixedTime + 3 * DAY, FORMAT_SHOW_WEEKDAY)); 115 116 assertEquals("January 19 – April 22, 2009", formatDateRange(en_US, tz, fixedTime, fixedTime + 3 * MONTH, 0)); 117 assertEquals("Jan 19 – Apr 22, 2009", formatDateRange(en_US, tz, fixedTime, fixedTime + 3 * MONTH, FORMAT_SHOW_DATE | FORMAT_ABBREV_ALL)); 118 assertEquals("Mon, Jan 19 – Wed, Apr 22, 2009", formatDateRange(en_US, tz, fixedTime, fixedTime + 3 * MONTH, FORMAT_SHOW_WEEKDAY | FORMAT_ABBREV_ALL)); 119 assertEquals("January – April 2009", formatDateRange(en_US, tz, fixedTime, fixedTime + 3 * MONTH, FORMAT_NO_MONTH_DAY)); 120 121 assertEquals("Jan 19, 2009 – Feb 9, 2012", formatDateRange(en_US, tz, fixedTime, fixedTime + 3 * YEAR, FORMAT_SHOW_DATE | FORMAT_ABBREV_ALL)); 122 assertEquals("Jan 2009 – Feb 2012", formatDateRange(en_US, tz, fixedTime, fixedTime + 3 * YEAR, FORMAT_NO_MONTH_DAY | FORMAT_ABBREV_ALL)); 123 assertEquals("January 19, 2009 – February 9, 2012", formatDateRange(en_US, tz, fixedTime, fixedTime + 3 * YEAR, 0)); 124 assertEquals("Monday, January 19, 2009 – Thursday, February 9, 2012", formatDateRange(en_US, tz, fixedTime, fixedTime + 3 * YEAR, FORMAT_SHOW_WEEKDAY)); 125 126 // The same tests but for de_DE. 127 128 assertEquals("19.–22. Januar 2009", formatDateRange(de_DE, tz, fixedTime, fixedTime + 3 * DAY, 0)); 129 assertEquals("19.–22. Jan. 2009", formatDateRange(de_DE, tz, fixedTime, fixedTime + 3 * DAY, FORMAT_SHOW_DATE | FORMAT_ABBREV_ALL)); 130 assertEquals("Mo., 19. – Do., 22. Jan. 2009", formatDateRange(de_DE, tz, fixedTime, fixedTime + 3 * DAY, FORMAT_SHOW_WEEKDAY | FORMAT_ABBREV_ALL)); 131 assertEquals("Montag, 19. – Donnerstag, 22. Januar 2009", formatDateRange(de_DE, tz, fixedTime, fixedTime + 3 * DAY, FORMAT_SHOW_WEEKDAY)); 132 133 assertEquals("19. Januar – 22. April 2009", formatDateRange(de_DE, tz, fixedTime, fixedTime + 3 * MONTH, 0)); 134 assertEquals("19. Jan. – 22. Apr. 2009", formatDateRange(de_DE, tz, fixedTime, fixedTime + 3 * MONTH, FORMAT_SHOW_DATE | FORMAT_ABBREV_ALL)); 135 assertEquals("Mo., 19. Jan. – Mi., 22. Apr. 2009", formatDateRange(de_DE, tz, fixedTime, fixedTime + 3 * MONTH, FORMAT_SHOW_WEEKDAY | FORMAT_ABBREV_ALL)); 136 assertEquals("Januar–April 2009", formatDateRange(de_DE, tz, fixedTime, fixedTime + 3 * MONTH, FORMAT_NO_MONTH_DAY)); 137 138 assertEquals("19. Jan. 2009 – 9. Feb. 2012", formatDateRange(de_DE, tz, fixedTime, fixedTime + 3 * YEAR, FORMAT_SHOW_DATE | FORMAT_ABBREV_ALL)); 139 assertEquals("Jan. 2009 – Feb. 2012", formatDateRange(de_DE, tz, fixedTime, fixedTime + 3 * YEAR, FORMAT_NO_MONTH_DAY | FORMAT_ABBREV_ALL)); 140 assertEquals("19. Januar 2009 – 9. Februar 2012", formatDateRange(de_DE, tz, fixedTime, fixedTime + 3 * YEAR, 0)); 141 assertEquals("Montag, 19. Januar 2009 – Donnerstag, 9. Februar 2012", formatDateRange(de_DE, tz, fixedTime, fixedTime + 3 * YEAR, FORMAT_SHOW_WEEKDAY)); 142 143 // The same tests but for es_US. 144 145 assertEquals("19–22 de enero de 2009", formatDateRange(es_US, tz, fixedTime, fixedTime + 3 * DAY, 0)); 146 assertEquals("19–22 de ene de 2009", formatDateRange(es_US, tz, fixedTime, fixedTime + 3 * DAY, FORMAT_SHOW_DATE | FORMAT_ABBREV_ALL)); 147 assertEquals("lun, 19 de ene – jue, 22 de ene de 2009", formatDateRange(es_US, tz, fixedTime, fixedTime + 3 * DAY, FORMAT_SHOW_WEEKDAY | FORMAT_ABBREV_ALL)); 148 assertEquals("lunes, 19 de enero – jueves, 22 de enero de 2009", formatDateRange(es_US, tz, fixedTime, fixedTime + 3 * DAY, FORMAT_SHOW_WEEKDAY)); 149 150 assertEquals("19 de enero – 22 de abril de 2009", formatDateRange(es_US, tz, fixedTime, fixedTime + 3 * MONTH, 0)); 151 assertEquals("19 de ene – 22 de abr 2009", formatDateRange(es_US, tz, fixedTime, fixedTime + 3 * MONTH, FORMAT_SHOW_DATE | FORMAT_ABBREV_ALL)); 152 assertEquals("lun, 19 de ene – mié, 22 de abr de 2009", formatDateRange(es_US, tz, fixedTime, fixedTime + 3 * MONTH, FORMAT_SHOW_WEEKDAY | FORMAT_ABBREV_ALL)); 153 assertEquals("enero–abril de 2009", formatDateRange(es_US, tz, fixedTime, fixedTime + 3 * MONTH, FORMAT_NO_MONTH_DAY)); 154 155 assertEquals("19 de ene de 2009 – 9 de feb de 2012", formatDateRange(es_US, tz, fixedTime, fixedTime + 3 * YEAR, FORMAT_SHOW_DATE | FORMAT_ABBREV_ALL)); 156 assertEquals("ene de 2009 – feb de 2012", formatDateRange(es_US, tz, fixedTime, fixedTime + 3 * YEAR, FORMAT_NO_MONTH_DAY | FORMAT_ABBREV_ALL)); 157 assertEquals("19 de enero de 2009 – 9 de febrero de 2012", formatDateRange(es_US, tz, fixedTime, fixedTime + 3 * YEAR, 0)); 158 assertEquals("lunes, 19 de enero de 2009 – jueves, 9 de febrero de 2012", formatDateRange(es_US, tz, fixedTime, fixedTime + 3 * YEAR, FORMAT_SHOW_WEEKDAY)); 159 160 // The same tests but for es_ES. 161 162 assertEquals("19–22 de enero de 2009", formatDateRange(es_ES, tz, fixedTime, fixedTime + 3 * DAY, 0)); 163 assertEquals("19–22 ene 2009", formatDateRange(es_ES, tz, fixedTime, fixedTime + 3 * DAY, FORMAT_SHOW_DATE | FORMAT_ABBREV_ALL)); 164 assertEquals("lun, 19 ene – jue, 22 ene 2009", formatDateRange(es_ES, tz, fixedTime, fixedTime + 3 * DAY, FORMAT_SHOW_WEEKDAY | FORMAT_ABBREV_ALL)); 165 assertEquals("lunes, 19 de enero – jueves, 22 de enero de 2009", formatDateRange(es_ES, tz, fixedTime, fixedTime + 3 * DAY, FORMAT_SHOW_WEEKDAY)); 166 167 assertEquals("19 de enero – 22 de abril de 2009", formatDateRange(es_ES, tz, fixedTime, fixedTime + 3 * MONTH, 0)); 168 assertEquals("19 ene – 22 abr 2009", formatDateRange(es_ES, tz, fixedTime, fixedTime + 3 * MONTH, FORMAT_SHOW_DATE | FORMAT_ABBREV_ALL)); 169 assertEquals("lun, 19 ene – mié, 22 abr 2009", formatDateRange(es_ES, tz, fixedTime, fixedTime + 3 * MONTH, FORMAT_SHOW_WEEKDAY | FORMAT_ABBREV_ALL)); 170 assertEquals("enero–abril de 2009", formatDateRange(es_ES, tz, fixedTime, fixedTime + 3 * MONTH, FORMAT_NO_MONTH_DAY)); 171 172 assertEquals("19 ene 2009 – 9 feb 2012", formatDateRange(es_ES, tz, fixedTime, fixedTime + 3 * YEAR, FORMAT_SHOW_DATE | FORMAT_ABBREV_ALL)); 173 assertEquals("ene 2009 – feb 2012", formatDateRange(es_ES, tz, fixedTime, fixedTime + 3 * YEAR, FORMAT_NO_MONTH_DAY | FORMAT_ABBREV_ALL)); 174 assertEquals("19 de enero de 2009 – 9 de febrero de 2012", formatDateRange(es_ES, tz, fixedTime, fixedTime + 3 * YEAR, 0)); 175 assertEquals("lunes, 19 de enero de 2009 – jueves, 9 de febrero de 2012", formatDateRange(es_ES, tz, fixedTime, fixedTime + 3 * YEAR, FORMAT_SHOW_WEEKDAY)); 176 } 177 178 // http://b/8862241 - we should be able to format dates past 2038. 179 // See also http://code.google.com/p/android/issues/detail?id=13050. test8862241()180 public void test8862241() throws Exception { 181 ULocale l = ULocale.US; 182 TimeZone tz = TimeZone.getTimeZone("America/Los_Angeles"); 183 Calendar c = Calendar.getInstance(tz, l); 184 c.clear(); 185 c.set(2042, Calendar.JANUARY, 19, 3, 30); 186 long jan_19_2042 = c.getTimeInMillis(); 187 c.set(2046, Calendar.OCTOBER, 4, 3, 30); 188 long oct_4_2046 = c.getTimeInMillis(); 189 int flags = FORMAT_SHOW_DATE | FORMAT_ABBREV_ALL; 190 assertEquals("Jan 19, 2042 – Oct 4, 2046", formatDateRange(l, tz, jan_19_2042, oct_4_2046, flags)); 191 } 192 193 // http://b/10089890 - we should take the given time zone into account. test10089890()194 public void test10089890() throws Exception { 195 ULocale l = ULocale.US; 196 TimeZone utc = TimeZone.getTimeZone("UTC"); 197 TimeZone pacific = TimeZone.getTimeZone("America/Los_Angeles"); 198 int flags = FORMAT_SHOW_DATE | FORMAT_ABBREV_ALL | FORMAT_SHOW_TIME | FORMAT_24HOUR; 199 200 // The Unix epoch is UTC, so 0 is 1970-01-01T00:00Z... 201 assertEquals("Jan 1, 1970, 00:00 – Jan 2, 1970, 00:00", formatDateRange(l, utc, 0, DAY + 1, flags)); 202 // But MTV is hours behind, so 0 was still the afternoon of the previous day... 203 assertEquals("Dec 31, 1969, 16:00 – Jan 1, 1970, 16:00", formatDateRange(l, pacific, 0, DAY, flags)); 204 } 205 206 // http://b/10318326 - we can drop the minutes in a 12-hour time if they're zero, 207 // but not if we're using the 24-hour clock. That is: "4 PM" is reasonable, "16" is not. test10318326()208 public void test10318326() throws Exception { 209 long midnight = 0; 210 long teaTime = 16 * HOUR; 211 212 int time12 = FORMAT_12HOUR | FORMAT_SHOW_TIME; 213 int time24 = FORMAT_24HOUR | FORMAT_SHOW_TIME; 214 int abbr12 = time12 | FORMAT_ABBREV_ALL; 215 int abbr24 = time24 | FORMAT_ABBREV_ALL; 216 217 ULocale l = ULocale.US; 218 TimeZone utc = TimeZone.getTimeZone("UTC"); 219 220 // Full length on-the-hour times. 221 assertEquals("00:00", formatDateRange(l, utc, midnight, midnight, time24)); 222 assertEquals("12:00 AM", formatDateRange(l, utc, midnight, midnight, time12)); 223 assertEquals("16:00", formatDateRange(l, utc, teaTime, teaTime, time24)); 224 assertEquals("4:00 PM", formatDateRange(l, utc, teaTime, teaTime, time12)); 225 226 // Abbreviated on-the-hour times. 227 assertEquals("00:00", formatDateRange(l, utc, midnight, midnight, abbr24)); 228 assertEquals("12 AM", formatDateRange(l, utc, midnight, midnight, abbr12)); 229 assertEquals("16:00", formatDateRange(l, utc, teaTime, teaTime, abbr24)); 230 assertEquals("4 PM", formatDateRange(l, utc, teaTime, teaTime, abbr12)); 231 232 // Abbreviated on-the-hour ranges. 233 assertEquals("00:00 – 16:00", formatDateRange(l, utc, midnight, teaTime, abbr24)); 234 assertEquals("12 AM – 4 PM", formatDateRange(l, utc, midnight, teaTime, abbr12)); 235 236 // Abbreviated mixed ranges. 237 assertEquals("00:00 – 16:01", formatDateRange(l, utc, midnight, teaTime + MINUTE, abbr24)); 238 assertEquals("12:00 AM – 4:01 PM", formatDateRange(l, utc, midnight, teaTime + MINUTE, abbr12)); 239 } 240 241 // http://b/10560853 - when the time is not displayed, an end time 0 ms into the next day is 242 // considered to belong to the previous day. test10560853_when_time_not_displayed()243 public void test10560853_when_time_not_displayed() throws Exception { 244 ULocale l = ULocale.US; 245 TimeZone utc = TimeZone.getTimeZone("UTC"); 246 247 long midnight = 0; 248 long midnightNext = 1 * DAY; 249 250 int flags = FORMAT_SHOW_DATE | FORMAT_SHOW_WEEKDAY; 251 252 // An all-day event runs until 0 milliseconds into the next day, but is formatted as if it's 253 // just the first day. 254 assertEquals("Thursday, January 1, 1970", formatDateRange(l, utc, midnight, midnightNext, flags)); 255 256 // Run one millisecond over, though, and you're into the next day. 257 long nextMorning = 1 * DAY + 1; 258 assertEquals("Thursday, January 1 – Friday, January 2, 1970", formatDateRange(l, utc, midnight, nextMorning, flags)); 259 260 // But the same reasoning applies for that day. 261 long nextMidnight = 2 * DAY; 262 assertEquals("Thursday, January 1 – Friday, January 2, 1970", formatDateRange(l, utc, midnight, nextMidnight, flags)); 263 } 264 265 // http://b/10560853 - when the start and end times are otherwise on the same day, 266 // an end time 0 ms into the next day is considered to belong to the previous day. test10560853_for_single_day_events()267 public void test10560853_for_single_day_events() throws Exception { 268 ULocale l = ULocale.US; 269 TimeZone utc = TimeZone.getTimeZone("UTC"); 270 271 int flags = FORMAT_SHOW_TIME | FORMAT_24HOUR | FORMAT_SHOW_DATE; 272 273 assertEquals("January 1, 1970, 22:00 – 00:00", formatDateRange(l, utc, 22 * HOUR, 24 * HOUR, flags)); 274 assertEquals("January 1, 1970, 22:00 – January 2, 1970, 00:30", formatDateRange(l, utc, 22 * HOUR, 24 * HOUR + 30 * MINUTE, flags)); 275 } 276 277 // The fix for http://b/10560853 didn't work except for the day around the epoch, which was 278 // all the unit test checked! test_single_day_events_later_than_epoch()279 public void test_single_day_events_later_than_epoch() throws Exception { 280 ULocale l = ULocale.US; 281 TimeZone utc = TimeZone.getTimeZone("UTC"); 282 283 int flags = FORMAT_SHOW_TIME | FORMAT_24HOUR | FORMAT_SHOW_DATE; 284 285 Calendar c = Calendar.getInstance(utc, l); 286 c.clear(); 287 c.set(1980, Calendar.JANUARY, 1, 0, 0); 288 long jan_1_1980 = c.getTimeInMillis(); 289 assertEquals("January 1, 1980, 22:00 – 00:00", 290 formatDateRange(l, utc, jan_1_1980 + 22 * HOUR, jan_1_1980 + 24 * HOUR, flags)); 291 assertEquals("January 1, 1980, 22:00 – January 2, 1980, 00:30", 292 formatDateRange(l, utc, jan_1_1980 + 22 * HOUR, jan_1_1980 + 24 * HOUR + 30 * MINUTE, flags)); 293 } 294 295 // The fix for http://b/10560853 didn't work except for UTC, which was 296 // all the unit test checked! test_single_day_events_not_in_UTC()297 public void test_single_day_events_not_in_UTC() throws Exception { 298 ULocale l = ULocale.US; 299 TimeZone pacific = TimeZone.getTimeZone("America/Los_Angeles"); 300 301 int flags = FORMAT_SHOW_TIME | FORMAT_24HOUR | FORMAT_SHOW_DATE; 302 303 Calendar c = Calendar.getInstance(pacific, l); 304 c.clear(); 305 c.set(1980, Calendar.JANUARY, 1, 0, 0); 306 long jan_1_1980 = c.getTimeInMillis(); 307 assertEquals("January 1, 1980, 22:00 – 00:00", 308 formatDateRange(l, pacific, jan_1_1980 + 22 * HOUR, jan_1_1980 + 24 * HOUR, flags)); 309 310 c.set(1980, Calendar.JULY, 1, 0, 0); 311 long jul_1_1980 = c.getTimeInMillis(); 312 assertEquals("July 1, 1980, 22:00 – 00:00", 313 formatDateRange(l, pacific, jul_1_1980 + 22 * HOUR, jul_1_1980 + 24 * HOUR, flags)); 314 } 315 316 // http://b/10209343 - even if the caller didn't explicitly ask us to include the year, 317 // we should do so for years other than the current year. test10209343_when_not_this_year()318 public void test10209343_when_not_this_year() { 319 ULocale l = ULocale.US; 320 TimeZone utc = TimeZone.getTimeZone("UTC"); 321 322 int flags = FORMAT_SHOW_DATE | FORMAT_SHOW_WEEKDAY | FORMAT_SHOW_TIME | FORMAT_24HOUR; 323 324 assertEquals("Thursday, January 1, 1970, 00:00", formatDateRange(l, utc, 0L, 0L, flags)); 325 326 long t1833 = ((long) Integer.MIN_VALUE + Integer.MIN_VALUE) * 1000L; 327 assertEquals("Sunday, November 24, 1833, 17:31", formatDateRange(l, utc, t1833, t1833, flags)); 328 329 long t1901 = Integer.MIN_VALUE * 1000L; 330 assertEquals("Friday, December 13, 1901, 20:45", formatDateRange(l, utc, t1901, t1901, flags)); 331 332 long t2038 = Integer.MAX_VALUE * 1000L; 333 assertEquals("Tuesday, January 19, 2038, 03:14", formatDateRange(l, utc, t2038, t2038, flags)); 334 335 long t2106 = (2L + Integer.MAX_VALUE + Integer.MAX_VALUE) * 1000L; 336 assertEquals("Sunday, February 7, 2106, 06:28", formatDateRange(l, utc, t2106, t2106, flags)); 337 } 338 339 // http://b/10209343 - for the current year, we should honor the FORMAT_SHOW_YEAR flags. test10209343_when_this_year()340 public void test10209343_when_this_year() { 341 // Construct a date in the current year (whenever the test happens to be run). 342 ULocale l = ULocale.US; 343 TimeZone utc = TimeZone.getTimeZone("UTC"); 344 Calendar c = Calendar.getInstance(utc, l); 345 c.set(Calendar.MONTH, Calendar.FEBRUARY); 346 c.set(Calendar.DAY_OF_MONTH, 10); 347 c.set(Calendar.HOUR_OF_DAY, 0); 348 long thisYear = c.getTimeInMillis(); 349 350 // You don't get the year if it's this year... 351 assertEquals("February 10", formatDateRange(l, utc, thisYear, thisYear, FORMAT_SHOW_DATE)); 352 353 // ...unless you explicitly ask for it. 354 assertEquals(String.format("February 10, %d", c.get(Calendar.YEAR)), 355 formatDateRange(l, utc, thisYear, thisYear, FORMAT_SHOW_DATE | FORMAT_SHOW_YEAR)); 356 357 // ...or it's not actually this year... 358 Calendar c2 = (Calendar) c.clone(); 359 c2.set(Calendar.YEAR, 1980); 360 long oldYear = c2.getTimeInMillis(); 361 assertEquals("February 10, 1980", formatDateRange(l, utc, oldYear, oldYear, FORMAT_SHOW_DATE)); 362 363 // (But you can disable that!) 364 assertEquals("February 10", formatDateRange(l, utc, oldYear, oldYear, FORMAT_SHOW_DATE | FORMAT_NO_YEAR)); 365 366 // ...or the start and end years aren't the same... 367 assertEquals(String.format("February 10, 1980 – February 10, %d", c.get(Calendar.YEAR)), 368 formatDateRange(l, utc, oldYear, thisYear, FORMAT_SHOW_DATE)); 369 370 // (And you can't avoid that --- icu4c steps in and overrides you.) 371 assertEquals(String.format("February 10, 1980 – February 10, %d", c.get(Calendar.YEAR)), 372 formatDateRange(l, utc, oldYear, thisYear, FORMAT_SHOW_DATE | FORMAT_NO_YEAR)); 373 } 374 375 // http://b/8467515 - yet another y2k38 bug report. test8467515()376 public void test8467515() throws Exception { 377 ULocale l = ULocale.US; 378 TimeZone utc = TimeZone.getTimeZone("UTC"); 379 int flags = FORMAT_SHOW_DATE | FORMAT_SHOW_WEEKDAY | FORMAT_SHOW_YEAR | FORMAT_ABBREV_MONTH | FORMAT_ABBREV_WEEKDAY; 380 long t; 381 382 Calendar calendar = Calendar.getInstance(utc, l); 383 calendar.clear(); 384 385 calendar.set(2038, Calendar.JANUARY, 19, 12, 0, 0); 386 t = calendar.getTimeInMillis(); 387 assertEquals("Tue, Jan 19, 2038", formatDateRange(l, utc, t, t, flags)); 388 389 calendar.set(1900, Calendar.JANUARY, 1, 0, 0, 0); 390 t = calendar.getTimeInMillis(); 391 assertEquals("Mon, Jan 1, 1900", formatDateRange(l, utc, t, t, flags)); 392 } 393 394 // http://b/12004664 test12004664()395 public void test12004664() throws Exception { 396 TimeZone utc = TimeZone.getTimeZone("UTC"); 397 Calendar c = Calendar.getInstance(utc, ULocale.US); 398 c.clear(); 399 c.set(Calendar.YEAR, 1980); 400 c.set(Calendar.MONTH, Calendar.FEBRUARY); 401 c.set(Calendar.DAY_OF_MONTH, 10); 402 c.set(Calendar.HOUR_OF_DAY, 0); 403 long thisYear = c.getTimeInMillis(); 404 405 int flags = FORMAT_SHOW_DATE | FORMAT_SHOW_WEEKDAY | FORMAT_SHOW_YEAR; 406 assertEquals("Sunday, February 10, 1980", formatDateRange(new ULocale("en", "US"), utc, thisYear, thisYear, flags)); 407 408 // If we supported non-Gregorian calendars, this is what that we'd expect for these ULocales. 409 // This is really the correct behavior, but since java.util.Calendar currently only supports 410 // the Gregorian calendar, we want to deliberately force icu4c to agree, otherwise we'd have 411 // a mix of calendars throughout an app's UI depending on whether Java or native code formatted 412 // the date. 413 // assertEquals("یکشنبه ۲۱ بهمن ۱۳۵۸ ه.ش.", formatDateRange(new ULocale("fa"), utc, thisYear, thisYear, flags)); 414 // assertEquals("AP ۱۳۵۸ سلواغه ۲۱, یکشنبه", formatDateRange(new ULocale("ps"), utc, thisYear, thisYear, flags)); 415 // assertEquals("วันอาทิตย์ 10 กุมภาพันธ์ 2523", formatDateRange(new ULocale("th"), utc, thisYear, thisYear, flags)); 416 417 // For now, here are the localized Gregorian strings instead... 418 assertEquals("یکشنبه ۱۰ فوریهٔ ۱۹۸۰", formatDateRange(new ULocale("fa"), utc, thisYear, thisYear, flags)); 419 assertEquals("يونۍ د ۱۹۸۰ د فبروري ۱۰", formatDateRange(new ULocale("ps"), utc, thisYear, thisYear, flags)); 420 assertEquals("วันอาทิตย์ที่ 10 กุมภาพันธ์ ค.ศ. 1980", formatDateRange(new ULocale("th"), utc, thisYear, thisYear, flags)); 421 } 422 423 // http://b/13234532 test13234532()424 public void test13234532() throws Exception { 425 ULocale l = ULocale.US; 426 TimeZone utc = TimeZone.getTimeZone("UTC"); 427 428 int flags = FORMAT_SHOW_TIME | FORMAT_ABBREV_ALL | FORMAT_12HOUR; 429 430 assertEquals("10 – 11 AM", formatDateRange(l, utc, 10*HOUR, 11*HOUR, flags)); 431 assertEquals("11 AM – 1 PM", formatDateRange(l, utc, 11*HOUR, 13*HOUR, flags)); 432 assertEquals("2 – 3 PM", formatDateRange(l, utc, 14*HOUR, 15*HOUR, flags)); 433 } 434 435 // http://b/20708022 testEndOfDayOnLastDayOfMonth()436 public void testEndOfDayOnLastDayOfMonth() throws Exception { 437 final ULocale locale = new ULocale("en"); 438 final TimeZone timeZone = TimeZone.getTimeZone("UTC"); 439 440 assertEquals("11:00 PM – 12:00 AM", formatDateRange(locale, timeZone, 441 1430434800000L, 1430438400000L, FORMAT_SHOW_TIME)); 442 } 443 444 // http://b/68847519 testEndAtMidnight_dateAndTime()445 public void testEndAtMidnight_dateAndTime() { 446 BiFunction<Long, Long, String> fmt = (from, to) -> formatDateRange( 447 ENGLISH, GMT_ZONE, from, to, FORMAT_SHOW_DATE | FORMAT_SHOW_TIME | FORMAT_24HOUR); 448 // If we're showing times and the end-point is midnight the following day, we want the 449 // behaviour of suppressing the date for the end... 450 assertEquals("February 27, 2007, 04:00 – 00:00", fmt.apply(1172548800000L, 1172620800000L)); 451 // ...unless the start-point is also midnight, in which case we need dates to disambiguate. 452 assertEquals("February 27, 2007, 00:00 – February 28, 2007, 00:00", 453 fmt.apply(1172534400000L, 1172620800000L)); 454 // We want to show the date if the end-point is a millisecond after midnight the following 455 // day, or if it is exactly midnight the day after that. 456 assertEquals("February 27, 2007, 04:00 – February 28, 2007, 00:00", 457 fmt.apply(1172548800000L, 1172620800001L)); 458 assertEquals("February 27, 2007, 04:00 – March 1, 2007, 00:00", 459 fmt.apply(1172548800000L, 1172707200000L)); 460 // We want to show the date if the start-point is anything less than a minute after midnight, 461 // since that gets displayed as midnight... 462 assertEquals("February 27, 2007, 00:00 – February 28, 2007, 00:00", 463 fmt.apply(1172534459999L, 1172620800000L)); 464 // ...but not if it is exactly one minute after midnight. 465 assertEquals("February 27, 2007, 00:01 – 00:00", fmt.apply(1172534460000L, 1172620800000L)); 466 } 467 468 // http://b/68847519 testEndAtMidnight_dateOnly()469 public void testEndAtMidnight_dateOnly() { 470 BiFunction<Long, Long, String> fmt = (from, to) -> formatDateRange( 471 ENGLISH, GMT_ZONE, from, to, FORMAT_SHOW_DATE); 472 // If we're only showing dates and the end-point is midnight of any day, we want the 473 // behaviour of showing an end date one earlier. So if the end-point is March 2, 2007 00:00, 474 // show March 1, 2007 instead (whether the start-point is midnight or not). 475 assertEquals("February 27 – March 1, 2007", fmt.apply(1172534400000L, 1172793600000L)); 476 assertEquals("February 27 – March 1, 2007", fmt.apply(1172548800000L, 1172793600000L)); 477 // We want to show the true date if the end-point is a millisecond after midnight. 478 assertEquals("February 27 – March 2, 2007", fmt.apply(1172534400000L, 1172793600001L)); 479 480 // 2006-02-27 00:00:00.000 GMT - 2007-03-02 00:00:00.000 GMT 481 assertEquals("February 27, 2006 – March 1, 2007", fmt.apply(1140998400000L, 1172793600000L)); 482 483 // Spans a leap year's Feb 29th. 484 assertEquals("February 27 – March 1, 2004", fmt.apply(1077840000000L, 1078185600000L)); 485 } 486 } 487