Java SimpleDateFormat parse result off by one hour (and yes, I set the time zone)

后端 未结 2 730
北恋
北恋 2020-12-17 21:08

Riddle me this: why does this simple JUnit assertion fail?

public void testParseDate() throws ParseException {
    final SimpleDateFormat formatter = new Sim         


        
相关标签:
2条回答
  • 2020-12-17 21:25

    The default constructor of the Gregorian Calendar uses the local timezone of the machine. If that's different from UTC, you get this behavior. Try to use the GregorianCalendar(TimeZone) constructor and pass UTC into that.

    This will work:

    public void testParseDate() throws Exception {
    
        TimeZone UTC = TimeZone.getTimeZone("UTC");
    
        // Create a UTC formatter
        final SimpleDateFormat formatter = new SimpleDateFormat(
                "yyyy-MM-dd HH:mm:ss z");
        formatter.setTimeZone(UTC);
    
        // Create a UTC Gregorian Calendar (stores internally in UTC, so
        // get(Calendar.HOUR_OF_DAY) returns in UTC instead of in the
        // local machine's timezone.
        final Calendar c = new GregorianCalendar(UTC);
    
        // Ask the formatter for a date representation and pass that
        // into the GregorianCalendar (which will convert it into
        // it's internal timezone, which is also UTC.
        c.setTime(formatter.parse("2013-03-02 11:59:59 UTC"));
    
        // Output the UTC hour of day
        assertEquals(11, c.get(Calendar.HOUR_OF_DAY));
    }
    
    0 讨论(0)
  • 2020-12-17 21:31

    You also need to set up the timezone/daylight savings time for the calendar. Have a look at this snippet taken from the documentation:

     // create a Pacific Standard Time time zone
     SimpleTimeZone pdt = new SimpleTimeZone(-8 * 60 * 60 * 1000, ids[0]);
    
     // set up rules for daylight savings time
     pdt.setStartRule(Calendar.APRIL, 1, Calendar.SUNDAY, 2 * 60 * 60 * 1000);
     pdt.setEndRule(Calendar.OCTOBER, -1, Calendar.SUNDAY, 2 * 60 * 60 * 1000);
    
     // create a GregorianCalendar with the Pacific Daylight time zone
     // and the current date and time
     Calendar calendar = new GregorianCalendar(pdt);
    
    0 讨论(0)
提交回复
热议问题