jdk/test/java/util/logging/XMLFormatterDate.java
changeset 38573 4964706e8a45
parent 21823 2100a5feec29
child 40684 2e37c119dc2a
equal deleted inserted replaced
38572:347523bb90c6 38573:4964706e8a45
    19  *
    19  *
    20  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    20  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    21  * or visit www.oracle.com if you need additional information or have any
    21  * or visit www.oracle.com if you need additional information or have any
    22  * questions.
    22  * questions.
    23  */
    23  */
    24 import java.util.Calendar;
    24 import java.io.ByteArrayInputStream;
    25 import java.util.GregorianCalendar;
    25 import java.io.ByteArrayOutputStream;
       
    26 import java.io.IOException;
       
    27 import java.time.Month;
       
    28 import java.time.ZoneId;
       
    29 import java.time.ZoneOffset;
       
    30 import java.time.ZonedDateTime;
    26 import java.util.Locale;
    31 import java.util.Locale;
       
    32 import java.util.Properties;
       
    33 import java.util.function.Supplier;
    27 import java.util.logging.Level;
    34 import java.util.logging.Level;
       
    35 import java.util.logging.LogManager;
    28 import java.util.logging.LogRecord;
    36 import java.util.logging.LogRecord;
    29 import java.util.logging.XMLFormatter;
    37 import java.util.logging.XMLFormatter;
    30 
    38 
    31 /**
    39 /**
    32  * @test
    40  * @test
    33  * @bug 8028185
    41  * @bug 8028185
    34  * @summary XMLFormatter.format emits incorrect year (year + 1900)
    42  * @summary XMLFormatter.format emits incorrect year (year + 1900)
    35  * @author dfuchs
    43  * @author dfuchs
       
    44  * @run main/othervm XMLFormatterDate
    36  */
    45  */
    37 public class XMLFormatterDate {
    46 public class XMLFormatterDate {
       
    47 
       
    48     static final class TimeStamp {
       
    49 
       
    50         final ZonedDateTime zdt;
       
    51         TimeStamp(ZoneId zoneId) {
       
    52             zdt = ZonedDateTime.now(zoneId);
       
    53         }
       
    54         int getYear() {
       
    55             return zdt.getYear();
       
    56         }
       
    57         boolean isJanuaryFirst() {
       
    58             return zdt.getMonth() == Month.JANUARY && zdt.getDayOfMonth() == 1;
       
    59         }
       
    60     }
       
    61 
    38 
    62 
    39     /**
    63     /**
    40      * Before the fix, JDK8 prints: {@code
    64      * Before the fix, JDK8 prints: {@code
    41      * <record>
    65      * <record>
    42      *   <date>3913-11-18T17:35:40</date>
    66      *   <date>3913-11-18T17:35:40</date>
    62     public static void main(String[] args) {
    86     public static void main(String[] args) {
    63         Locale locale = Locale.getDefault();
    87         Locale locale = Locale.getDefault();
    64         try {
    88         try {
    65             Locale.setDefault(Locale.ENGLISH);
    89             Locale.setDefault(Locale.ENGLISH);
    66 
    90 
    67             final GregorianCalendar cal1 = new GregorianCalendar();
    91             // Test with default format: by default date is in UTC.
    68             final int year1 = cal1.get(Calendar.YEAR);
    92             System.out.println("Testing with UTC");
       
    93             test(() -> new TimeStamp(ZoneOffset.UTC));
    69 
    94 
    70             LogRecord record = new LogRecord(Level.INFO, "test");
    95             // Change LogManager configuration so that new
    71             XMLFormatter formatter = new XMLFormatter();
    96             // XMLFormatter prints date in the pre Java 9 local zone format
    72             final String formatted = formatter.format(record);
    97             try {
    73             System.out.println(formatted);
    98                 Properties props = new Properties();
    74 
    99                 props.setProperty("java.util.logging.XMLFormatter.useInstant", "false");
    75             final GregorianCalendar cal2 = new GregorianCalendar();
   100                 ByteArrayOutputStream baos = new ByteArrayOutputStream();
    76             final int year2 = cal2.get(Calendar.YEAR);
   101                 props.store(baos, "");
    77             if (year2 < 1900) {
   102                 ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
    78                 throw new Error("Invalid system year: " + year2);
   103                 LogManager.getLogManager().updateConfiguration(bais, (k) -> (o,n) -> n!=null?n:o);
       
   104             } catch (IOException io) {
       
   105                 throw new RuntimeException(io);
    79             }
   106             }
    80 
   107 
    81             StringBuilder buf2 = new StringBuilder()
   108             // re test with the old format: date will be in the local time zone.
    82                     .append("<date>").append(year2).append("-");
   109             System.out.println("Testing with old format");
    83             if (!formatted.contains(buf2.toString())) {
   110             test(() -> new TimeStamp(ZoneId.systemDefault()));
    84                 StringBuilder buf1 = new StringBuilder()
   111 
    85                         .append("<date>").append(year1).append("-");
       
    86                 if (formatted.contains(buf1)
       
    87                         && year2 == year1 + 1
       
    88                         && cal2.get(Calendar.MONTH) == Calendar.JANUARY
       
    89                         && cal2.get(Calendar.DAY_OF_MONTH) == 1) {
       
    90                     // Oh! The year just switched in the midst of the test...
       
    91                     System.out.println("Happy new year!");
       
    92                 } else {
       
    93                     throw new Error("Expected year " + year2
       
    94                             + " not found in log:\n" + formatted);
       
    95                 }
       
    96             }
       
    97         } finally {
   112         } finally {
    98             Locale.setDefault(locale);
   113             Locale.setDefault(locale);
    99         }
   114         }
   100     }
   115     }
   101 
   116 
       
   117     static void test(Supplier<TimeStamp> timeStampSupplier) {
       
   118 
       
   119         TimeStamp t1 = timeStampSupplier.get();
       
   120         int year1 = t1.getYear();
       
   121 
       
   122         LogRecord record = new LogRecord(Level.INFO, "test");
       
   123         XMLFormatter formatter = new XMLFormatter();
       
   124         final String formatted = formatter.format(record);
       
   125         System.out.println(formatted);
       
   126 
       
   127         final TimeStamp t2 = timeStampSupplier.get();
       
   128         final int year2 = t2.getYear();
       
   129         if (year2 < 1900) {
       
   130             throw new Error("Invalid system year: " + year2);
       
   131         }
       
   132 
       
   133         final StringBuilder buf2 = new StringBuilder()
       
   134                 .append("<date>").append(year2).append("-");
       
   135         if (!formatted.contains(buf2.toString())) {
       
   136             StringBuilder buf1 = new StringBuilder()
       
   137                     .append("<date>").append(year1).append("-");
       
   138             if (formatted.contains(buf1) && year2 == year1 + 1
       
   139                     && t2.isJanuaryFirst()) {
       
   140                 // Oh! The year just switched in the midst of the test...
       
   141                 System.out.println("Happy new year!");
       
   142             } else {
       
   143                 throw new Error("Expected year " + year2
       
   144                         + " not found in log:\n" + formatted);
       
   145             }
       
   146         }
       
   147     }
       
   148 
   102 }
   149 }