Skip to content

Commit 98387c0

Browse files
committed
Revert changes for the timeFromExcelTime function
- Made special date format result consistent with Excel - Update unit tests
1 parent f940cde commit 98387c0

File tree

5 files changed

+47
-43
lines changed

5 files changed

+47
-43
lines changed

date.go

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -145,12 +145,7 @@ func timeFromExcelTime(excelTime float64, date1904 bool) time.Time {
145145
if date1904 {
146146
date = julianDateToGregorianTime(MJD0, excelTime+OFFSET1904)
147147
} else {
148-
// Fix for off-by-one error in days 1-59
149-
offset := OFFSET1900
150-
if wholeDaysPart >= 1 && wholeDaysPart <= 59 {
151-
offset = OFFSET1900 + 1.0
152-
}
153-
date = julianDateToGregorianTime(MJD0, excelTime+offset)
148+
date = julianDateToGregorianTime(MJD0, excelTime+OFFSET1900)
154149
}
155150
return date
156151
}

date_test.go

Lines changed: 1 addition & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ var trueExpectedDateList = []dateTest{
3131
var excelTimeInputList = []dateTest{
3232
{0.0, time.Date(1899, 12, 30, 0, 0, 0, 0, time.UTC)},
3333
{60.0, time.Date(1900, 2, 28, 0, 0, 0, 0, time.UTC)},
34-
{61.0, time.Date(1900, 3, 1, 0, 0, 0, 0, time.UTC)},
34+
{61.0, time.Date(1900, 2, 29, 0, 0, 0, 0, time.UTC)},
3535
{41275.0, time.Date(2013, 1, 1, 0, 0, 0, 0, time.UTC)},
3636
{44450.3333333333, time.Date(2021, time.September, 11, 8, 0, 0, 0, time.UTC)},
3737
{401769.0, time.Date(3000, 1, 1, 0, 0, 0, 0, time.UTC)},
@@ -101,30 +101,6 @@ func TestTimeFromExcelTime_1904(t *testing.T) {
101101
assert.Equal(t, timeFromExcelTime(62, true), time.Date(1904, time.March, 3, 0, 0, 0, 0, time.UTC))
102102
}
103103

104-
func TestTimeFromExcelTime_Issue2192(t *testing.T) {
105-
// Test case for issue #2192: timeFromExcelTime(2.0, false) should return 1900-01-02
106-
// This test verifies that the off-by-one error in early Excel dates (1-59) is fixed
107-
testCases := []struct {
108-
excelTime float64
109-
expected time.Time
110-
description string
111-
}{
112-
{0.0, time.Date(1899, 12, 30, 0, 0, 0, 0, time.UTC), "Day 0 (Excel epoch)"},
113-
{1.0, time.Date(1900, 1, 1, 0, 0, 0, 0, time.UTC), "Day 1 (1900-01-01)"},
114-
{2.0, time.Date(1900, 1, 2, 0, 0, 0, 0, time.UTC), "Day 2 (1900-01-02) - Original issue"},
115-
{3.0, time.Date(1900, 1, 3, 0, 0, 0, 0, time.UTC), "Day 3 (1900-01-03)"},
116-
{58.0, time.Date(1900, 2, 27, 0, 0, 0, 0, time.UTC), "Day 58 (1900-02-27) - Day before the Excel leap year bug"},
117-
{59.0, time.Date(1900, 2, 28, 0, 0, 0, 0, time.UTC), "Day 59 (1900-02-28) - Last affected day"},
118-
{60.0, time.Date(1900, 2, 28, 0, 0, 0, 0, time.UTC), "Day 60 (1900-02-28)"},
119-
{61.0, time.Date(1900, 3, 1, 0, 0, 0, 0, time.UTC), "Day 61 (1900-03-01)"},
120-
}
121-
122-
for _, tc := range testCases {
123-
result := timeFromExcelTime(tc.excelTime, false)
124-
assert.Equal(t, tc.expected, result, "timeFromExcelTime(%.1f, false) failed: %s", tc.excelTime, tc.description)
125-
}
126-
}
127-
128104
func TestExcelDateToTime(t *testing.T) {
129105
// Check normal case
130106
for i, test := range excelTimeInputList {

excelize_test.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -780,8 +780,8 @@ func TestSetCellStyleNumberFormat(t *testing.T) {
780780
expected := [][]string{
781781
{"37947.75", "37948", "37947.75", "37,948", "37,947.75", "3794775%", "3794775.00%", "3.79E+04", "37947 3/4", "37947 3/4", "11-22-03", "22-Nov-03", "22-Nov", "Nov-03", "6:00 PM", "6:00:00 PM", "18:00", "18:00:00", "11/22/03 18:00", "37,948 ", "37,948 ", "37,947.75 ", "37,947.75 ", " 37,948 ", " $37,948 ", " 37,947.75 ", " $37,947.75 ", "00:00", "910746:00:00", "00:00.0", "37947.7500001", "37947.7500001"},
782782
{"-37947.75", "-37948", "-37947.75", "-37,948", "-37,947.75", "-3794775%", "-3794775.00%", "-3.79E+04", "-37947 3/4", "-37947 3/4", "-37947.7500001", "-37947.7500001", "-37947.7500001", "-37947.7500001", "-37947.7500001", "-37947.7500001", "-37947.7500001", "-37947.7500001", "-37947.7500001", "(37,948)", "(37,948)", "(37,947.75)", "(37,947.75)", " (37,948)", " $(37,948)", " (37,947.75)", " $(37,947.75)", "-37947.7500001", "-37947.7500001", "-37947.7500001", "-37947.7500001", "-37947.7500001"},
783-
{"0.007", "0", "0.01", "0", "0.01", "1%", "0.70%", "7.00E-03", "0 ", "0 ", "12-30-99", "30-Dec-99", "30-Dec", "Dec-99", "12:10 AM", "12:10:05 AM", "00:10", "00:10:05", "12/30/99 00:10", "0 ", "0 ", "0.01 ", "0.01 ", " 0 ", " $0 ", " 0.01 ", " $0.01 ", "10:05", "0:10:05", "10:04.8", "0.007", "0.007"},
784-
{"2.1", "2", "2.10", "2", "2.10", "210%", "210.00%", "2.10E+00", "2 1/9", "2 1/10", "01-01-00", "1-Jan-00", "1-Jan", "Jan-00", "2:24 AM", "2:24:00 AM", "02:24", "02:24:00", "1/1/00 02:24", "2 ", "2 ", "2.10 ", "2.10 ", " 2 ", " $2 ", " 2.10 ", " $2.10 ", "24:00", "50:24:00", "24:00.0", "2.1", "2.1"},
783+
{"0.007", "0", "0.01", "0", "0.01", "1%", "0.70%", "7.00E-03", "0 ", "0 ", "01-00-00", "0-Jan-00", "0-Jan", "Jan-00", "12:10 AM", "12:10:05 AM", "00:10", "00:10:05", "1/0/00 00:10", "0 ", "0 ", "0.01 ", "0.01 ", " 0 ", " $0 ", " 0.01 ", " $0.01 ", "10:05", "0:10:05", "10:04.8", "0.007", "0.007"},
784+
{"2.1", "2", "2.10", "2", "2.10", "210%", "210.00%", "2.10E+00", "2 1/9", "2 1/10", "01-02-00", "2-Jan-00", "2-Jan", "Jan-00", "2:24 AM", "2:24:00 AM", "02:24", "02:24:00", "1/2/00 02:24", "2 ", "2 ", "2.10 ", "2.10 ", " 2 ", " $2 ", " 2.10 ", " $2.10 ", "24:00", "50:24:00", "24:00.0", "2.1", "2.1"},
785785
{"String", "String", "String", "String", "String", "String", "String", "String", "String", "String", "String", "String", "String", "String", "String", "String", "String", "String", "String", "String", "String", "String", "String", " String ", " String ", " String ", " String ", "String", "String", "String", "String", "String"},
786786
}
787787

numfmt.go

Lines changed: 41 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -7425,10 +7425,17 @@ func localMonthsNameZulu(t time.Time, abbr int) string {
74257425

74267426
// localMonthsName return months name by supported language ID.
74277427
func (nf *numberFormat) localMonthsName(abbr int) string {
7428+
t := nf.t
7429+
if nf.number < 1 {
7430+
t = timeFromExcelTime(nf.number+2, nf.date1904)
7431+
}
7432+
if 1 <= nf.number && nf.number < 60 {
7433+
t = timeFromExcelTime(nf.number+1, nf.date1904)
7434+
}
74287435
if languageInfo, ok := getSupportedLanguageInfo(nf.localCode); ok {
7429-
return languageInfo.localMonth(nf.t, abbr)
7436+
return languageInfo.localMonth(t, abbr)
74307437
}
7431-
return localMonthsNameEnglish(nf.t, abbr)
7438+
return localMonthsNameEnglish(t, abbr)
74327439
}
74337440

74347441
// dateTimesHandler will be handling date and times types tokens for a number
@@ -7447,13 +7454,20 @@ func (nf *numberFormat) dateTimesHandler(i int, token nfp.Token) {
74477454
return
74487455
}
74497456
if strings.Contains(strings.ToUpper(token.TValue), "M") {
7457+
m := int(nf.t.Month())
7458+
if nf.number < 2 {
7459+
m = 1
7460+
}
7461+
if 60 <= nf.number && nf.number < 61 {
7462+
m = 2
7463+
}
74507464
l := len(token.TValue)
74517465
if l == 1 && nf.isMonthToken(i) {
7452-
nf.result += strconv.Itoa(int(nf.t.Month()))
7466+
nf.result += strconv.Itoa(int(m))
74537467
return
74547468
}
74557469
if l == 2 && nf.isMonthToken(i) {
7456-
nf.result += fmt.Sprintf("%02d", int(nf.t.Month()))
7470+
nf.result += fmt.Sprintf("%02d", int(m))
74577471
return
74587472
}
74597473
if l == 3 {
@@ -7528,8 +7542,12 @@ func (nf *numberFormat) japaneseYearHandler(token nfp.Token, langInfo languageIn
75287542

75297543
// republicOfChinaYearHandler handling the Republic of China calendar years.
75307544
func (nf *numberFormat) republicOfChinaYearHandler(token nfp.Token, langInfo languageInfo) {
7545+
year := nf.t.Year()
7546+
if nf.number < 2 {
7547+
year = 1900
7548+
}
75317549
if strings.Contains(strings.ToUpper(token.TValue), "G") {
7532-
year := nf.t.Year() - republicOfChinaYear.Year() + 1
7550+
year = year - republicOfChinaYear.Year() + 1
75337551
if year == 1 {
75347552
nf.useGannen = langInfo.useGannen
75357553
}
@@ -7543,7 +7561,7 @@ func (nf *numberFormat) republicOfChinaYearHandler(token nfp.Token, langInfo lan
75437561
nf.result += name
75447562
}
75457563
if strings.Contains(strings.ToUpper(token.TValue), "E") {
7546-
year := nf.t.Year() - republicOfChinaYear.Year() + 1
7564+
year = year - republicOfChinaYear.Year() + 1
75477565
if year < 0 {
75487566
year = republicOfChinaYear.Year() - nf.t.Year()
75497567
}
@@ -7561,8 +7579,11 @@ func (nf *numberFormat) republicOfChinaYearHandler(token nfp.Token, langInfo lan
75617579
// number format expression.
75627580
func (nf *numberFormat) yearsHandler(token nfp.Token) {
75637581
langInfo, _ := getSupportedLanguageInfo(nf.localCode)
7582+
year := nf.t.Year()
7583+
if nf.number < 2 {
7584+
year = 1900
7585+
}
75647586
if strings.Contains(strings.ToUpper(token.TValue), "Y") {
7565-
year := nf.t.Year()
75667587
if nf.opts != nil && nf.opts.CultureInfo == CultureNameKoKR {
75677588
year += 2333
75687589
}
@@ -7584,7 +7605,7 @@ func (nf *numberFormat) yearsHandler(token nfp.Token) {
75847605
return
75857606
}
75867607
if strings.Contains(strings.ToUpper(token.TValue), "E") {
7587-
nf.result += strconv.Itoa(nf.t.Year())
7608+
nf.result += strconv.Itoa(year)
75887609
return
75897610
}
75907611
}
@@ -7611,11 +7632,21 @@ func (nf *numberFormat) daysHandler(token nfp.Token) {
76117632
return
76127633
}
76137634
if strings.Contains(strings.ToUpper(token.TValue), "D") {
7635+
d := nf.t.Day()
7636+
if nf.number < 1 {
7637+
d = 0
7638+
}
7639+
if 1 <= nf.number && nf.number < 60 {
7640+
d = timeFromExcelTime(nf.number+1, nf.date1904).Day()
7641+
}
7642+
if 60 <= nf.number && nf.number < 61 {
7643+
d = 29
7644+
}
76147645
switch l {
76157646
case 1:
7616-
nf.result += strconv.Itoa(nf.t.Day())
7647+
nf.result += strconv.Itoa(d)
76177648
case 2:
7618-
nf.result += fmt.Sprintf("%02d", nf.t.Day())
7649+
nf.result += fmt.Sprintf("%02d", d)
76197650
case 3:
76207651
nf.result += weekdayNamesAbbr[nf.t.Weekday()]
76217652
default:

numfmt_test.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,8 @@ func TestNumFmt(t *testing.T) {
7878
{"0", "0%", "0%"},
7979
{"0", "0.0%", "0.0%"},
8080
{"0", "0.00%", "0.00%"},
81+
{"0", "[$-zh-TW]yyyy\"\"m\"\"d\"\";@", "1900年1月0日"},
82+
{"60", "yyyy-mm-dd;@", "1900-02-29"},
8183
{"43528", "[$-409]MM/DD/YYYY", "03/04/2019"},
8284
{"43528", "[$-409]MM/DD/YYYY am/pm", "03/04/2019 AM"},
8385
{"43528", "[$-111]MM/DD/YYYY", "43528"},

0 commit comments

Comments
 (0)