1 /*
   2  * Copyright (c) 2014, 2015, 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 package datatype;
  25 
  26 import java.math.BigDecimal;
  27 import java.math.BigInteger;
  28 import java.util.Calendar;
  29 import java.util.Date;
  30 import java.util.GregorianCalendar;
  31 import java.util.TimeZone;
  32 
  33 import javax.xml.datatype.DatatypeConfigurationException;
  34 import javax.xml.datatype.DatatypeConstants;
  35 import javax.xml.datatype.DatatypeFactory;
  36 import javax.xml.datatype.Duration;
  37 import javax.xml.namespace.QName;
  38 
  39 import org.testng.Assert;
  40 import org.testng.AssertJUnit;
  41 import org.testng.annotations.BeforeMethod;
  42 import org.testng.annotations.Test;
  43 
  44 /*
  45  * @summary Test Duration.
  46  */
  47 public class DurationTest {
  48 
  49     private final static boolean DEBUG = true;
  50 
  51     protected Duration duration = null;
  52 
  53     @BeforeMethod
  54     protected void setUp() {
  55         try {
  56             duration = DatatypeFactory.newInstance().newDuration(100);
  57         } catch (DatatypeConfigurationException dce) {
  58             dce.printStackTrace();
  59             Assert.fail("Failed to create instance of DatatypeFactory " + dce.getMessage());
  60         }
  61     }
  62 
  63     @Test
  64     public void testDurationSubtract() {
  65         try {
  66             Duration bigDur = DatatypeFactory.newInstance().newDuration(20000);
  67             Duration smallDur = DatatypeFactory.newInstance().newDuration(10000);
  68             if (smallDur.subtract(bigDur).getSign() != -1) {
  69                 Assert.fail("smallDur.subtract(bigDur).getSign() is not -1");
  70             }
  71             if (bigDur.subtract(smallDur).getSign() != 1) {
  72                 Assert.fail("bigDur.subtract(smallDur).getSign() is not 1");
  73             }
  74             if (smallDur.subtract(smallDur).getSign() != 0) {
  75                 Assert.fail("smallDur.subtract(smallDur).getSign() is not 0");
  76             }
  77         } catch (DatatypeConfigurationException e) {
  78             e.printStackTrace();
  79         }
  80     }
  81 
  82     @Test
  83     public void testDurationMultiply() {
  84         int num = 5000; // millisends. 5 seconds
  85         int factor = 2;
  86         try {
  87             Duration dur = DatatypeFactory.newInstance().newDuration(num);
  88             if (dur.multiply(factor).getSeconds() != 10) {
  89                 Assert.fail("duration.multiply() return wrong value");
  90             }
  91             // factor is 2*10^(-1)
  92             if (dur.multiply(new BigDecimal(new BigInteger("2"), 1)).getSeconds() != 1) {
  93                 Assert.fail("duration.multiply() return wrong value");
  94             }
  95             if (dur.subtract(DatatypeFactory.newInstance().newDuration(1000)).multiply(new BigDecimal(new BigInteger("2"), 1)).getSeconds() != 0) {
  96                 Assert.fail("duration.multiply() return wrong value");
  97             }
  98         } catch (DatatypeConfigurationException e) {
  99             e.printStackTrace();
 100         }
 101     }
 102 
 103     @Test
 104     public void testDurationAndCalendar1() {
 105         int year = 1;
 106         int month = 2;
 107         int day = 3;
 108         int hour = 4;
 109         int min = 5;
 110         int sec = 6;
 111         String lexicalRepresentation = "P" + year + "Y" + month + "M" + day + "DT" + hour + "H" + min + "M" + sec + "S";
 112         try {
 113             Duration dur = DatatypeFactory.newInstance().newDuration(lexicalRepresentation);
 114             System.out.println(dur.toString());
 115             AssertJUnit.assertTrue("year should be 1", dur.getYears() == year);
 116             AssertJUnit.assertTrue("month should be 2", dur.getMonths() == month);
 117             AssertJUnit.assertTrue("day should be 3", dur.getDays() == day);
 118             AssertJUnit.assertTrue("hour should be 4", dur.getHours() == hour);
 119             AssertJUnit.assertTrue("minute should be 5", dur.getMinutes() == min);
 120             AssertJUnit.assertTrue("second should be 6", dur.getSeconds() == sec);
 121         } catch (DatatypeConfigurationException e) {
 122             e.printStackTrace();
 123         }
 124     }
 125 
 126     @Test
 127     public void testDurationAndCalendar2() {
 128         try {
 129             AssertJUnit.assertTrue("10.00099S means 10 sec since it will be rounded to zero", DatatypeFactory.newInstance().newDuration("PT10.00099S")
 130                     .getTimeInMillis(new Date()) == 10000);
 131             AssertJUnit.assertTrue("10.00099S means 10 sec since it will be rounded to zero", DatatypeFactory.newInstance().newDuration("-PT10.00099S")
 132                     .getTimeInMillis(new Date()) == -10000);
 133             AssertJUnit.assertTrue("10.00099S means 10 sec since it will be rounded to zero", DatatypeFactory.newInstance().newDuration("PT10.00099S")
 134                     .getTimeInMillis(new GregorianCalendar()) == 10000);
 135             AssertJUnit.assertTrue("10.00099S means 10 sec since it will be rounded to zero", DatatypeFactory.newInstance().newDuration("-PT10.00099S")
 136                     .getTimeInMillis(new GregorianCalendar()) == -10000);
 137         } catch (DatatypeConfigurationException e) {
 138             e.printStackTrace();
 139         }
 140     }
 141 
 142     @Test
 143     public void testDurationAndCalendar3() {
 144         try {
 145             Calendar cal = new GregorianCalendar();
 146             cal.set(Calendar.SECOND, 59);
 147             DatatypeFactory.newInstance().newDuration(10000).addTo(cal);
 148             AssertJUnit.assertTrue("sec will be 9", cal.get(Calendar.SECOND) == 9);
 149 
 150             Date date = new Date();
 151             date.setSeconds(59);
 152             DatatypeFactory.newInstance().newDuration(10000).addTo(date);
 153             AssertJUnit.assertTrue("sec will be 9", date.getSeconds() == 9);
 154         } catch (DatatypeConfigurationException e) {
 155             e.printStackTrace();
 156         }
 157     }
 158 
 159     @Test
 160     public void testEqualsWithDifferentObjectParam() {
 161 
 162         AssertJUnit.assertFalse("equals method should return false for any object other than Duration", duration.equals(new Integer(0)));
 163     }
 164 
 165     @Test
 166     public void testEqualsWithNullObjectParam() {
 167 
 168         AssertJUnit.assertFalse("equals method should return false for null parameter", duration.equals(null));
 169     }
 170 
 171     @Test
 172     public void testEqualsWithEqualObjectParam() {
 173         try {
 174             AssertJUnit.assertTrue("equals method is expected to return true", duration.equals(DatatypeFactory.newInstance().newDuration(100)));
 175         } catch (DatatypeConfigurationException dce) {
 176             dce.printStackTrace();
 177             Assert.fail("Failed to create instance of DatatypeFactory " + dce.getMessage());
 178         }
 179     }
 180 
 181     /**
 182      * Inspired by CR 5077522 Duration.compare makes mistakes for some values.
 183      */
 184     @Test
 185     public void testCompareWithInderterminateRelation() {
 186 
 187         final String[][] partialOrder = { // partialOrder
 188         { "P1Y", "<>", "P365D" }, { "P1Y", "<>", "P366D" }, { "P1M", "<>", "P28D" }, { "P1M", "<>", "P29D" }, { "P1M", "<>", "P30D" }, { "P1M", "<>", "P31D" },
 189                 { "P5M", "<>", "P150D" }, { "P5M", "<>", "P151D" }, { "P5M", "<>", "P152D" }, { "P5M", "<>", "P153D" }, { "PT2419200S", "<>", "P1M" },
 190                 { "PT2678400S", "<>", "P1M" }, { "PT31536000S", "<>", "P1Y" }, { "PT31622400S", "<>", "P1Y" }, { "PT525600M", "<>", "P1Y" },
 191                 { "PT527040M", "<>", "P1Y" }, { "PT8760H", "<>", "P1Y" }, { "PT8784H", "<>", "P1Y" }, { "P365D", "<>", "P1Y" }, };
 192 
 193         DatatypeFactory df = null;
 194         try {
 195             df = DatatypeFactory.newInstance();
 196         } catch (DatatypeConfigurationException ex) {
 197             ex.printStackTrace();
 198             Assert.fail(ex.toString());
 199         }
 200 
 201         boolean compareErrors = false;
 202 
 203         for (int valueIndex = 0; valueIndex < partialOrder.length; ++valueIndex) {
 204             Duration duration1 = df.newDuration(partialOrder[valueIndex][0]);
 205             Duration duration2 = df.newDuration(partialOrder[valueIndex][2]);
 206             int cmp = duration1.compare(duration2);
 207             int expected = ">".equals(partialOrder[valueIndex][1]) ? DatatypeConstants.GREATER
 208                     : "<".equals(partialOrder[valueIndex][1]) ? DatatypeConstants.LESSER : "==".equals(partialOrder[valueIndex][1]) ? DatatypeConstants.EQUAL
 209                             : DatatypeConstants.INDETERMINATE;
 210 
 211             // just note any errors, do not fail until all cases have been
 212             // tested
 213             if (expected != cmp) {
 214                 compareErrors = true;
 215                 System.err.println("returned " + cmp2str(cmp) + " for durations \'" + duration1 + "\' and " + duration2 + "\', but expected "
 216                         + cmp2str(expected));
 217             }
 218         }
 219 
 220         if (compareErrors) {
 221             // TODO; fix bug, these tests should pass
 222             if (false) {
 223                 Assert.fail("Errors in comparing indeterminate relations, see Stderr");
 224             } else {
 225                 System.err.println("Please fix this bug: " + "Errors in comparing indeterminate relations, see Stderr");
 226             }
 227         }
 228     }
 229 
 230     public static String cmp2str(int cmp) {
 231         return cmp == DatatypeConstants.LESSER ? "LESSER" : cmp == DatatypeConstants.GREATER ? "GREATER" : cmp == DatatypeConstants.EQUAL ? "EQUAL"
 232                 : cmp == DatatypeConstants.INDETERMINATE ? "INDETERMINATE" : "UNDEFINED";
 233     }
 234 
 235     /**
 236      * Inspired by CR 6238220 javax.xml.datatype.Duration has no clear
 237      * description concerning return values range.
 238      */
 239     @Test
 240     public void testNormalizedReturnValues() throws Exception {
 241 
 242         final Object[] TEST_VALUES = {
 243                 // test 61 seconds -> 1 minute, 1 second
 244                 true, // isPositive,
 245                 BigInteger.ZERO, // years,
 246                 BigInteger.ZERO, // months
 247                 BigInteger.ZERO, // days
 248                 BigInteger.ZERO, // hours
 249                 BigInteger.ZERO, // minutes
 250                 new BigDecimal(61), // seconds
 251                 61000L, // durationInMilliSeconds,
 252                 "P0Y0M0DT0H0M61S", // lexicalRepresentation
 253 
 254                 // test - 61 seconds -> - 1 minute, 1 second
 255                 false, // isPositive,
 256                 BigInteger.ZERO, // years,
 257                 BigInteger.ZERO, // months
 258                 BigInteger.ZERO, // days
 259                 BigInteger.ZERO, // hours
 260                 BigInteger.ZERO, // minutes
 261                 new BigDecimal(61), // seconds
 262                 61000L, // durationInMilliSeconds,
 263                 "-P0Y0M0DT0H0M61S", // lexicalRepresentation
 264         };
 265 
 266         final Object[] NORM_VALUES = {
 267                 // test 61 seconds -> 1 minute, 1 second
 268                 true, // normalized isPositive,
 269                 BigInteger.ZERO, // normalized years,
 270                 BigInteger.ZERO, // normalized months
 271                 BigInteger.ZERO, // normalized days
 272                 BigInteger.ZERO, // normalized hours
 273                 BigInteger.ONE, // normalized minutes
 274                 BigDecimal.ONE, // normalized seconds
 275                 61000L, // normalized durationInMilliSeconds,
 276                 "P0Y0M0DT0H1M1.000S", // normalized lexicalRepresentation
 277 
 278                 // test - 61 seconds -> - 1 minute, 1 second
 279                 false, // normalized isPositive,
 280                 BigInteger.ZERO, // normalized years,
 281                 BigInteger.ZERO, // normalized months
 282                 BigInteger.ZERO, // normalized days
 283                 BigInteger.ZERO, // normalized hours
 284                 BigInteger.ONE, // normalized minutes
 285                 BigDecimal.ONE, // normalized seconds
 286                 61000L, // normalized durationInMilliSeconds,
 287                 "-P0Y0M0DT0H1M1.000S" // normalized lexicalRepresentation
 288         };
 289 
 290         for (int onValue = 0; onValue < TEST_VALUES.length; onValue += 9) {
 291             newDurationTester(((Boolean) TEST_VALUES[onValue]).booleanValue(), // isPositive,
 292                     ((Boolean) NORM_VALUES[onValue]).booleanValue(), // normalized
 293                                                                      // isPositive,
 294                     (BigInteger) TEST_VALUES[onValue + 1], // years,
 295                     (BigInteger) NORM_VALUES[onValue + 1], // normalized years,
 296                     (BigInteger) TEST_VALUES[onValue + 2], // months
 297                     (BigInteger) NORM_VALUES[onValue + 2], // normalized months
 298                     (BigInteger) TEST_VALUES[onValue + 3], // days
 299                     (BigInteger) NORM_VALUES[onValue + 3], // normalized days
 300                     (BigInteger) TEST_VALUES[onValue + 4], // hours
 301                     (BigInteger) NORM_VALUES[onValue + 4], // normalized hours
 302                     (BigInteger) TEST_VALUES[onValue + 5], // minutes
 303                     (BigInteger) NORM_VALUES[onValue + 5], // normalized minutes
 304                     (BigDecimal) TEST_VALUES[onValue + 6], // seconds
 305                     (BigDecimal) NORM_VALUES[onValue + 6], // normalized seconds
 306                     ((Long) TEST_VALUES[onValue + 7]).longValue(), // durationInMilliSeconds,
 307                     ((Long) NORM_VALUES[onValue + 7]).longValue(), // normalized
 308                                                                    // durationInMilliSeconds,
 309                     (String) TEST_VALUES[onValue + 8], // lexicalRepresentation
 310                     (String) NORM_VALUES[onValue + 8]); // normalized
 311                                                         // lexicalRepresentation
 312 
 313             newDurationDayTimeTester(((Boolean) TEST_VALUES[onValue]).booleanValue(), // isPositive,
 314                     ((Boolean) NORM_VALUES[onValue]).booleanValue(), // normalized
 315                                                                      // isPositive,
 316                     BigInteger.ZERO, // years,
 317                     BigInteger.ZERO, // normalized years,
 318                     BigInteger.ZERO, // months
 319                     BigInteger.ZERO, // normalized months
 320                     (BigInteger) TEST_VALUES[onValue + 3], // days
 321                     (BigInteger) NORM_VALUES[onValue + 3], // normalized days
 322                     (BigInteger) TEST_VALUES[onValue + 4], // hours
 323                     (BigInteger) NORM_VALUES[onValue + 4], // normalized hours
 324                     (BigInteger) TEST_VALUES[onValue + 5], // minutes
 325                     (BigInteger) NORM_VALUES[onValue + 5], // normalized minutes
 326                     (BigDecimal) TEST_VALUES[onValue + 6], // seconds
 327                     (BigDecimal) NORM_VALUES[onValue + 6], // normalized seconds
 328                     ((Long) TEST_VALUES[onValue + 7]).longValue(), // durationInMilliSeconds,
 329                     ((Long) NORM_VALUES[onValue + 7]).longValue(), // normalized
 330                                                                    // durationInMilliSeconds,
 331                     (String) TEST_VALUES[onValue + 8], // lexicalRepresentation
 332                     (String) NORM_VALUES[onValue + 8]); // normalized
 333                                                         // lexicalRepresentation
 334         }
 335     }
 336 
 337     private void newDurationTester(boolean isPositive, boolean normalizedIsPositive, BigInteger years, BigInteger normalizedYears, BigInteger months,
 338             BigInteger normalizedMonths, BigInteger days, BigInteger normalizedDays, BigInteger hours, BigInteger normalizedHours, BigInteger minutes,
 339             BigInteger normalizedMinutes, BigDecimal seconds, BigDecimal normalizedSeconds, long durationInMilliSeconds, long normalizedDurationInMilliSeconds,
 340             String lexicalRepresentation, String normalizedLexicalRepresentation) {
 341 
 342         DatatypeFactory datatypeFactory = null;
 343         try {
 344             datatypeFactory = DatatypeFactory.newInstance();
 345         } catch (DatatypeConfigurationException ex) {
 346             ex.printStackTrace();
 347             Assert.fail(ex.toString());
 348         }
 349 
 350         // create 4 Durations using the 4 different constructors
 351 
 352         Duration durationBigInteger = datatypeFactory.newDuration(isPositive, years, months, days, hours, minutes, seconds);
 353         durationAssertEquals(durationBigInteger, DatatypeConstants.DURATION, normalizedIsPositive, normalizedYears.intValue(), normalizedMonths.intValue(),
 354                 normalizedDays.intValue(), normalizedHours.intValue(), normalizedMinutes.intValue(), normalizedSeconds.intValue(),
 355                 normalizedDurationInMilliSeconds, normalizedLexicalRepresentation);
 356 
 357         Duration durationInt = datatypeFactory.newDuration(isPositive, years.intValue(), months.intValue(), days.intValue(), hours.intValue(),
 358                 minutes.intValue(), seconds.intValue());
 359         durationAssertEquals(durationInt, DatatypeConstants.DURATION, normalizedIsPositive, normalizedYears.intValue(), normalizedMonths.intValue(),
 360                 normalizedDays.intValue(), normalizedHours.intValue(), normalizedMinutes.intValue(), normalizedSeconds.intValue(),
 361                 normalizedDurationInMilliSeconds, normalizedLexicalRepresentation);
 362 
 363         Duration durationMilliseconds = datatypeFactory.newDuration(durationInMilliSeconds);
 364         durationAssertEquals(durationMilliseconds, DatatypeConstants.DURATION, normalizedIsPositive, normalizedYears.intValue(), normalizedMonths.intValue(),
 365                 normalizedDays.intValue(), normalizedHours.intValue(), normalizedMinutes.intValue(), normalizedSeconds.intValue(),
 366                 normalizedDurationInMilliSeconds, normalizedLexicalRepresentation);
 367 
 368         Duration durationLexical = datatypeFactory.newDuration(lexicalRepresentation);
 369         durationAssertEquals(durationLexical, DatatypeConstants.DURATION, normalizedIsPositive, normalizedYears.intValue(), normalizedMonths.intValue(),
 370                 normalizedDays.intValue(), normalizedHours.intValue(), normalizedMinutes.intValue(), normalizedSeconds.intValue(),
 371                 normalizedDurationInMilliSeconds, normalizedLexicalRepresentation);
 372     }
 373 
 374     private void newDurationDayTimeTester(boolean isPositive, boolean normalizedIsPositive, BigInteger years, BigInteger normalizedYears, BigInteger months,
 375             BigInteger normalizedMonths, BigInteger days, BigInteger normalizedDays, BigInteger hours, BigInteger normalizedHours, BigInteger minutes,
 376             BigInteger normalizedMinutes, BigDecimal seconds, BigDecimal normalizedSeconds, long durationInMilliSeconds, long normalizedDurationInMilliSeconds,
 377             String lexicalRepresentation, String normalizedLexicalRepresentation) {
 378 
 379         DatatypeFactory datatypeFactory = null;
 380         try {
 381             datatypeFactory = DatatypeFactory.newInstance();
 382         } catch (DatatypeConfigurationException ex) {
 383             ex.printStackTrace();
 384             Assert.fail(ex.toString());
 385         }
 386 
 387         // create 4 dayTime Durations using the 4 different constructors
 388 
 389         Duration durationDayTimeBigInteger = datatypeFactory.newDurationDayTime(isPositive, days, hours, minutes, seconds.toBigInteger());
 390         durationAssertEquals(durationDayTimeBigInteger, DatatypeConstants.DURATION_DAYTIME, normalizedIsPositive, normalizedYears.intValue(),
 391                 normalizedMonths.intValue(), normalizedDays.intValue(), normalizedHours.intValue(), normalizedMinutes.intValue(), normalizedSeconds.intValue(),
 392                 normalizedDurationInMilliSeconds, normalizedLexicalRepresentation);
 393 
 394         /*
 395          * Duration durationDayTimeInt = datatypeFactory.newDurationDayTime(
 396          * isPositive, days.intValue(), hours.intValue(), minutes.intValue(),
 397          * seconds.intValue()); Duration durationDayTimeMilliseconds =
 398          * datatypeFactory.newDurationDayTime( durationInMilliSeconds); Duration
 399          * durationDayTimeLexical = datatypeFactory.newDurationDayTime(
 400          * lexicalRepresentation);
 401          * Duration durationYearMonthBigInteger =
 402          * datatypeFactory.newDurationYearMonth( isPositive, years, months);
 403          * Duration durationYearMonthInt = datatypeFactory.newDurationYearMonth(
 404          * isPositive, years.intValue(), months.intValue()); Duration
 405          * durationYearMonthMilliseconds = datatypeFactory.newDurationYearMonth(
 406          * durationInMilliSeconds); Duration durationYearMonthLexical =
 407          * datatypeFactory.newDurationYearMonth( lexicalRepresentation) ;
 408          */
 409 
 410     }
 411 
 412     private void durationAssertEquals(Duration duration, QName xmlSchemaType, boolean isPositive, int years, int months, int days, int hours, int minutes,
 413             int seconds, long milliseconds, String lexical) {
 414 
 415         final TimeZone GMT = TimeZone.getTimeZone("GMT");
 416         final GregorianCalendar EPOCH = new GregorianCalendar(GMT);
 417         EPOCH.clear();
 418 
 419         if (DEBUG) {
 420             System.out.println("Testing Duration: " + duration.toString());
 421         }
 422 
 423         // sign
 424         if (DEBUG) {
 425             boolean actual = (duration.getSign() == 1) ? true : false;
 426             System.out.println("sign:");
 427             System.out.println("    expected: \"" + isPositive + "\"");
 428             System.out.println("    actual:   \"" + actual + "\"");
 429         }
 430 
 431         if (DEBUG) {
 432             System.out.println("years:");
 433             System.out.println("    expected: \"" + years + "\"");
 434             System.out.println("    actual:   \"" + duration.getYears() + "\"");
 435         }
 436 
 437         if (DEBUG) {
 438             System.out.println("months:");
 439             System.out.println("    expected: \"" + months + "\"");
 440             System.out.println("    actual:   \"" + duration.getMonths() + "\"");
 441         }
 442 
 443         if (DEBUG) {
 444             System.out.println("days:");
 445             System.out.println("    expected: \"" + days + "\"");
 446             System.out.println("    actual:   \"" + duration.getDays() + "\"");
 447         }
 448 
 449         if (DEBUG) {
 450             System.out.println("hours:");
 451             System.out.println("    expected: \"" + hours + "\"");
 452             System.out.println("    actual:   \"" + duration.getHours() + "\"");
 453         }
 454 
 455         if (DEBUG) {
 456             System.out.println("minutes:");
 457             System.out.println("    expected: \"" + minutes + "\"");
 458             System.out.println("    actual:   \"" + duration.getMinutes() + "\"");
 459         }
 460 
 461         if (DEBUG) {
 462             System.out.println("seconds:");
 463             System.out.println("    expected: \"" + seconds + "\"");
 464             System.out.println("    actual:   \"" + duration.getSeconds() + "\"");
 465         }
 466 
 467         if (DEBUG) {
 468             System.out.println("milliseconds:");
 469             System.out.println("    expected: \"" + milliseconds + "\"");
 470             System.out.println("    actual:   \"" + duration.getTimeInMillis(EPOCH) + "\"");
 471         }
 472 
 473         if (DEBUG) {
 474             System.out.println("lexical:");
 475             System.out.println("    expected: \"" + lexical + "\"");
 476             System.out.println("    actual:   \"" + duration.toString() + "\"");
 477         }
 478 
 479     }
 480 }