1 /* 2 * Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. 8 * 9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 */ 23 24 /* 25 * This file is available under and governed by the GNU General Public 26 * License version 2 only, as published by the Free Software Foundation. 27 * However, the following notice accompanied the original version of this 28 * file: 29 * 30 * Copyright (c) 2010-2013, Stephen Colebourne & Michael Nascimento Santos 31 * 32 * All rights reserved. 33 * 34 * Redistribution and use in source and binary forms, with or without 35 * modification, are permitted provided that the following conditions are met: 36 * 37 * * Redistributions of source code must retain the above copyright notice, 38 * this list of conditions and the following disclaimer. 39 * 40 * * Redistributions in binary form must reproduce the above copyright notice, 41 * this list of conditions and the following disclaimer in the documentation 42 * and/or other materials provided with the distribution. 43 * 44 * * Neither the name of JSR-310 nor the names of its contributors 45 * may be used to endorse or promote products derived from this software 46 * without specific prior written permission. 47 * 48 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 49 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 50 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 51 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR 52 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 53 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 54 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 55 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 56 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 57 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 58 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 59 */ 60 package tck.java.time.format; 61 62 import static org.testng.Assert.assertEquals; 63 import static org.testng.Assert.fail; 64 65 import java.time.DateTimeException; 66 import java.time.Instant; 67 import java.time.OffsetDateTime; 68 import java.time.Period; 69 import java.time.ZoneOffset; 70 import java.time.format.DateTimeFormatter; 71 import java.time.format.DateTimeFormatterBuilder; 72 import java.time.format.DateTimeParseException; 73 import java.time.format.ResolverStyle; 74 import java.time.temporal.TemporalAccessor; 75 76 import org.testng.annotations.DataProvider; 77 import org.testng.annotations.Test; 78 79 /* 80 * @test 81 * @bug 8166138 82 */ 83 84 /** 85 * Test DateTimeFormatterBuilder.appendInstant(). 86 */ 87 @Test 88 public class TCKInstantPrinterParser { 89 90 @DataProvider(name="printGrouped") data_printGrouped()91 Object[][] data_printGrouped() { 92 return new Object[][] { 93 {0, 0, "1970-01-01T00:00:00Z"}, 94 95 {-1, 0, "1969-12-31T23:59:59Z"}, 96 {1, 0, "1970-01-01T00:00:01Z"}, 97 {60, 0, "1970-01-01T00:01:00Z"}, 98 {3600, 0, "1970-01-01T01:00:00Z"}, 99 {86400, 0, "1970-01-02T00:00:00Z"}, 100 101 {182, 2, "1970-01-01T00:03:02.000000002Z"}, 102 {182, 20, "1970-01-01T00:03:02.000000020Z"}, 103 {182, 200, "1970-01-01T00:03:02.000000200Z"}, 104 {182, 2000, "1970-01-01T00:03:02.000002Z"}, 105 {182, 20000, "1970-01-01T00:03:02.000020Z"}, 106 {182, 200000, "1970-01-01T00:03:02.000200Z"}, 107 {182, 2000000, "1970-01-01T00:03:02.002Z"}, 108 {182, 20000000, "1970-01-01T00:03:02.020Z"}, 109 {182, 200000000, "1970-01-01T00:03:02.200Z"}, 110 111 {Instant.MAX.getEpochSecond(), 999999999, "+1000000000-12-31T23:59:59.999999999Z"}, 112 {Instant.MIN.getEpochSecond(), 0, "-1000000000-01-01T00:00:00Z"}, 113 }; 114 } 115 116 @Test(dataProvider="printGrouped") test_print_grouped(long instantSecs, int nano, String expected)117 public void test_print_grouped(long instantSecs, int nano, String expected) { 118 Instant instant = Instant.ofEpochSecond(instantSecs, nano); 119 DateTimeFormatter f = new DateTimeFormatterBuilder().appendInstant().toFormatter(); 120 assertEquals(f.format(instant), expected); 121 } 122 123 //----------------------------------------------------------------------- 124 @DataProvider(name="printDigits") data_printDigits()125 Object[][] data_printDigits() { 126 return new Object[][] { 127 {-1, 0, 0, "1970-01-01T00:00:00Z"}, 128 {0, 0, 0, "1970-01-01T00:00:00Z"}, 129 {1, 0, 0, "1970-01-01T00:00:00.0Z"}, 130 {3, 0, 0, "1970-01-01T00:00:00.000Z"}, 131 {9, 0, 0, "1970-01-01T00:00:00.000000000Z"}, 132 133 {-1, -1, 0, "1969-12-31T23:59:59Z"}, 134 {-1, 1, 0, "1970-01-01T00:00:01Z"}, 135 {-1, 60, 0, "1970-01-01T00:01:00Z"}, 136 {-1, 3600, 0, "1970-01-01T01:00:00Z"}, 137 {-1, 86400, 0, "1970-01-02T00:00:00Z"}, 138 139 {-1, 182, 2, "1970-01-01T00:03:02.000000002Z"}, 140 {-1, 182, 20, "1970-01-01T00:03:02.00000002Z"}, 141 {-1, 182, 200, "1970-01-01T00:03:02.0000002Z"}, 142 {-1, 182, 2000, "1970-01-01T00:03:02.000002Z"}, 143 {-1, 182, 20000, "1970-01-01T00:03:02.00002Z"}, 144 {-1, 182, 200000, "1970-01-01T00:03:02.0002Z"}, 145 {-1, 182, 2000000, "1970-01-01T00:03:02.002Z"}, 146 {-1, 182, 20000000, "1970-01-01T00:03:02.02Z"}, 147 {-1, 182, 200000000, "1970-01-01T00:03:02.2Z"}, 148 149 {0, 182, 2, "1970-01-01T00:03:02Z"}, 150 {0, 182, 20, "1970-01-01T00:03:02Z"}, 151 {0, 182, 200, "1970-01-01T00:03:02Z"}, 152 {0, 182, 2000, "1970-01-01T00:03:02Z"}, 153 {0, 182, 20000, "1970-01-01T00:03:02Z"}, 154 {0, 182, 200000, "1970-01-01T00:03:02Z"}, 155 {0, 182, 2000000, "1970-01-01T00:03:02Z"}, 156 {0, 182, 20000000, "1970-01-01T00:03:02Z"}, 157 {0, 182, 200000000, "1970-01-01T00:03:02Z"}, 158 159 {1, 182, 2, "1970-01-01T00:03:02.0Z"}, 160 {1, 182, 20, "1970-01-01T00:03:02.0Z"}, 161 {1, 182, 200, "1970-01-01T00:03:02.0Z"}, 162 {1, 182, 2000, "1970-01-01T00:03:02.0Z"}, 163 {1, 182, 20000, "1970-01-01T00:03:02.0Z"}, 164 {1, 182, 200000, "1970-01-01T00:03:02.0Z"}, 165 {1, 182, 2000000, "1970-01-01T00:03:02.0Z"}, 166 {1, 182, 20000000, "1970-01-01T00:03:02.0Z"}, 167 {1, 182, 200000000, "1970-01-01T00:03:02.2Z"}, 168 169 {3, 182, 2, "1970-01-01T00:03:02.000Z"}, 170 {3, 182, 20, "1970-01-01T00:03:02.000Z"}, 171 {3, 182, 200, "1970-01-01T00:03:02.000Z"}, 172 {3, 182, 2000, "1970-01-01T00:03:02.000Z"}, 173 {3, 182, 20000, "1970-01-01T00:03:02.000Z"}, 174 {3, 182, 200000, "1970-01-01T00:03:02.000Z"}, 175 {3, 182, 2000000, "1970-01-01T00:03:02.002Z"}, 176 {3, 182, 20000000, "1970-01-01T00:03:02.020Z"}, 177 {3, 182, 200000000, "1970-01-01T00:03:02.200Z"}, 178 179 {9, 182, 2, "1970-01-01T00:03:02.000000002Z"}, 180 {9, 182, 20, "1970-01-01T00:03:02.000000020Z"}, 181 {9, 182, 200, "1970-01-01T00:03:02.000000200Z"}, 182 {9, 182, 2000, "1970-01-01T00:03:02.000002000Z"}, 183 {9, 182, 20000, "1970-01-01T00:03:02.000020000Z"}, 184 {9, 182, 200000, "1970-01-01T00:03:02.000200000Z"}, 185 {9, 182, 2000000, "1970-01-01T00:03:02.002000000Z"}, 186 {9, 182, 20000000, "1970-01-01T00:03:02.020000000Z"}, 187 {9, 182, 200000000, "1970-01-01T00:03:02.200000000Z"}, 188 189 {9, Instant.MAX.getEpochSecond(), 999999999, "+1000000000-12-31T23:59:59.999999999Z"}, 190 {9, Instant.MIN.getEpochSecond(), 0, "-1000000000-01-01T00:00:00.000000000Z"}, 191 }; 192 } 193 194 @Test(dataProvider="printDigits") test_print_digits(int fractionalDigits, long instantSecs, int nano, String expected)195 public void test_print_digits(int fractionalDigits, long instantSecs, int nano, String expected) { 196 Instant instant = Instant.ofEpochSecond(instantSecs, nano); 197 DateTimeFormatter f = new DateTimeFormatterBuilder().appendInstant(fractionalDigits).toFormatter(); 198 assertEquals(f.format(instant), expected); 199 } 200 201 //----------------------------------------------------------------------- 202 @DataProvider(name="parseDigits") data_parse_digits()203 Object[][] data_parse_digits() { 204 return new Object[][] { 205 {0, 0, "1970-01-01T00:00:00Z"}, 206 {0, 0, "1970-01-01T00:00:00Z"}, 207 {0, 0, "1970-01-01T00:00:00.0Z"}, 208 {0, 0, "1970-01-01T00:00:00.000Z"}, 209 210 {0, 0, "1970-01-01T00:00:00+00:00"}, 211 {0, 0, "1970-01-01T05:30:00+05:30"}, 212 {0, 0, "1970-01-01T01:00:00.0+01:00"}, 213 214 {-1, 0, "1969-12-31T23:59:59Z"}, 215 {1, 0, "1970-01-01T00:00:01Z"}, 216 {60, 0, "1970-01-01T00:01:00Z"}, 217 {3600, 0, "1970-01-01T01:00:00Z"}, 218 {86400, 0, "1970-01-02T00:00:00Z"}, 219 220 {-1, 0, "1969-12-31T23:59:59+00:00"}, 221 {1, 0, "1970-01-01T05:30:01+05:30"}, 222 {60, 0, "1969-12-31T19:01:00-05:00"}, 223 {3600, 0, "1970-01-01T06:30:00+05:30"}, 224 {86400, 0, "1970-01-01T19:00:00-05:00"}, 225 226 {182, 234000000, "1970-01-01T00:03:02.234Z"}, 227 {182, 234000000, "1970-01-01T00:03:02.2340Z"}, 228 {182, 234000000, "1970-01-01T00:03:02.23400Z"}, 229 {182, 234000000, "1970-01-01T00:03:02.234000Z"}, 230 231 {182, 234000000, "1970-01-01T00:03:02.234+00:00"}, 232 {182, 234000000, "1970-01-01T05:33:02.2340+05:30"}, 233 {182, 234000000, "1969-12-31T19:03:02.23400-05:00"}, 234 {182, 234000000, "1970-01-01T00:03:02.234000+00:00"}, 235 236 }; 237 } 238 239 @Test(dataProvider="parseDigits") test_parse_digitsMinusOne(long instantSecs, int nano, String input)240 public void test_parse_digitsMinusOne(long instantSecs, int nano, String input) { 241 Instant expected = Instant.ofEpochSecond(instantSecs, nano); 242 DateTimeFormatter f = new DateTimeFormatterBuilder().appendInstant(-1).toFormatter(); 243 assertEquals(f.parse(input, Instant::from), expected); 244 assertEquals(f.parse(input).query(DateTimeFormatter.parsedExcessDays()), Period.ZERO); 245 assertEquals(f.parse(input).query(DateTimeFormatter.parsedLeapSecond()), Boolean.FALSE); 246 } 247 248 @DataProvider(name="parseNineDigits") data_parse_ninedigits()249 Object[][] data_parse_ninedigits() { 250 return new Object[][] { 251 {0, 0, "1970-01-01T00:00:00.000000000Z"}, 252 {0, 0, "1970-01-01T05:30:00.000000000+05:30"}, 253 254 {182, 234000000, "1970-01-01T00:03:02.234000000Z"}, 255 {182, 234000000, "1970-01-01T01:03:02.234000000+01:00"}, 256 257 {((23 * 60) + 59) * 60 + 59, 123456789, "1970-01-01T23:59:59.123456789Z"}, 258 {((23 * 60) + 59) * 60 + 59, 123456789, "1970-01-02T05:29:59.123456789+05:30"}, 259 260 {Instant.MAX.getEpochSecond(), 999999999, "+1000000000-12-31T23:59:59.999999999Z"}, 261 {Instant.MIN.getEpochSecond(), 0, "-1000000000-01-01T00:00:00.000000000Z"}, 262 {Instant.MAX.getEpochSecond(), 999999999, "+1000000000-12-31T23:59:59.999999999+00:00"}, 263 {Instant.MIN.getEpochSecond(), 0, "-1000000000-01-01T00:00:00.000000000+00:00"}, 264 }; 265 } 266 267 @Test(dataProvider="parseNineDigits") test_parse_digitsNine(long instantSecs, int nano, String input)268 public void test_parse_digitsNine(long instantSecs, int nano, String input) { 269 DateTimeFormatter f = new DateTimeFormatterBuilder().appendInstant(9).toFormatter(); 270 Instant expected = Instant.ofEpochSecond(instantSecs, nano); 271 assertEquals(f.parse(input, Instant::from), expected); 272 assertEquals(f.parse(input).query(DateTimeFormatter.parsedExcessDays()), Period.ZERO); 273 assertEquals(f.parse(input).query(DateTimeFormatter.parsedLeapSecond()), Boolean.FALSE); 274 } 275 276 @DataProvider(name="parseMaxMinInstant") data_parse_MaxMinInstant()277 Object[][] data_parse_MaxMinInstant() { 278 return new Object[][] { 279 {"+1000000000-12-31T23:59:59.999999999-01:00"}, 280 {"-1000000000-01-01T00:00:00.000000000+01:00"} 281 }; 282 } 283 284 @Test(dataProvider="parseMaxMinInstant", expectedExceptions=DateTimeParseException.class) test_invalid_Instant(String input)285 public void test_invalid_Instant(String input) { 286 DateTimeFormatter f = new DateTimeFormatterBuilder().appendInstant(-1).toFormatter(); 287 f.parse(input, Instant::from); 288 } 289 290 @Test test_parse_endOfDay()291 public void test_parse_endOfDay() { 292 Instant expected = OffsetDateTime.of(1970, 2, 4, 0, 0, 0, 0, ZoneOffset.UTC).toInstant(); 293 DateTimeFormatter f = new DateTimeFormatterBuilder().appendInstant(-1).toFormatter(); 294 for (ResolverStyle style : ResolverStyle.values()) { 295 TemporalAccessor parsed = f.withResolverStyle(style).parse("1970-02-03T24:00:00Z"); 296 assertEquals(parsed.query(Instant::from), expected); 297 assertEquals(parsed.query(DateTimeFormatter.parsedExcessDays()), Period.ZERO); 298 assertEquals(parsed.query(DateTimeFormatter.parsedLeapSecond()), Boolean.FALSE); 299 } 300 } 301 302 @Test test_parse_leapSecond()303 public void test_parse_leapSecond() { 304 Instant expected = OffsetDateTime.of(1970, 2, 3, 23, 59, 59, 123456789, ZoneOffset.UTC).toInstant(); 305 DateTimeFormatter f = new DateTimeFormatterBuilder().appendInstant(-1).toFormatter(); 306 for (ResolverStyle style : ResolverStyle.values()) { 307 TemporalAccessor parsed = f.withResolverStyle(style).parse("1970-02-03T23:59:60.123456789Z"); 308 assertEquals(parsed.query(Instant::from), expected); 309 assertEquals(parsed.query(DateTimeFormatter.parsedExcessDays()), Period.ZERO); 310 assertEquals(parsed.query(DateTimeFormatter.parsedLeapSecond()), Boolean.TRUE); 311 } 312 } 313 314 //----------------------------------------------------------------------- 315 @Test(expectedExceptions=IllegalArgumentException.class) test_appendInstant_tooSmall()316 public void test_appendInstant_tooSmall() { 317 new DateTimeFormatterBuilder().appendInstant(-2); 318 } 319 320 @Test(expectedExceptions=IllegalArgumentException.class) test_appendInstant_tooBig()321 public void test_appendInstant_tooBig() { 322 new DateTimeFormatterBuilder().appendInstant(10); 323 } 324 325 //------------------------------------------------------------------------ 326 @Test test_equality()327 public void test_equality() { 328 Instant instant1 = Instant.parse("2018-09-12T22:15:51+05:30"); 329 Instant instant2 = Instant.parse("2018-09-12T16:45:51Z"); 330 assertEquals(instant2, instant1); 331 } 332 333 } 334