提交 2483d502 编写于 作者: O okutsu

4267450: (cal) API: Need public API to calculate, format and parse "year of week"

6549953: (cal) WEEK_OF_YEAR and DAY_OF_YEAR calculation problems around Gregorian cutover
Reviewed-by: peytoia
上级 1e4cca65
#
# Copyright (c) 1996, 2007, Oracle and/or its affiliates. All rights reserved.
# Copyright (c) 1996, 2010, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
......@@ -29,6 +29,7 @@ FILES_java = \
java/text/AttributedString.java \
java/text/BreakDictionary.java \
java/text/BreakIterator.java \
java/text/CalendarBuilder.java \
java/text/CharacterIterator.java \
java/text/CharacterIteratorFieldDelegate.java \
java/text/ChoiceFormat.java \
......
/*
* Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package java.text;
import java.util.Calendar;
import static java.util.GregorianCalendar.*;
/**
* {@code CalendarBuilder} keeps field-value pairs for setting
* the calendar fields of the given {@code Calendar}. It has the
* {@link Calendar#FIELD_COUNT FIELD_COUNT}-th field for the week year
* support. Also {@code ISO_DAY_OF_WEEK} is used to specify
* {@code DAY_OF_WEEK} in the ISO day of week numbering.
*
* <p>{@code CalendarBuilder} retains the semantic of the pseudo
* timestamp for fields. {@code CalendarBuilder} uses a single
* int array combining fields[] and stamp[] of {@code Calendar}.
*
* @author Masayoshi Okutsu
*/
class CalendarBuilder {
/*
* Pseudo time stamp constants used in java.util.Calendar
*/
private static final int UNSET = 0;
private static final int COMPUTED = 1;
private static final int MINIMUM_USER_STAMP = 2;
private static final int MAX_FIELD = FIELD_COUNT + 1;
public static final int WEEK_YEAR = FIELD_COUNT;
public static final int ISO_DAY_OF_WEEK = 1000; // pseudo field index
// stamp[] (lower half) and field[] (upper half) combined
private final int[] field;
private int nextStamp;
private int maxFieldIndex;
CalendarBuilder() {
field = new int[MAX_FIELD * 2];
nextStamp = MINIMUM_USER_STAMP;
maxFieldIndex = -1;
}
CalendarBuilder set(int index, int value) {
if (index == ISO_DAY_OF_WEEK) {
index = DAY_OF_WEEK;
value = toCalendarDayOfWeek(value);
}
field[index] = nextStamp++;
field[MAX_FIELD + index] = value;
if (index > maxFieldIndex && index < FIELD_COUNT) {
maxFieldIndex = index;
}
return this;
}
CalendarBuilder addYear(int value) {
field[MAX_FIELD + YEAR] += value;
field[MAX_FIELD + WEEK_YEAR] += value;
return this;
}
boolean isSet(int index) {
if (index == ISO_DAY_OF_WEEK) {
index = DAY_OF_WEEK;
}
return field[index] > UNSET;
}
Calendar establish(Calendar cal) {
boolean weekDate = isSet(WEEK_YEAR)
&& field[WEEK_YEAR] > field[YEAR];
if (weekDate && !cal.isWeekDateSupported()) {
// Use YEAR instead
if (!isSet(YEAR)) {
set(YEAR, field[MAX_FIELD + WEEK_YEAR]);
}
weekDate = false;
}
cal.clear();
// Set the fields from the min stamp to the max stamp so that
// the field resolution works in the Calendar.
for (int stamp = MINIMUM_USER_STAMP; stamp < nextStamp; stamp++) {
for (int index = 0; index <= maxFieldIndex; index++) {
if (field[index] == stamp) {
cal.set(index, field[MAX_FIELD + index]);
break;
}
}
}
if (weekDate) {
int weekOfYear = isSet(WEEK_OF_YEAR) ? field[MAX_FIELD + WEEK_OF_YEAR] : 1;
int dayOfWeek = isSet(DAY_OF_WEEK) ?
field[MAX_FIELD + DAY_OF_WEEK] : cal.getFirstDayOfWeek();
if (!isValidDayOfWeek(dayOfWeek) && cal.isLenient()) {
if (dayOfWeek >= 8) {
dayOfWeek--;
weekOfYear += dayOfWeek / 7;
dayOfWeek = (dayOfWeek % 7) + 1;
} else {
while (dayOfWeek <= 0) {
dayOfWeek += 7;
weekOfYear--;
}
}
dayOfWeek = toCalendarDayOfWeek(dayOfWeek);
}
cal.setWeekDate(field[MAX_FIELD + WEEK_YEAR], weekOfYear, dayOfWeek);
}
return cal;
}
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append("CalendarBuilder:[");
for (int i = 0; i < field.length; i++) {
if (isSet(i)) {
sb.append(i).append('=').append(field[MAX_FIELD + i]).append(',');
}
}
int lastIndex = sb.length() - 1;
if (sb.charAt(lastIndex) == ',') {
sb.setLength(lastIndex);
}
sb.append(']');
return sb.toString();
}
static int toISODayOfWeek(int calendarDayOfWeek) {
return calendarDayOfWeek == SUNDAY ? 7 : calendarDayOfWeek - 1;
}
static int toCalendarDayOfWeek(int isoDayOfWeek) {
if (!isValidDayOfWeek(isoDayOfWeek)) {
// adjust later for lenient mode
return isoDayOfWeek;
}
return isoDayOfWeek == 7 ? SUNDAY : isoDayOfWeek + 1;
}
static boolean isValidDayOfWeek(int dayOfWeek) {
return dayOfWeek > 0 && dayOfWeek <= 7;
}
}
/*
* Copyright (c) 1996, 2006, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1996, 2010, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
......@@ -226,7 +226,29 @@ public class DateFormatSymbols implements Serializable, Cloneable {
* Unlocalized date-time pattern characters. For example: 'y', 'd', etc.
* All locales use the same these unlocalized pattern characters.
*/
static final String patternChars = "GyMdkHmsSEDFwWahKzZ";
static final String patternChars = "GyMdkHmsSEDFwWahKzZYu";
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
/**
* Localized date-time pattern characters. For example, a locale may
......@@ -505,7 +527,7 @@ public class DateFormatSymbols implements Serializable, Cloneable {
* @return the localized date-time pattern characters.
*/
public String getLocalPatternChars() {
return new String(localPatternChars);
return localPatternChars;
}
/**
......@@ -514,7 +536,8 @@ public class DateFormatSymbols implements Serializable, Cloneable {
* pattern characters.
*/
public void setLocalPatternChars(String newLocalPatternChars) {
localPatternChars = new String(newLocalPatternChars);
// Call toString() to throw an NPE in case the argument is null
localPatternChars = newLocalPatternChars.toString();
}
/**
......@@ -699,7 +722,7 @@ public class DateFormatSymbols implements Serializable, Cloneable {
} else {
dst.zoneStrings = null;
}
dst.localPatternChars = new String (src.localPatternChars);
dst.localPatternChars = src.localPatternChars;
}
/**
......
/*
* Copyright (c) 1996, 2007, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1996, 2010, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
......@@ -119,7 +119,7 @@ import sun.util.resources.LocaleData;
* calculating its time or calendar field values if any out-of-range field
* value has been set.
*
* <h4>First Week</h4>
* <h4><a name="first_week">First Week</a></h4>
*
* <code>Calendar</code> defines a locale-specific seven day week using two
* parameters: the first day of the week and the minimal days in first week
......@@ -2195,6 +2195,101 @@ public abstract class Calendar implements Serializable, Cloneable, Comparable<Ca
return minimalDaysInFirstWeek;
}
/**
* Returns whether this {@code Calendar} supports week dates.
*
* <p>The default implementation of this method returns {@code false}.
*
* @return {@code true} if this {@code Calendar} supports week dates;
* {@code false} otherwise.
* @see #getWeekYear()
* @see #setWeekDate(int,int,int)
* @see #getWeeksInWeekYear()
* @since 1.7
*/
public boolean isWeekDateSupported() {
return false;
}
/**
* Returns the week year represented by this {@code Calendar}. The
* week year is in sync with the week cycle. The {@linkplain
* #getFirstDayOfWeek() first day of the first week} is the first
* day of the week year.
*
* <p>The default implementation of this method throws an
* {@link UnsupportedOperationException}.
*
* @return the week year of this {@code Calendar}
* @exception UnsupportedOperationException
* if any week year numbering isn't supported
* in this {@code Calendar}.
* @see #isWeekDateSupported()
* @see #getFirstDayOfWeek()
* @see #getMinimalDaysInFirstWeek()
* @since 1.7
*/
public int getWeekYear() {
throw new UnsupportedOperationException();
}
/**
* Sets the date of this {@code Calendar} with the the given date
* specifiers - week year, week of year, and day of week.
*
* <p>Unlike the {@code set} method, all of the calendar fields
* and {@code time} values are calculated upon return.
*
* <p>If {@code weekOfYear} is out of the valid week-of-year range
* in {@code weekYear}, the {@code weekYear} and {@code
* weekOfYear} values are adjusted in lenient mode, or an {@code
* IllegalArgumentException} is thrown in non-lenient mode.
*
* <p>The default implementation of this method throws an
* {@code UnsupportedOperationException}.
*
* @param weekYear the week year
* @param weekOfYear the week number based on {@code weekYear}
* @param dayOfWeek the day of week value: one of the constants
* for the {@link #DAY_OF_WEEK} field: {@link
* #SUNDAY}, ..., {@link #SATURDAY}.
* @exception IllegalArgumentException
* if any of the given date specifiers is invalid
* or any of the calendar fields are inconsistent
* with the given date specifiers in non-lenient mode
* @exception UnsupportedOperationException
* if any week year numbering isn't supported in this
* {@code Calendar}.
* @see #isWeekDateSupported()
* @see #getFirstDayOfWeek()
* @see #getMinimalDaysInFirstWeek()
* @since 1.7
*/
public void setWeekDate(int weekYear, int weekOfYear, int dayOfWeek) {
throw new UnsupportedOperationException();
}
/**
* Returns the number of weeks in the week year represented by this
* {@code Calendar}.
*
* <p>The default implementation of this method throws an
* {@code UnsupportedOperationException}.
*
* @return the number of weeks in the week year.
* @exception UnsupportedOperationException
* if any week year numbering isn't supported in this
* {@code Calendar}.
* @see #WEEK_OF_YEAR
* @see #isWeekDateSupported()
* @see #getWeekYear()
* @see #getActualMaximum(int)
* @since 1.7
*/
public int getWeeksInWeekYear() {
throw new UnsupportedOperationException();
}
/**
* Returns the minimum value for the given calendar field of this
* <code>Calendar</code> instance. The minimum value is defined as
......
/*
* Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* @test
* @bug 4267450
* @summary Unit test for week date support
*/
import java.text.*;
import java.util.*;
import static java.util.GregorianCalendar.*;
public class WeekDateTest {
static SimpleDateFormat ymdFormat = new SimpleDateFormat("yyyy-MM-dd");
static SimpleDateFormat ywdFormat = new SimpleDateFormat("YYYY-'W'ww-u");
static {
ymdFormat.setCalendar(newCalendar());
ywdFormat.setCalendar(newCalendar());
}
// Round-trip Data
static final String[][] roundTripData = {
{ "2005-01-01", "2004-W53-6" },
{ "2005-01-02", "2004-W53-7" },
{ "2005-12-31", "2005-W52-6" },
{ "2007-01-01", "2007-W01-1" },
{ "2007-12-30", "2007-W52-7" },
{ "2007-12-31", "2008-W01-1" },
{ "2008-01-01", "2008-W01-2" },
{ "2008-12-29", "2009-W01-1" },
{ "2008-12-31", "2009-W01-3" },
{ "2009-01-01", "2009-W01-4" },
{ "2009-12-31", "2009-W53-4" },
{ "2010-01-03", "2009-W53-7" },
{ "2009-12-31", "2009-W53-4" },
{ "2010-01-01", "2009-W53-5" },
{ "2010-01-02", "2009-W53-6" },
{ "2010-01-03", "2009-W53-7" },
{ "2008-12-28", "2008-W52-7" },
{ "2008-12-29", "2009-W01-1" },
{ "2008-12-30", "2009-W01-2" },
{ "2008-12-31", "2009-W01-3" },
{ "2009-01-01", "2009-W01-4" },
{ "2009-01-01", "2009-W01-4" },
};
// Data for leniency test
static final String[][] leniencyData = {
{ "2008-12-28", "2009-W01-0" },
{ "2010-01-04", "2009-W53-8" },
{ "2008-12-29", "2008-W53-1" },
};
static final String[] invalidData = {
"2010-W00-1",
"2010-W55-1",
"2010-W03-0",
"2010-W04-8",
"2010-W04-19"
};
public static void main(String[] args) throws Exception {
formatTest(roundTripData);
parseTest(roundTripData);
parseTest(leniencyData);
nonLenientTest(invalidData);
noWeekDateSupport();
}
private static void formatTest(String[][] data) throws Exception {
for (String[] dates : data) {
String regularDate = dates[0];
String weekDate = dates[1];
Date date = null;
date = ymdFormat.parse(regularDate);
String s = ywdFormat.format(date);
if (!s.equals(weekDate)) {
throw new RuntimeException("format: got="+s+", expecetd="+weekDate);
}
}
}
private static void parseTest(String[][] data) throws Exception {
for (String[] dates : data) {
String regularDate = dates[0];
String weekDate = dates[1];
Date date1 = null, date2 = null;
date1 = ymdFormat.parse(regularDate);
date2 = ywdFormat.parse(weekDate);
if (!date1.equals(date2)) {
System.err.println(regularDate + ": date1 = " + date1);
System.err.println(weekDate + ": date2 = " + date2);
throw new RuntimeException("parse: date1 != date2");
}
}
}
// Non-lenient mode test
private static void nonLenientTest(String[] data) {
ywdFormat.setLenient(false);
for (String date : data) {
try {
Date d = ywdFormat.parse(date);
throw new RuntimeException("No ParseException thrown with " + date);
} catch (ParseException e) {
// OK
}
}
ywdFormat.setLenient(true);
}
private static void noWeekDateSupport() throws Exception {
// Tests with Japanese Imperial Calendar that doesn't support week dates.
Calendar jcal = Calendar.getInstance(TimeZone.getTimeZone("GMT"),
new Locale("ja", "JP", "JP"));
jcal.setFirstDayOfWeek(MONDAY);
jcal.setMinimalDaysInFirstWeek(4);
SimpleDateFormat sdf = new SimpleDateFormat("Y-'W'ww-u");
sdf.setCalendar(jcal);
Date d = sdf.parse("21-W01-3"); // 2008-12-31 == H20-12-31
GregorianCalendar gcal = newCalendar();
gcal.setTime(d);
if (gcal.get(YEAR) != 2008
|| gcal.get(MONTH) != DECEMBER
|| gcal.get(DAY_OF_MONTH) != 31) {
String s = String.format("noWeekDateSupport: got %04d-%02d-%02d, expected 2008-12-31%n",
gcal.get(YEAR),
gcal.get(MONTH)+1,
gcal.get(DAY_OF_MONTH));
throw new RuntimeException(s);
}
}
private static GregorianCalendar newCalendar() {
// Use GMT to avoid any surprises related DST transitions.
GregorianCalendar cal = new GregorianCalendar(TimeZone.getTimeZone("GMT"));
// Setup the ISO 8601 compatible parameters
cal.setFirstDayOfWeek(MONDAY);
cal.setMinimalDaysInFirstWeek(4);
return cal;
}
}
/*
* Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* @test
* @bug 4267450
* @summary Unit test for week date support
*/
import java.text.*;
import java.util.*;
import static java.util.GregorianCalendar.*;
public class WeekDateTest {
// Week dates are in the ISO numbering for day-of-week.
static int[][][] data = {
// Calendar year-date, Week year-date
{{ 2005, 01, 01}, {2004, 53, 6}},
{{ 2005, 01, 02}, {2004, 53, 7}},
{{ 2005, 12, 31}, {2005, 52, 6}},
{{ 2007, 01, 01}, {2007, 01, 1}},
{{ 2007, 12, 30}, {2007, 52, 7}},
{{ 2007, 12, 31}, {2008, 01, 1}},
{{ 2008, 01, 01}, {2008, 01, 2}},
{{ 2008, 12, 29}, {2009, 01, 1}},
{{ 2008, 12, 31}, {2009, 01, 3}},
{{ 2009, 01, 01}, {2009, 01, 4}},
{{ 2009, 12, 31}, {2009, 53, 4}},
{{ 2010, 01, 03}, {2009, 53, 7}},
{{ 2009, 12, 31}, {2009, 53, 4}},
{{ 2010, 01, 01}, {2009, 53, 5}},
{{ 2010, 01, 02}, {2009, 53, 6}},
{{ 2010, 01, 03}, {2009, 53, 7}},
{{ 2008, 12, 28}, {2008, 52, 7}},
{{ 2008, 12, 29}, {2009, 01, 1}},
{{ 2008, 12, 30}, {2009, 01, 2}},
{{ 2008, 12, 31}, {2009, 01, 3}},
{{ 2009, 01, 01}, {2009, 01, 4}}
};
public static void main(String[] args) {
GregorianCalendar cal = newCalendar();
for (int[][] dates : data) {
int[] expected = dates[0];
int[] weekDate = dates[1];
// Convert ISO 8601 day-of-week to Calendar.DAY_OF_WEEK.
int dayOfWeek = weekDate[2] == 7 ? SUNDAY : weekDate[2] + 1;
cal.clear();
cal.setWeekDate(weekDate[0], weekDate[1], dayOfWeek);
if (cal.get(YEAR) != expected[0]
|| cal.get(MONTH)+1 != expected[1]
|| cal.get(DAY_OF_MONTH) != expected[2]) {
String s = String.format("got=%4d-%02d-%02d, expected=%4d-%02d-%02d",
cal.get(YEAR), cal.get(MONTH)+1, cal.get(DAY_OF_MONTH),
expected[0], expected[1], expected[2]);
throw new RuntimeException(s);
}
if (cal.getWeekYear() != weekDate[0]
|| cal.get(WEEK_OF_YEAR) != weekDate[1]
|| cal.get(DAY_OF_WEEK) != dayOfWeek) {
String s = String.format(
"got=%4d-W%02d-%d, expected=%4d-W%02d-%d (not ISO day-of-week)",
cal.getWeekYear(), cal.get(WEEK_OF_YEAR), cal.get(DAY_OF_WEEK),
weekDate[0], weekDate[1], dayOfWeek);
throw new RuntimeException(s);
}
}
// Test getWeeksInWeekYear().
// If we avoid the first week of January and the last week of
// December, getWeeksInWeekYear() and
// getActualMaximum(WEEK_OF_YEAR) values should be the same.
for (int year = 2000; year <= 2100; year++) {
cal.clear();
cal.set(year, JUNE, 1);
int n = cal.getWeeksInWeekYear();
if (n != cal.getActualMaximum(WEEK_OF_YEAR)) {
String s = String.format("getWeeksInWeekYear() = %d, "
+ "getActualMaximum(WEEK_OF_YEAR) = %d%n",
n, cal.getActualMaximum(WEEK_OF_YEAR));
throw new RuntimeException(s);
}
cal.setWeekDate(cal.getWeekYear(), 1, MONDAY);
System.out.println(cal.getTime());
if (cal.getWeeksInWeekYear() != n) {
String s = String.format("first day: got %d, expected %d%n",
cal.getWeeksInWeekYear(), n);
throw new RuntimeException(s);
}
cal.setWeekDate(cal.getWeekYear(), n, SUNDAY);
System.out.println(cal.getTime());
if (cal.getWeeksInWeekYear() != n) {
String s = String.format("last day: got %d, expected %d%n",
cal.getWeeksInWeekYear(), n);
throw new RuntimeException(s);
}
}
}
private static GregorianCalendar newCalendar() {
// Use GMT to avoid any surprises related DST transitions.
GregorianCalendar cal = new GregorianCalendar(TimeZone.getTimeZone("GMT"));
if (!cal.isWeekDateSupported()) {
throw new RuntimeException("Week dates not supported");
}
// Setup the ISO 8601 compatible parameters
cal.setFirstDayOfWeek(MONDAY);
cal.setMinimalDaysInFirstWeek(4);
return cal;
}
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册