Интересно, почему 'Y' возвращает 2012 год, а 'y' возвращает 2011 год в SimpleDateFormat
:
System.out.println(new SimpleDateFormat("Y").format(new Date())); // prints 2012
System.out.println(new SimpleDateFormat("y").format(new Date())); // prints 2011
Кто-нибудь может объяснить почему?
java
date
simpledateformat
Eng.Fouad
источник
источник
Ответы:
неделя год и год. Из javadoc
источник
$ date Wed Dec 30 00:42:51 UTC 2015
$ date +%G 2015
$ date +%Y 2015
Некоторое программное обеспечение сбивает с толку:strftime
сегодня (29.12.2015) вычисляется как неделя 53, а неделя-год - как 2015.Вот обновление Java 8 с некоторым кодом, поскольку GregorianCalendar, вероятно, будет устаревшим или удаленным из будущих версий JDK.
Новый код обрабатывается в
WeekFields
классе, особенно для нижнегоy
/ верхнего регистраY
с помощьюweekBasedYear()
метода доступа к полю.Настройка этого
WeekFields
экземпляра зависит от локали и может иметь разные настройки в зависимости от нее. В США и европейских странах, таких как Франция, может быть другой день в качестве начала недели.Например,
DateFormatterBuilder
Java 8, создайте экземпляр синтаксического анализатора с локалью и используйте эту локаль дляY
символа:public final class DateTimeFormatterBuilder { ... private void parsePattern(String pattern) { ... } else if (cur == 'Y') { // Fields defined by Locale appendInternal(new WeekBasedFieldPrinterParser(cur, count)); } else { ... static final class WeekBasedFieldPrinterParser implements DateTimePrinterParser { ... /** * Gets the printerParser to use based on the field and the locale. * * @param locale the locale to use, not null * @return the formatter, not null * @throws IllegalArgumentException if the formatter cannot be found */ private DateTimePrinterParser printerParser(Locale locale) { WeekFields weekDef = WeekFields.of(locale); TemporalField field = null; switch (chr) { case 'Y': field = weekDef.weekBasedYear(); if (count == 2) { return new ReducedPrinterParser(field, 2, 2, 0, ReducedPrinterParser.BASE_DATE, 0); } else { return new NumberPrinterParser(field, count, 19, (count < 4) ? SignStyle.NORMAL : SignStyle.EXCEEDS_PAD, -1); } case 'e': case 'c': field = weekDef.dayOfWeek(); break; case 'w': field = weekDef.weekOfWeekBasedYear(); break; case 'W': field = weekDef.weekOfMonth(); break; default: throw new IllegalStateException("unreachable"); } return new NumberPrinterParser(field, (count == 2 ? 2 : 1), 2, SignStyle.NOT_NEGATIVE); } ... } ... }
Вот пример
System.out.format("Conundrum : %s%n", ZonedDateTime.of(2015, 12, 30, 0, 0, 0, 0, ZoneId.of("UTC")) .format(DateTimeFormatter.ofPattern("YYYYMMdd'T'HHmms'S'"))); System.out.format("Solution : %s%n", ZonedDateTime.of(2015, 12, 30, 0, 0, 0, 0, ZoneId.of("UTC")) .format(DateTimeFormatter.ofPattern("yyyyMMdd'T'HHmms'S'"))); System.out.format("JVM Locale first day of week : %s%n", WeekFields.of(Locale.getDefault()).getFirstDayOfWeek()); System.out.format("US first day of week : %s%n", WeekFields.of(Locale.US).getFirstDayOfWeek()); System.out.format("France first day of week : %s%n", WeekFields.of(Locale.FRANCE).getFirstDayOfWeek()); System.out.format("JVM Locale min days in 1st week : %s%n", WeekFields.of(Locale.getDefault()).getMinimalDaysInFirstWeek()); System.out.format("US min days in 1st week : %s%n", WeekFields.of(Locale.US).getMinimalDaysInFirstWeek()); System.out.format("JVM Locale min days in 1st week : %s%n", WeekFields.of(Locale.FRANCE).getMinimalDaysInFirstWeek()); System.out.format("JVM Locale week based year (big Y): %s%n", ZonedDateTime.of(2015, 12, 30, 0, 0, 0, 0, ZoneId.of("UTC")).get(WeekFields.of(Locale.FRANCE).weekBasedYear())); System.out.format("France week based year (big Y) : %s%n", ZonedDateTime.of(2015, 12, 30, 0, 0, 0, 0, ZoneId.of("UTC")).get(WeekFields.of(Locale.FRANCE).weekBasedYear())); System.out.format("US week based year (big Y) : %s%n", ZonedDateTime.of(2015, 12, 30, 0, 0, 0, 0, ZoneId.of("UTC")).get(WeekFields.of(Locale.US).weekBasedYear()));
И в отношении локали и верхнего корпуса
Y
, вы можете играть с опцией командной строки-Duser.language=
(fr
,en
,es
и т.д.), или принудительно локаль во время вызова:System.out.format("English localized : %s%n", ZonedDateTime.of(2015, 12, 30, 0, 0, 0, 0, ZoneId.of("UTC")) .format(DateTimeFormatter.ofPattern("YYYYMMdd'T'HHmms'S'", Locale.ENGLISH))); System.out.format("French localized : %s%n", ZonedDateTime.of(2015, 12, 30, 0, 0, 0, 0, ZoneId.of("UTC")) .format(DateTimeFormatter.ofPattern("YYYYMMdd'T'HHmms'S'", Locale.FRENCH)));
источник
Отформатируйте год
Y
недели, если календарь поддерживает год недели. (getCalendar().isWeekDateSupported()
)источник
Я узнал , Трудный путь к JSTL библиотеки тегов
format:date
сshort
запрошенной формат использует YYYY под одеялом. Что действительно может перевернуть напечатанную дату на год вперед.источник
Я конвертирую дату туда и обратно - вы ожидаете того же года, когда вы это делаете.
Обратите внимание, как он продвигается вперед!
Это плохо: ГГГГ!
Вы можете запустить его здесь .
import java.util.Date; import java.text.SimpleDateFormat; import java.text.ParseException; import static java.lang.System.out; class Playground { public static Date convertYYYYMMDDStr(String s) { SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); Date result = null; try { result = sdf.parse(s); } catch(ParseException e) { e.printStackTrace(); } return result; } public static String formatDateToStrWithSDF(Date d, SimpleDateFormat s) { return s.format(d); } public static void main(String[ ] args) { // DON'T DO. Use yyyy instead of YYYY SimpleDateFormat sdfdmy = new SimpleDateFormat("dd-MM-YYYY"); String jan1st2020sb = "2020-01-01"; Date jan1st2020d = convertYYYYMMDDStr(jan1st2020sb); String jan1st2020sa = formatDateToStrWithSDF(jan1st2020d, sdfdmy); out.println(jan1st2020sb); out.println(jan1st2020d); out.println(jan1st2020sa); String dec31st2020sb = "2020-12-31"; Date dec31st2020d = convertYYYYMMDDStr(dec31st2020sb); String dec31st2020sa = formatDateToStrWithSDF(dec31st2020d, sdfdmy); out.println(dec31st2020sb); out.println(dec31st2020d); out.println(dec31st2020sa); } }
Это хорошо: гггг
источник