Eu me pergunto por que 'Y' retorna 2012 enquanto 'y' retorna 2011 em SimpleDateFormat
:
System.out.println(new SimpleDateFormat("Y").format(new Date())); // prints 2012
System.out.println(new SimpleDateFormat("y").format(new Date())); // prints 2011
Alguém pode explicar por quê?
java
date
simpledateformat
Eng.Fouad
fonte
fonte
Respostas:
semana ano e ano. De Javadoc
fonte
$ date Wed Dec 30 00:42:51 UTC 2015
$ date +%G 2015
$ date +%Y 2015
Alguns software está confuso:strftime
calcula hoje (2015/12/29) como tendo semana 53 e semana-ano como 2015.Aqui está uma atualização do Java 8 com algum código, já que GregorianCalendar provavelmente será descontinuado ou removido de versões futuras do JDK.
O novo código é tratado na
WeekFields
classe e especificamente para maiúsculasy
/ minúsculasY
com oweekBasedYear()
acessador de campo.A configuração desta
WeekFields
instância depende da localidade e pode ter configurações diferentes dependendo dela, os EUA e países europeus como a França podem ter um dia diferente como início da semana.Por exemplo, o
DateFormatterBuilder
do Java 8, instancie o analisador com a localidade e use esta localidade para oY
símbolo: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); } ... } ... }
Aqui está um exemplo
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()));
E no que diz respeito do local e maiúsculas
Y
, você pode jogar com a opção de linha de comando-Duser.language=
(fr
,en
,es
, etc.), ou forçar o local em tempo de invocação: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)));
fonte
Formato
Y
para obter o ano da semana se o calendário suportar o ano da semana. (getCalendar().isWeekDateSupported()
)fonte
Aprendi da maneira mais difícil que a biblioteca de tags JSTL
format:date
comshort
o formato solicitado usa YYYY nos bastidores. O que pode realmente adiantar a data impressa um ano.fonte
Eu converto uma data para frente e para trás - você esperaria o mesmo ano ao fazer isso.
Observe como avança um!
Isso é ruim: YYYY!
Você pode executá-lo aqui .
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); } }
Isso é bom: aaaa
fonte