diff options
author | Dominik Stadler <centic@apache.org> | 2019-10-09 19:12:59 +0000 |
---|---|---|
committer | Dominik Stadler <centic@apache.org> | 2019-10-09 19:12:59 +0000 |
commit | b10f94cc75d00d2b215f3a148dd4e79bbaf2b1b3 (patch) | |
tree | 8d81cb6b541655373493c8c1bc3d6b0f2c6b9788 /src/java | |
parent | 97c21e31b10a37365cf499dbe1c5345680c872df (diff) | |
download | poi-b10f94cc75d00d2b215f3a148dd4e79bbaf2b1b3.tar.gz poi-b10f94cc75d00d2b215f3a148dd4e79bbaf2b1b3.zip |
63779 Add support for the new Java date/time API added in Java 8
Deprecate HSSFDateUtil
Closes #160 on Github
git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1868198 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'src/java')
6 files changed, 339 insertions, 32 deletions
diff --git a/src/java/org/apache/poi/hssf/usermodel/DVConstraint.java b/src/java/org/apache/poi/hssf/usermodel/DVConstraint.java index f3f5e557a4..5317969278 100644 --- a/src/java/org/apache/poi/hssf/usermodel/DVConstraint.java +++ b/src/java/org/apache/poi/hssf/usermodel/DVConstraint.java @@ -31,6 +31,7 @@ import org.apache.poi.ss.formula.ptg.NumberPtg; import org.apache.poi.ss.formula.ptg.Ptg; import org.apache.poi.ss.formula.ptg.StringPtg; import org.apache.poi.ss.usermodel.DataValidationConstraint; +import org.apache.poi.ss.usermodel.DateUtil; import org.apache.poi.util.LocaleUtil; /** @@ -242,7 +243,7 @@ public class DVConstraint implements DataValidationConstraint { if (timeStr == null) { return null; } - return Double.valueOf(HSSFDateUtil.convertTime(timeStr)); + return Double.valueOf(DateUtil.convertTime(timeStr)); } /** * @param dateFormat pass <code>null</code> for default YYYYMMDD @@ -254,7 +255,7 @@ public class DVConstraint implements DataValidationConstraint { } Date dateVal; if (dateFormat == null) { - dateVal = HSSFDateUtil.parseYYYYMMDDDate(dateStr); + dateVal = DateUtil.parseYYYYMMDDDate(dateStr); } else { try { dateVal = dateFormat.parse(dateStr); @@ -263,7 +264,7 @@ public class DVConstraint implements DataValidationConstraint { + "' using specified format '" + dateFormat + "'", e); } } - return Double.valueOf(HSSFDateUtil.getExcelDate(dateVal)); + return Double.valueOf(DateUtil.getExcelDate(dateVal)); } public static DVConstraint createCustomFormulaConstraint(String formula) { diff --git a/src/java/org/apache/poi/hssf/usermodel/HSSFCell.java b/src/java/org/apache/poi/hssf/usermodel/HSSFCell.java index 12788d5bf9..7b309fe54f 100644 --- a/src/java/org/apache/poi/hssf/usermodel/HSSFCell.java +++ b/src/java/org/apache/poi/hssf/usermodel/HSSFCell.java @@ -18,6 +18,7 @@ package org.apache.poi.hssf.usermodel; import java.text.SimpleDateFormat; +import java.time.LocalDateTime; import java.util.Calendar; import java.util.Date; import java.util.Iterator; @@ -47,6 +48,7 @@ import org.apache.poi.ss.usermodel.CellStyle; import org.apache.poi.ss.usermodel.CellType; import org.apache.poi.ss.usermodel.CellValue; import org.apache.poi.ss.usermodel.Comment; +import org.apache.poi.ss.usermodel.DateUtil; import org.apache.poi.ss.usermodel.FormulaError; import org.apache.poi.ss.usermodel.Hyperlink; import org.apache.poi.ss.usermodel.RichTextString; @@ -453,11 +455,22 @@ public class HSSFCell extends CellBase { * {@inheritDoc} * * <p>In HSSF, only the number of days is stored. The fractional part is ignored.</p> - * @see HSSFDateUtil + * @see DateUtil * @see org.apache.poi.ss.usermodel.DateUtil */ protected void setCellValueImpl(Date value) { - setCellValue(HSSFDateUtil.getExcelDate(value, _book.getWorkbook().isUsing1904DateWindowing())); + setCellValue(DateUtil.getExcelDate(value, _book.getWorkbook().isUsing1904DateWindowing())); + } + + /** + * {@inheritDoc} + * + * <p>In HSSF, only the number of days is stored. The fractional part is ignored.</p> + * @see DateUtil + * @see org.apache.poi.ss.usermodel.DateUtil + */ + protected void setCellValueImpl(LocalDateTime value) { + setCellValue(DateUtil.getExcelDate(value, _book.getWorkbook().isUsing1904DateWindowing())); } /** @@ -465,7 +478,7 @@ public class HSSFCell extends CellBase { */ @Override protected void setCellValueImpl(Calendar value) { - setCellValue( HSSFDateUtil.getExcelDate(value, _book.getWorkbook().isUsing1904DateWindowing()) ); + setCellValue( DateUtil.getExcelDate(value, _book.getWorkbook().isUsing1904DateWindowing()) ); } /** @@ -679,9 +692,28 @@ public class HSSFCell extends CellBase { } double value = getNumericCellValue(); if (_book.getWorkbook().isUsing1904DateWindowing()) { - return HSSFDateUtil.getJavaDate(value, true); + return DateUtil.getJavaDate(value, true); } - return HSSFDateUtil.getJavaDate(value, false); + return DateUtil.getJavaDate(value, false); + } + + /** + * Get the value of the cell as a LocalDateTime. + * For strings we throw an exception. + * For blank cells we return a null. + * See {@link HSSFDataFormatter} for formatting + * this date into a string similar to how excel does. + */ + public LocalDateTime getLocalDateTimeCellValue() { + + if (_cellType == CellType.BLANK) { + return null; + } + double value = getNumericCellValue(); + if (_book.getWorkbook().isUsing1904DateWindowing()) { + return DateUtil.getLocalDateTime(value, true); + } + return DateUtil.getLocalDateTime(value, false); } /** @@ -853,7 +885,7 @@ public class HSSFCell extends CellBase { default: throw new IllegalStateException("Unexpected formula result type (" + _cellType + ")"); } - + } /** @@ -899,7 +931,7 @@ public class HSSFCell extends CellBase { /** * <p>Set the style for the cell. The style should be an HSSFCellStyle created/retreived from * the HSSFWorkbook.</p> - * + * * <p>To change the style of a cell without affecting other cells that use the same style, * use {@link org.apache.poi.ss.util.CellUtil#setCellStyleProperties(org.apache.poi.ss.usermodel.Cell, java.util.Map)}</p> * @@ -1001,7 +1033,7 @@ public class HSSFCell extends CellBase { return getCellFormula(); case NUMERIC: //TODO apply the dataformat for this cell - if (HSSFDateUtil.isCellDateFormatted(this)) { + if (DateUtil.isCellDateFormatted(this)) { SimpleDateFormat sdf = new SimpleDateFormat("dd-MMM-yyyy", LocaleUtil.getUserLocale()); sdf.setTimeZone(LocaleUtil.getUserTimeZone()); return sdf.format(getDateCellValue()); diff --git a/src/java/org/apache/poi/hssf/usermodel/HSSFDateUtil.java b/src/java/org/apache/poi/hssf/usermodel/HSSFDateUtil.java index eb415269e9..f0ff039fd1 100644 --- a/src/java/org/apache/poi/hssf/usermodel/HSSFDateUtil.java +++ b/src/java/org/apache/poi/hssf/usermodel/HSSFDateUtil.java @@ -30,8 +30,10 @@ import org.apache.poi.ss.usermodel.DateUtil; /** * Contains methods for dealing with Excel dates. + * @deprecated Use {@link DateUtil} instead */ -public class HSSFDateUtil extends DateUtil { +@Deprecated +public final class HSSFDateUtil extends DateUtil { protected static int absoluteDay(Calendar cal, boolean use1904windowing) { return DateUtil.absoluteDay(cal, use1904windowing); } diff --git a/src/java/org/apache/poi/ss/usermodel/Cell.java b/src/java/org/apache/poi/ss/usermodel/Cell.java index d806ef6842..c6a017b26b 100644 --- a/src/java/org/apache/poi/ss/usermodel/Cell.java +++ b/src/java/org/apache/poi/ss/usermodel/Cell.java @@ -17,6 +17,8 @@ package org.apache.poi.ss.usermodel; +import java.time.LocalDate; +import java.time.LocalDateTime; import java.util.Calendar; import java.util.Date; import java.util.Map; @@ -179,6 +181,42 @@ public interface Cell { void setCellValue(Date value); /** + * <p>Converts the supplied date to its equivalent Excel numeric value and sets + * that into the cell.</p> + * + * <p><b>Note</b> - There is actually no 'DATE' cell type in Excel. In many + * cases (when entering date values), Excel automatically adjusts the + * <i>cell style</i> to some date format, creating the illusion that the cell + * data type is now something besides {@link CellType#NUMERIC}. POI + * does not attempt to replicate this behaviour. To make a numeric cell + * display as a date, use {@link #setCellStyle(CellStyle)} etc.</p> + * + * @param value the numeric value to set this cell to. For formulas we'll set the + * precalculated value, for numerics we'll set its value. For other types we + * will change the cell to a numerics cell and set its value. + */ + void setCellValue(LocalDateTime value); + + /** + * <p>Converts the supplied date to its equivalent Excel numeric value and sets + * that into the cell.</p> + * + * <p><b>Note</b> - There is actually no 'DATE' cell type in Excel. In many + * cases (when entering date values), Excel automatically adjusts the + * <i>cell style</i> to some date format, creating the illusion that the cell + * data type is now something besides {@link CellType#NUMERIC}. POI + * does not attempt to replicate this behaviour. To make a numeric cell + * display as a date, use {@link #setCellStyle(CellStyle)} etc.</p> + * + * @param value the numeric value to set this cell to. For formulas we'll set the + * precalculated value, for numerics we'll set its value. For other types we + * will change the cell to a numerics cell and set its value. + */ + default void setCellValue(LocalDate value) { + setCellValue(value.atStartOfDay()); + } + + /** * <p>Set a date value for the cell. Excel treats dates as numeric so you will need to format the cell as * a date.</p> * <p> @@ -280,6 +318,18 @@ public interface Cell { Date getDateCellValue(); /** + * Get the value of the cell as a LocalDateTime. + * <p> + * For strings we throw an exception. For blank cells we return a null. + * </p> + * @return the value of the cell as a LocalDateTime + * @throws IllegalStateException if the cell type returned by {@link #getCellType()} is {@link CellType#STRING} + * @exception NumberFormatException if the cell value isn't a parsable <code>double</code>. + * @see DataFormatter for formatting this date into a string similar to how excel does. + */ + LocalDateTime getLocalDateTimeCellValue(); + + /** * Get the value of the cell as a XSSFRichTextString * <p> * For numeric cells we throw an exception. For blank cells we return an empty string. diff --git a/src/java/org/apache/poi/ss/usermodel/CellBase.java b/src/java/org/apache/poi/ss/usermodel/CellBase.java index 7193075fa7..819c789ca8 100644 --- a/src/java/org/apache/poi/ss/usermodel/CellBase.java +++ b/src/java/org/apache/poi/ss/usermodel/CellBase.java @@ -24,6 +24,7 @@ import org.apache.poi.ss.util.CellRangeAddress; import org.apache.poi.ss.util.CellReference; import org.apache.poi.util.Removal; +import java.time.LocalDateTime; import java.util.Calendar; import java.util.Date; import java.util.Locale; @@ -228,6 +229,15 @@ public abstract class CellBase implements Cell { setCellValueImpl(value); } + @Override + public void setCellValue(LocalDateTime value) { + if(value == null) { + setBlank(); + return; + } + setCellValueImpl(value); + } + /** * Implementation-specific way to set a date value. * <code>value</code> is guaranteed to be non-null. @@ -238,6 +248,15 @@ public abstract class CellBase implements Cell { protected abstract void setCellValueImpl(Date value); /** + * Implementation-specific way to set a date value. + * <code>value</code> is guaranteed to be non-null. + * The implementation is expected to adjust the cell type accordingly, so that after this call + * getCellType() or getCachedFormulaResultType() would return {@link CellType#NUMERIC}. + * @param value the new date to set + */ + protected abstract void setCellValueImpl(LocalDateTime value); + + /** * {@inheritDoc} */ @Override diff --git a/src/java/org/apache/poi/ss/usermodel/DateUtil.java b/src/java/org/apache/poi/ss/usermodel/DateUtil.java index fbf34b7ae7..981abb4a31 100644 --- a/src/java/org/apache/poi/ss/usermodel/DateUtil.java +++ b/src/java/org/apache/poi/ss/usermodel/DateUtil.java @@ -18,7 +18,11 @@ package org.apache.poi.ss.usermodel; +import org.apache.poi.ss.formula.ConditionalFormattingEvaluator; +import org.apache.poi.util.LocaleUtil; + import java.time.LocalDate; +import java.time.LocalDateTime; import java.time.LocalTime; import java.time.ZoneId; import java.time.format.DateTimeFormatter; @@ -31,13 +35,11 @@ import java.util.Date; import java.util.TimeZone; import java.util.regex.Pattern; -import org.apache.poi.ss.formula.ConditionalFormattingEvaluator; -import org.apache.poi.util.LocaleUtil; - /** * Contains methods for dealing with Excel dates. */ public class DateUtil { + // FIXME this should be changed to private and the class marked final once HSSFDateUtil can be removed protected DateUtil() { // no instances of this class } @@ -75,6 +77,88 @@ public class DateUtil { .toFormatter(); /** + * Convert a Java Date (at UTC) to LocalDateTime. + * @param date the date + * @return LocalDateTime instance + */ + public static LocalDateTime toLocalDateTime(Date date) { + return date.toInstant() + .atZone(TimeZone.getTimeZone("UTC").toZoneId()) // java.util.Date uses UTC + .toLocalDateTime(); + } + + /** + * Convert a Java Calendar (at UTC) to LocalDateTime. + * @param date the date + * @return LocalDateTime instance + */ + public static LocalDateTime toLocalDateTime(Calendar date) { + return date.toInstant() + .atZone(TimeZone.getTimeZone("UTC").toZoneId()) // java.util.Date uses UTC + .toLocalDateTime(); + } + + /** + * Given a LocalDate, converts it into a double representing its internal Excel representation, + * which is the number of days since 1/1/1900. Fractional days represent hours, minutes, and seconds. + * + * @return Excel representation of Date (-1 if error - test for error by checking for less than 0.1) + * @param date the Date + */ + public static double getExcelDate(LocalDate date) { + return getExcelDate(date, false); + } + + /** + * Given a LocalDate, converts it into a double representing its internal Excel representation, + * which is the number of days since 1/1/1900. Fractional days represent hours, minutes, and seconds. + * + * @return Excel representation of Date (-1 if error - test for error by checking for less than 0.1) + * @param date the Date + * @param use1904windowing Should 1900 or 1904 date windowing be used? + */ + public static double getExcelDate(LocalDate date, boolean use1904windowing) { + int year = date.getYear(); + int dayOfYear = date.getDayOfYear(); + int hour = 0; + int minute = 0; + int second = 0; + int milliSecond = 0; + + return internalGetExcelDate(year, dayOfYear, hour, minute, second, milliSecond, use1904windowing); + } + + /** + * Given a LocalDateTime, converts it into a double representing its internal Excel representation, + * which is the number of days since 1/1/1900. Fractional days represent hours, minutes, and seconds. + * + * @return Excel representation of Date (-1 if error - test for error by checking for less than 0.1) + * @param date the Date + */ + public static double getExcelDate(LocalDateTime date) { + return getExcelDate(date, false); + } + + /** + * Given a LocalDateTime, converts it into a double representing its internal Excel representation, + * which is the number of days since 1/1/1900. Fractional days represent hours, minutes, and seconds. + * + * @return Excel representation of Date (-1 if error - test for error by checking for less than 0.1) + * @param date the Date + * @param use1904windowing Should 1900 or 1904 date windowing be used? + */ + public static double getExcelDate(LocalDateTime date, boolean use1904windowing) { + int year = date.getYear(); + int dayOfYear = date.getDayOfYear(); + int hour = date.getHour(); + int minute = date.getMinute(); + int second = date.getSecond(); + int milliSecond = date.getNano()/1_000_000; + + return internalGetExcelDate(year, dayOfYear, hour, minute, second, milliSecond, use1904windowing); + } + + /** * Given a Date, converts it into a double representing its internal Excel representation, * which is the number of days since 1/1/1900. Fractional days represent hours, minutes, and seconds. * @@ -84,6 +168,7 @@ public class DateUtil { public static double getExcelDate(Date date) { return getExcelDate(date, false); } + /** * Given a Date, converts it into a double representing its internal Excel representation, * which is the number of days since 1/1/1900. Fractional days represent hours, minutes, and seconds. @@ -94,9 +179,17 @@ public class DateUtil { */ public static double getExcelDate(Date date, boolean use1904windowing) { Calendar calStart = LocaleUtil.getLocaleCalendar(); - calStart.setTime(date); // If date includes hours, minutes, and seconds, set them to 0 - return internalGetExcelDate(calStart, use1904windowing); + calStart.setTime(date); + int year = calStart.get(Calendar.YEAR); + int dayOfYear = calStart.get(Calendar.DAY_OF_YEAR); + int hour = calStart.get(Calendar.HOUR_OF_DAY); + int minute = calStart.get(Calendar.MINUTE); + int second = calStart.get(Calendar.SECOND); + int milliSecond = calStart.get(Calendar.MILLISECOND); + + return internalGetExcelDate(year, dayOfYear, hour, minute, second, milliSecond, use1904windowing); } + /** * Given a Date in the form of a Calendar, converts it into a double * representing its internal Excel representation, which is the @@ -108,15 +201,23 @@ public class DateUtil { * @param use1904windowing Should 1900 or 1904 date windowing be used? */ public static double getExcelDate(Calendar date, boolean use1904windowing) { - // Don't alter the supplied Calendar as we do our work - return internalGetExcelDate( (Calendar)date.clone(), use1904windowing ); - } - private static double internalGetExcelDate(Calendar date, boolean use1904windowing) { - if ((!use1904windowing && date.get(Calendar.YEAR) < 1900) || - (use1904windowing && date.get(Calendar.YEAR) < 1904)) + int year = date.get(Calendar.YEAR); + int dayOfYear = date.get(Calendar.DAY_OF_YEAR); + int hour = date.get(Calendar.HOUR_OF_DAY); + int minute = date.get(Calendar.MINUTE); + int second = date.get(Calendar.SECOND); + int milliSecond = date.get(Calendar.MILLISECOND); + + return internalGetExcelDate(year, dayOfYear, hour, minute, second, milliSecond, use1904windowing); + } + + private static double internalGetExcelDate(int year, int dayOfYear, int hour, int minute, int second, int milliSecond, boolean use1904windowing) { + if ((!use1904windowing && year < 1900) || + (use1904windowing && year < 1904)) { return BAD_DATE; } + // Because of daylight time saving we cannot use // date.getTime() - calStart.getTimeInMillis() // as the difference in milliseconds between 00:00 and 04:00 @@ -124,14 +225,13 @@ public class DateUtil { // be 4 hours. // E.g. 2004-03-28 04:00 CEST - 2004-03-28 00:00 CET is 3 hours // and 2004-10-31 04:00 CET - 2004-10-31 00:00 CEST is 5 hours - double fraction = (((date.get(Calendar.HOUR_OF_DAY) * 60.0 - + date.get(Calendar.MINUTE) - ) * 60.0 + date.get(Calendar.SECOND) - ) * 1000.0 + date.get(Calendar.MILLISECOND) + double fraction = (((hour * 60.0 + + minute + ) * 60.0 + second + ) * 1000.0 + milliSecond ) / DAY_MILLISECONDS; - Calendar calStart = dayStart(date); - double value = fraction + absoluteDay(calStart, use1904windowing); + double value = fraction + absoluteDay(year, dayOfYear, use1904windowing); if (!use1904windowing && value >= 60) { value++; @@ -241,6 +341,86 @@ public class DateUtil { public static Date getJavaDate(double date, boolean use1904windowing) { return getJavaDate(date, use1904windowing, null, false); } + + /** + * Given an Excel date with using 1900 date windowing, and + * converts it to a java.time.LocalDateTime. + * + * NOTE: If the default <code>TimeZone</code> in Java uses Daylight + * Saving Time then the conversion back to an Excel date may not give + * the same value, that is the comparison + * <CODE>excelDate == getExcelDate(getLocalDateTime(excelDate,false))</CODE> + * is not always true. For example if default timezone is + * <code>Europe/Copenhagen</code>, on 2004-03-28 the minute after + * 01:59 CET is 03:00 CEST, if the excel date represents a time between + * 02:00 and 03:00 then it is converted to past 03:00 summer time + * + * @param date The Excel date. + * @return Java representation of the date, or null if date is not a valid Excel date + * @see java.util.TimeZone + */ + public static LocalDateTime getLocalDateTime(double date) { + return getLocalDateTime(date, false, false); + } + + /** + * Given an Excel date with either 1900 or 1904 date windowing, + * converts it to a java.time.LocalDateTime. + * + * Excel Dates and Times are stored without any timezone + * information. If you know (through other means) that your file + * uses a different TimeZone to the system default, you can use + * this version of the getJavaDate() method to handle it. + * + * @param date The Excel date. + * @param use1904windowing true if date uses 1904 windowing, + * or false if using 1900 date windowing. + * @return Java representation of the date, or null if date is not a valid Excel date + */ + public static LocalDateTime getLocalDateTime(double date, boolean use1904windowing) { + return getLocalDateTime(date, use1904windowing, false); + } + + /** + * Given an Excel date with either 1900 or 1904 date windowing, + * converts it to a java.time.LocalDateTime. + * + * Excel Dates and Times are stored without any timezone + * information. If you know (through other means) that your file + * uses a different TimeZone to the system default, you can use + * this version of the getJavaDate() method to handle it. + * + * @param date The Excel date. + * @param use1904windowing true if date uses 1904 windowing, + * or false if using 1900 date windowing. + * @param roundSeconds round to closest second + * @return Java representation of the date, or null if date is not a valid Excel date + */ + public static LocalDateTime getLocalDateTime(double date, boolean use1904windowing, boolean roundSeconds) { + if (!isValidExcelDate(date)) { + return null; + } + int wholeDays = (int)Math.floor(date); + int millisecondsInDay = (int)((date - wholeDays) * DAY_MILLISECONDS + 0.5); + + int startYear = 1900; + int dayAdjust = -1; // Excel thinks 2/29/1900 is a valid date, which it isn't + if (use1904windowing) { + startYear = 1904; + dayAdjust = 1; // 1904 date windowing uses 1/2/1904 as the first day + } + else if (wholeDays < 61) { + // Date is prior to 3/1/1900, so adjust because Excel thinks 2/29/1900 exists + // If Excel date == 2/29/1900, will become 3/1/1900 in Java representation + dayAdjust = 0; + } + + LocalDateTime ldt = LocalDateTime.of(startYear, 1, 1, 0, 0); + ldt = ldt.plusDays(wholeDays+dayAdjust-1); + ldt = ldt.plusNanos(millisecondsInDay*1_000_000L); + + return ldt; + } public static void setCalendar(Calendar calendar, int wholeDays, int millisecondsInDay, boolean use1904windowing, boolean roundSeconds) { @@ -616,11 +796,34 @@ public class DateUtil { */ protected static int absoluteDay(Calendar cal, boolean use1904windowing) { - return cal.get(Calendar.DAY_OF_YEAR) - + daysInPriorYears(cal.get(Calendar.YEAR), use1904windowing); + return absoluteDay(cal.get(Calendar.YEAR), cal.get(Calendar.DAY_OF_YEAR), use1904windowing); + } + + /** + * Given a LocalDateTime, return the number of days since 1900/12/31. + * + * @return days number of days since 1900/12/31 + * @param date the Date + * @exception IllegalArgumentException if date is invalid + */ + protected static int absoluteDay(LocalDateTime date, boolean use1904windowing) + { + return absoluteDay(date.getYear(), date.getDayOfYear(), use1904windowing); } /** + * Given a year and day of year, return the number of days since 1900/12/31. + * + * @return days number of days since 1900/12/31 + * @param dayOfYear the day of the year + * @param year the year + * @exception IllegalArgumentException if date is invalid + */ + private static int absoluteDay(int year, int dayOfYear, boolean use1904windowing) { + return dayOfYear + daysInPriorYears(year, use1904windowing); + } + + /** * Return the number of days in prior years since 1900 * * @return days number of days in years prior to yr. @@ -629,7 +832,7 @@ public class DateUtil { * @exception IllegalArgumentException if year is outside of range. */ - private static int daysInPriorYears(int yr, boolean use1904windowing) + static int daysInPriorYears(int yr, boolean use1904windowing) { if ((!use1904windowing && yr < 1900) || (use1904windowing && yr < 1904)) { throw new IllegalArgumentException("'year' must be 1900 or greater"); |