Why does SimpleDateFormat change the date?

Given the following code:

[...]

    public void testFormatDateString() throws ParseException {

        String dateString = new java.util.Date().toString();

        System.out.println(dateString);

        SimpleDateFormat format = new SimpleDateFormat("EEE MMM dd HH:mm:ss z YYYY", Locale.ENGLISH);

        Date date = format.parse(dateString);

        System.out.println(date.toString());
    }

[...]

Before: Sat Aug 19 18:26:11 BST 2017

After: Sat Jan 07 17:26:11 GMT 2017

Why has the date changed?

+4
source share
3 answers

Upper case Yfor "week year" , which has 364 or 371 days instead of the usual 365 or 366. In lower case Y(which is used Date#toString) everything works as expected:

public void testFormatDateString() throws ParseException {

    String dateString = new java.util.Date().toString();

    System.out.println(dateString);

    // Force to Locale.US as this is hardcoded in Date#toString
    SimpleDateFormat format = new SimpleDateFormat(
            "EEE MMM dd HH:mm:ss z yyyy", Locale.US);

    Date date = format.parse(dateString);

    System.out.println(date.toString());
}

Conclusion:

Sat Aug 19 17:50:39 GMT 2017
Sat Aug 19 17:50:39 GMT 2017

Take a look at ideone.com

As mentioned in the comments, be sure to include Locale.USwhen parsing dateString, as this is hard-coded into Date#toString. See this question for more details .

+9
source

, Marvins answer, , - .

java doc SimpleDateFormat, YYYY. , . :

public class SimpleDateFormat extends DateFormat {
//....
/**
 * Returns the compiled form of the given pattern. The syntax of
 * the compiled pattern is:
 * <blockquote>
 * CompiledPattern:
 *     EntryList
 * EntryList:
 *     Entry
 *     EntryList Entry
 * Entry:
 *     TagField
 *     TagField data
 * TagField:
 *     Tag Length
 *     TaggedData
 * Tag:
 *     pattern_char_index
 *     TAG_QUOTE_CHARS
 * Length:
 *     short_length
 *     long_length
 * TaggedData:
 *     TAG_QUOTE_ASCII_CHAR ascii_char
 *
 * </blockquote>
 * ....
 *
 * @exception NullPointerException if the given pattern is null
 * @exception IllegalArgumentException if the given pattern is invalid
 */
    private char[] compile(String pattern) {
        ...
        if ((tag = DateFormatSymbols.patternChars.indexOf(c)) == -1) {
            throw new IllegalArgumentException("Illegal pattern character " +
                                               "'" + c + "'");
        }
        ...
    }
    ...
}

( ) DateFormatSymbols.patternChars:

public class DateFormatSymbols implements Serializable, Cloneable {
    ...
    static final String  patternChars = "GyMdkHmsSEDFwWahKzZYuXL";
    ...
}

Y , ( DateFormatSymbols)?

static final int PATTERN_ERA                  =  0; // G
static final int PATTERN_YEAR                 =  1; // y
static final int PATTERN_MONTH                =  2; // M
static final int PATTERN_DAY_OF_MONTH         =  3; // d
static final int PATTERN_HOUR_OF_DAY1         =  4; // k
static final int PATTERN_HOUR_OF_DAY0         =  5; // H
static final int PATTERN_MINUTE               =  6; // m
static final int PATTERN_SECOND               =  7; // s
static final int PATTERN_MILLISECOND          =  8; // S
static final int PATTERN_DAY_OF_WEEK          =  9; // E
static final int PATTERN_DAY_OF_YEAR          = 10; // D
static final int PATTERN_DAY_OF_WEEK_IN_MONTH = 11; // F
static final int PATTERN_WEEK_OF_YEAR         = 12; // w
static final int PATTERN_WEEK_OF_MONTH        = 13; // W
static final int PATTERN_AM_PM                = 14; // a
static final int PATTERN_HOUR1                = 15; // h
static final int PATTERN_HOUR0                = 16; // K
static final int PATTERN_ZONE_NAME            = 17; // z
static final int PATTERN_ZONE_VALUE           = 18; // Z
static final int PATTERN_WEEK_YEAR            = 19; // Y
static final int PATTERN_ISO_DAY_OF_WEEK      = 20; // u
static final int PATTERN_ISO_ZONE             = 21; // X
static final int PATTERN_MONTH_STANDALONE     = 22; // L

Y ( ):

static final int PATTERN_WEEK_YEAR            = 19; // Y

*_WEEK_YEAR , YEAR ( PATTERN_YEAR).

static final int PATTERN_YEAR                 =  1; // y

, (, wiki). ? SimpleDateFormat, , PATTERN_WEEK_YEAR PATTERN_YEAR . ( , DateFormatSymbols.java)... , wiki.


... java ( java doc ), JDK.

+1

, (BST) .

Note that "Y" is the week of the year, what you want to use is "y"

https://docs.oracle.com/javase/8/docs/api/java/text/SimpleDateFormat.html

-1
source

Source: https://habr.com/ru/post/1684037/


All Articles