Skip to content

Commit

Permalink
修复FastDatePrinter处理YY错误问题
Browse files Browse the repository at this point in the history
  • Loading branch information
looly committed Jul 1, 2024
1 parent f4d67ed commit 3aa08fe
Show file tree
Hide file tree
Showing 3 changed files with 99 additions and 27 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
* 【core 】 修复Tailer指定初始读取行数的计算错误问题(issue#IA77ML@Gitee)
* 【http 】 修复getFileNameFromDisposition获取头错误问题(issue#3632@Github)
* 【core 】 修复\n#出现在双引号中解析错误问题(issue#IA8WE0@Gitee)
* 【core 】 修复FastDatePrinter处理YY错误问题(issue#3641@Github)

-------------------------------------------------------------------------------------------------------------
# 5.8.28(2024-05-29)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,19 +23,24 @@
public class FastDatePrinter extends AbstractDateBasic implements DatePrinter {
private static final long serialVersionUID = -6305750172255764887L;

/** 规则列表. */
/**
* 规则列表.
*/
private transient Rule[] rules;
/** 估算最大长度. */
/**
* 估算最大长度.
*/
private transient int mMaxLengthEstimate;

// Constructor
// -----------------------------------------------------------------------

/**
* 构造,内部使用<br>
*
* @param pattern 使用{@link java.text.SimpleDateFormat} 相同的日期格式
* @param pattern 使用{@link java.text.SimpleDateFormat} 相同的日期格式
* @param timeZone 非空时区{@link TimeZone}
* @param locale 非空{@link Locale} 日期地理位置
* @param locale 非空{@link Locale} 日期地理位置
*/
public FastDatePrinter(String pattern, TimeZone timeZone, Locale locale) {
super(pattern, timeZone, locale);
Expand All @@ -50,7 +55,7 @@ private void init() {
rules = rulesList.toArray(new Rule[0]);

int len = 0;
for (int i = rules.length; --i >= 0;) {
for (int i = rules.length; --i >= 0; ) {
len += rules[i].estimateLength();
}

Expand All @@ -59,6 +64,7 @@ private void init() {

// Parse the pattern
// -----------------------------------------------------------------------

/**
* <p>
* Returns a list of Rules given a pattern.
Expand Down Expand Up @@ -207,7 +213,7 @@ protected List<Rule> parsePattern() {
* Performs the parsing of tokens.
* </p>
*
* @param pattern the pattern
* @param pattern the pattern
* @param indexRef index references
* @return parsed token
*/
Expand Down Expand Up @@ -267,7 +273,7 @@ protected String parseToken(String pattern, int[] indexRef) {
* Gets an appropriate rule for the padding required.
* </p>
*
* @param field the field to get a rule for
* @param field the field to get a rule for
* @param padding the padding required
* @return a new rule with the correct padding
*/
Expand Down Expand Up @@ -364,8 +370,8 @@ private String applyRulesToString(Calendar c) {
* </p>
*
* @param calendar the calendar to format
* @param buf the buffer to format into
* @param <B> the Appendable class type, usually StringBuilder or StringBuffer.
* @param buf the buffer to format into
* @param <B> the Appendable class type, usually StringBuilder or StringBuffer.
* @return the specified string buffer
*/
private <B extends Appendable> B applyRules(Calendar calendar, B buf) {
Expand All @@ -380,7 +386,7 @@ private <B extends Appendable> B applyRules(Calendar calendar, B buf) {
}

/**
*估算生成的日期字符串长度<br>
* 估算生成的日期字符串长度<br>
* 实际生成的字符串长度小于或等于此值
*
* @return 日期字符串长度
Expand All @@ -391,11 +397,12 @@ public int getMaxLengthEstimate() {

// Serializing
// -----------------------------------------------------------------------

/**
* Create the object after serialization. This implementation reinitializes the transient properties.
*
* @param in ObjectInputStream from which the object is being deserialized.
* @throws IOException if there is an IO issue.
* @throws IOException if there is an IO issue.
* @throws ClassNotFoundException if a class cannot be found.
*/
private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
Expand All @@ -407,7 +414,7 @@ private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundE
* Appends two digits to the given buffer.
*
* @param buffer the buffer to append to.
* @param value the value to append digits from.
* @param value the value to append digits from.
*/
private static void appendDigits(Appendable buffer, int value) throws IOException {
buffer.append((char) (value / 10 + '0'));
Expand All @@ -420,7 +427,7 @@ private static void appendDigits(Appendable buffer, int value) throws IOExceptio
* Appends all digits to the given buffer.
*
* @param buffer the buffer to append to.
* @param value the value to append digits from.
* @param value the value to append digits from.
*/
private static void appendFullDigits(Appendable buffer, int value, int minFieldWidth) throws IOException {
// specialized paths for 1 to 4 digits -> avoid the memory allocation from the temporary work array
Expand Down Expand Up @@ -490,6 +497,7 @@ private static void appendFullDigits(Appendable buffer, int value, int minFieldW

// Rules
// -----------------------------------------------------------------------

/**
* 规则
*/
Expand All @@ -504,7 +512,7 @@ private interface Rule {
/**
* Appends the value of the specified calendar to the output buffer based on the rule implementation.
*
* @param buf the output buffer
* @param buf the output buffer
* @param calendar calendar to be appended
* @throws IOException if an I/O error occurs
*/
Expand All @@ -521,7 +529,7 @@ private interface NumberRule extends Rule {
* Appends the specified value to the output buffer based on the rule implementation.
*
* @param buffer the output buffer
* @param value the value to be appended
* @param value the value to be appended
* @throws IOException if an I/O error occurs
*/
void appendTo(Appendable buffer, int value) throws IOException;
Expand Down Expand Up @@ -601,7 +609,7 @@ private static class TextField implements Rule {
/**
* Constructs an instance of {@code TextField} with the specified field and values.
*
* @param field the field
* @param field the field
* @param values the field values
*/
TextField(int field, String[] values) {
Expand All @@ -615,7 +623,7 @@ private static class TextField implements Rule {
@Override
public int estimateLength() {
int max = 0;
for (int i = mValues.length; --i >= 0;) {
for (int i = mValues.length; --i >= 0; ) {
final int len = mValues[i].length();
if (len > max) {
max = len;
Expand Down Expand Up @@ -691,7 +699,6 @@ private static class UnpaddedMonthField implements NumberRule {

/**
* Constructs an instance of {@code UnpaddedMonthField}.
*
*/
UnpaddedMonthField() {
}
Expand Down Expand Up @@ -738,7 +745,7 @@ private static class PaddedNumberField implements NumberRule {
* Constructs an instance of {@code PaddedNumberField}.
*
* @param field the field
* @param size size of the output field
* @param size size of the output field
*/
PaddedNumberField(int field, int size) {
if (size < 3) {
Expand Down Expand Up @@ -1038,7 +1045,12 @@ public int estimateLength() {

@Override
public void appendTo(Appendable buffer, Calendar calendar) throws IOException {
mRule.appendTo(buffer, calendar.getWeekYear());
int weekYear = calendar.getWeekYear();
if (mRule instanceof TwoDigitYearField) {
// issue#3641
weekYear %= 100;
}
mRule.appendTo(buffer, weekYear);
}

@Override
Expand All @@ -1056,10 +1068,10 @@ public void appendTo(Appendable buffer, int value) throws IOException {
* Gets the time zone display name, using a cache for performance.
* </p>
*
* @param tz the zone to query
* @param tz the zone to query
* @param daylight true if daylight savings
* @param style the style to use {@code TimeZone.LONG} or {@code TimeZone.SHORT}
* @param locale the locale to use
* @param style the style to use {@code TimeZone.LONG} or {@code TimeZone.SHORT}
* @param locale the locale to use
* @return the textual name of the time zone
*/
static String getTimeZoneDisplay(TimeZone tz, boolean daylight, int style, Locale locale) {
Expand Down Expand Up @@ -1091,8 +1103,8 @@ private static class TimeZoneNameRule implements Rule {
* Constructs an instance of {@code TimeZoneNameRule} with the specified properties.
*
* @param timeZone the time zone
* @param locale the locale
* @param style the style
* @param locale the locale
* @param style the style
*/
TimeZoneNameRule(TimeZone timeZone, Locale locale, int style) {
mLocale = locale;
Expand Down Expand Up @@ -1269,6 +1281,7 @@ public void appendTo(final Appendable buffer, final Calendar calendar) throws IO
}

// ----------------------------------------------------------------------

/**
* <p>
* Inner class that acts as a compound key for time zone names.
Expand All @@ -1284,8 +1297,8 @@ private static class TimeZoneDisplayKey {
*
* @param timeZone the time zone
* @param daylight adjust the style for daylight saving time if {@code true}
* @param style the timezone style
* @param locale the timezone locale
* @param style the timezone style
* @param locale the timezone locale
*/
TimeZoneDisplayKey(final TimeZone timeZone, final boolean daylight, final int style, final Locale locale) {
mTimeZone = timeZone;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
package cn.hutool.core.date;

import cn.hutool.core.date.format.FastDateFormat;
import org.junit.Test;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.TimeZone;

import static org.junit.Assert.assertEquals;

public class FastDateFormatTest {
private static final TimeZone timezone = TimeZone.getTimeZone("Etc/Utc");

private static FastDateFormat getHutoolInstance(String pattern) {
return FastDateFormat.getInstance(pattern, timezone);
}

@Test
public void yearTest() {
Date date = DateUtil.date(0L);

assertEquals(
"1970-01-01 00:00:00",
getHutoolInstance("yyyy-MM-dd HH:mm:ss").format(date)
);

assertEquals(
"1970-01-01 00:00:00",
getHutoolInstance("YYYY-MM-dd HH:mm:ss").format(date)
);

assertEquals(
"1970",
getHutoolInstance("YYYY").format(date)
);

assertEquals(
"70",
getHutoolInstance("yy").format(date)
);
}

@Test
public void weekYearTest() {
Date date = DateUtil.date(0L);

assertEquals(
"70",
new SimpleDateFormat("YY").format(date)
);

assertEquals(
"70",
getHutoolInstance("YY").format(date)
);
}
}

0 comments on commit 3aa08fe

Please sign in to comment.