Merge pull request 'fix/bug-75318-2' (#1614) from fix/bug-75318-2 into hotfix/v9.2.0

Reviewed-on: https://git.onlyoffice.com/ONLYOFFICE/sdkjs/pulls/1614
This commit is contained in:
Sergey Konovalov
2025-10-27 20:49:14 +00:00
3 changed files with 160 additions and 10 deletions

View File

@ -1306,16 +1306,23 @@ NumFormat.prototype =
{
//Разрешаем конфликты numFormat_MonthMinute
var bRightCond = false;
//ищем вперед первый элемент с типом datetime
for(var j = i + 1; j < nFormatLength; ++j)
if (item.bElapsed)
{
var subItem = this.aRawFormat[j];
if(numFormat_Year == subItem.type || numFormat_Month == subItem.type || numFormat_Day == subItem.type || numFormat_MonthMinute == subItem.type ||
numFormat_Hour == subItem.type || numFormat_Minute == subItem.type || numFormat_Second == subItem.type || numFormat_Milliseconds == subItem.type)
bRightCond = true;
}
else
{
//ищем вперед первый элемент с типом datetime
for(var j = i + 1; j < nFormatLength; ++j)
{
if(numFormat_Second == subItem.type)
bRightCond = true;
break;
var subItem = this.aRawFormat[j];
if(numFormat_Year == subItem.type || numFormat_Month == subItem.type || numFormat_Day == subItem.type || numFormat_MonthMinute == subItem.type ||
numFormat_Hour == subItem.type || numFormat_Minute == subItem.type || numFormat_Second == subItem.type || numFormat_Milliseconds == subItem.type)
{
if(numFormat_Second == subItem.type)
bRightCond = true;
break;
}
}
}
var bLeftCond = false;
@ -2727,13 +2734,25 @@ NumFormat.prototype =
}
else if(numFormat_Minute == item.type)
{
if (item.bElapsed) {
res += "[";
}
for(var j = 0; j < item.val; ++j)
res += minute;
if (item.bElapsed) {
res += "]";
}
}
else if(numFormat_Second == item.type)
{
if (item.bElapsed) {
res += "[";
}
for(var j = 0; j < item.val; ++j)
res += second;
if (item.bElapsed) {
res += "]";
}
}
else if(numFormat_DayOfWeek == item.type)
{

View File

@ -10,8 +10,12 @@
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/qunit/2.16.0/qunit.min.js"></script>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/xregexp/3.2.0/xregexp-all.min.js"></script>
<script type="text/javascript" src="../../../common/commonDefines.js"></script>
<script type="text/javascript" src="../../../common/NumFormat.js"></script>
<script type="text/javascript" src="../../../develop/sdkjs/cell/scripts.js"></script>
<script type="text/javascript">
window.sdk_scripts.forEach(function(item){
document.write('<script type="text/javascript" src="' + item + '"><\/script>');
});
</script>
<script type="text/javascript" src="NumFormatParse.js"></script>
</head>
<body>

View File

@ -31,6 +31,12 @@
*/
$(function () {
window["AscCommonExcel"] = window["AscCommonExcel"] || {};
window["AscCommonExcel"].Font = function () {
};
window["AscCommonExcel"].RgbColor = function () {
};
QUnit.module('NumFomat parse');
let eps = 1e-15;
QUnit.test('parseDate', function (assert) {
@ -83,4 +89,125 @@ $(function () {
assert.strictEqual(Math.abs(date.value - data[i][2]) < eps, true, `Case value: ${data[i][0]}`);
}
});
QUnit.test('formatNumber', function (assert) {
let testCases = [
// Thousand separators
[1234, '#,##0', '1,234'],
[1234567, '#,##0', '1,234,567'],
[0, '#,##0', '0'],
[-1234, '#,##0', '-1,234'],
// Decimal places
[1234.56, '#,##0.00', '1,234.56'],
[1234.5, '#,##0.00', '1,234.50'],
[0.5, '0.00', '0.50'],
[1.234, '0.00', '1.23'],
// Percentages
[0.5, '0%', '50%'],
[0.125, '0.00%', '12.50%'],
[1, '0%', '100%'],
[0.999, '0%', '100%'],
// Currency with text literals
[1234.56, '"$"#,##0.00', '$1,234.56'],
[0, '"$"#,##0.00', '$0.00'],
[-50, '"$"#,##0.00', '-$50.00'],
[1000, '"USD "0.00', 'USD 1000.00'],
// Negative numbers in parentheses
[100, '0;(0)', '100'],
[-100, '0;(0)', '(100)'],
[0, '0;(0)', '0'],
[-50.5, '0.00;(0.00)', '(50.50)'],
// Optional digits with #
[123, '###', '123'],
[0, '###', ''],
[12.3, '##.#', '12.3'],
[12, '##.#', '12.'],
// Mandatory zeros
[5, '000', '005'],
[123, '000', '123'],
[5.5, '000.00', '005.50'],
[0, '00', '00'],
// Space alignment with ?
[1, '??', '01'],
[10, '??', '10'],
[1.5, '?.??', '1.50'],
[10.25, '?.??', '10.25'],
// Escaped characters
[100, '\\#0', '#100'],
[50, '0\\%', '50%'],
[10, '0\\-', '10-'],
[25, '\\+0', '+25'],
// Mixed format
[1234.5, '#,##0.00;[Red](#,##0.00)', '1,234.50'],
[-1234.5, '#,##0.00;[Red](#,##0.00)', '(1,234.50)'],
// Additional important cases
[0.75, '0.#', '0.8'],
[100.123, '0.0', '100.1'],
[1234, '"Total: "#,##0', 'Total: 1,234'],
[0.5555, '0.00%', '55.55%'],
[999999, '#,##0', '999,999'],
[-0.25, '0.00;(0.00)', '(0.25)'],
// Date format cases
[0.684027777777778, 'mm', '01'],
[0.684027777777778, '[mm]', '985'],
[0.684027777777778, '[h] "hours"', '16 hours'],
[0.684027777777778, '[h]:mm', '16:25'],
[0.684027777777778, '[h]:mm" ""minutes"', '16:25 minutes'],
[0.684027777777778, '[s]', '59100'],
[0.684027777777778, '[s]" ""seconds"', '59100 seconds'],
[0.684027777777778, '[ss].0', '59100.0'],
[0.684027777777778, '[mm]:ss', '985:00'],
[0.684027777777778, '[mm]:mm', '985:01'],
[0.684027777777778, '[hh]', '16'],
[0.684027777777778, '[h]:mm:ss.000', '16:25:00.000'],
[0.684027777777778, 'dd"d "hh"h "mm"m "ss"s"" "AM/PM', '00d 04h 25m 00s PM'],
[0.684027777777778, '[h]"h*"mm"m*"ss"s*"ss"ms"', '16h*25m*00s*00ms'],
[0.684027777777778, 'yyyy"Y-"mm"M-"dd"D "hh"H:"mm"M:"ss"."s"S"" "AM/PM', '1900Y-01M-00D 04H:25M:00.0S PM'],
[0.684027777777778, 'dd:mm:yyyy" "hh:mm:ss" "[hh]:[mm]" "AM/PM" ""minutes AM/PM"', '00:01:1900 04:25:00 04:985 PM minutes AM/PM'],
[37753.6844097222, 'mm', '05'],
[37753.6844097222, '[mm]', '54365305'],
[37753.6844097222, '[h] "hours"', '906088 hours'],
[37753.6844097222, '[h]:mm', '906088:25'],
[37753.6844097222, '[h]:mm" ""minutes"', '906088:25 minutes'],
[37753.6844097222, '[s]', '3261918333'],
[37753.6844097222, '[s]" ""seconds"', '3261918333 seconds'],
[37753.6844097222, '[ss].0', '3261918333.0'],
[37753.6844097222, '[mm]:ss', '54365305:33'],
[37753.6844097222, '[mm]:mm', '54365305:05'],
[37753.6844097222, '[hh]', '906088'],
[37753.6844097222, '[h]:mm:ss.000', '906088:25:33.000'],
[37753.6844097222, 'dd"d "hh"h "mm"m "ss"s"" "AM/PM', '12d 04h 25m 33s PM'],
[37753.6844097222, '[h]"h*"mm"m*"ss"s*"ss"ms"', '906088h*25m*33s*33ms'],
[37753.6844097222, 'yyyy"Y-"mm"M-"dd"D "hh"H:"mm"M:"ss"."s"S"" "AM/PM', '2003Y-05M-12D 04H:25M:33.33S PM'],
[37753.6844097222, 'dd:mm:yyyy" "hh:mm:ss" "[hh]:[mm]" "AM/PM" ""minutes AM/PM"', '12:05:2003 04:25:33 04:54365305 PM minutes AM/PM'],
];
for (let i = 0; i < testCases.length; i++) {
let value = testCases[i][0];
let format = testCases[i][1];
let expected = testCases[i][2];
let expr = new AscCommon.CellFormat(format);
let formatted = expr.format(value);
let text = '';
for (let j = 0, length = formatted.length; j < length; ++j) {
text += formatted[j].text;
}
assert.strictEqual(text, expected, `format("${format}", ${value})`);
}
});
});