Aquí hay una actualización de Java 8 con algo de código, ya que GregorianCalendar probablemente quedará obsoleto o se eliminará de futuras versiones de JDK.
El nuevo código se maneja en la WeekFields
clase, y específicamente para minúsculas y
/ mayúsculas Y
con el descriptor de weekBasedYear()
acceso de campo.
Devuelve un campo para acceder al año de un año basado en semanas basado en este WeekFields. Esto representa el concepto del año en el que las semanas comienzan en un día fijo de la semana, como el lunes y cada semana pertenece exactamente a un año. Este campo se usa normalmente con dayOfWeek () y weekOfWeekBasedYear ().
La semana uno (1) es la semana que comienza en getFirstDayOfWeek () donde hay al menos días getMinimalDaysInFirstWeek () en el año. Por lo tanto, la semana uno puede comenzar antes del comienzo del año. Si la primera semana comienza después del comienzo del año, el período anterior corresponde a la última semana del año anterior.
Este campo se puede utilizar con cualquier sistema de calendario.
En la fase de resolución del análisis, se puede crear una fecha a partir de un año basado en la semana, una semana del año y un día de la semana.
En modo estricto, los tres campos se validan con su rango de valores válidos. El campo de la semana del año se valida para garantizar que el año basado en la semana resultante sea el año solicitado en la semana.
En el modo inteligente, los tres campos se validan con su rango de valores válidos. El campo del año basado en la semana de la semana se valida de 1 a 53, lo que significa que la fecha resultante puede estar en el año basado en la semana siguiente al especificado.
En modo indulgente, el año y el día de la semana se validan con el rango de valores válidos. La fecha resultante se calcula equivalente al siguiente enfoque de tres etapas. Primero, cree una fecha el primer día de la primera semana del año basado en la semana solicitado. Luego, tome el año basado en la semana de la semana, reste uno y agregue la cantidad en semanas a la fecha. Finalmente, ajústese al día de la semana correcto dentro de la semana localizada.
La configuración de esta WeekFields
instancia depende de la ubicación y puede tener diferentes configuraciones dependiendo de ella, los países de EE. UU. Y Europa como Francia pueden tener un día diferente como comienzo de la semana.
Por ejemplo, DateFormatterBuilder
de Java 8, cree una instancia del analizador con la configuración regional y use esta configuración regional para el Y
símbolo:
public final class DateTimeFormatterBuilder {
...
private void parsePattern(String pattern) {
...
} else if (cur == 'Y') {
appendInternal(new WeekBasedFieldPrinterParser(cur, count));
} else {
...
static final class WeekBasedFieldPrinterParser implements DateTimePrinterParser {
...
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);
}
...
}
...
}
Aquí hay un ejemplo
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 en lo que se refiere a la configuración regional y la carcasa superior Y
, se puede jugar ya sea con la opción de línea de comandos -Duser.language=
( fr
, en
, es
, etc.), o forzar la configuración regional en tiempo de invocación:
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)));