Proyectos de Subversion Moodle

Rev

| Ultima modificación | Ver Log |

Rev Autor Línea Nro. Línea
1441 ariadna 1
<?php
2
 
3
namespace PhpOffice\PhpSpreadsheet\Style\NumberFormat;
4
 
5
use PhpOffice\PhpSpreadsheet\Calculation\MathTrig;
6
 
7
class FractionFormatter extends BaseFormatter
8
{
9
    /** @param null|bool|float|int|string $value  value to be formatted */
10
    public static function format(mixed $value, string $format): string
11
    {
12
        $format = self::stripQuotes($format);
13
        $value = (float) $value;
14
        $absValue = abs($value);
15
 
16
        $sign = ($value < 0.0) ? '-' : '';
17
 
18
        $integerPart = floor($absValue);
19
 
20
        $decimalPart = self::getDecimal((string) $absValue);
21
        if ($decimalPart === '0') {
22
            return "{$sign}{$integerPart}";
23
        }
24
        $decimalLength = strlen($decimalPart);
25
        $decimalDivisor = 10 ** $decimalLength;
26
 
27
        preg_match('/(#?.*\?)\/(\?+|\d+)/', $format, $matches);
28
        $formatIntegerPart = $matches[1] ?? '0';
29
 
30
        if (isset($matches[2]) && is_numeric($matches[2])) {
31
            $fractionDivisor = 100 / (int) $matches[2];
32
        } else {
33
            /** @var float $fractionDivisor */
34
            $fractionDivisor = MathTrig\Gcd::evaluate((int) $decimalPart, $decimalDivisor);
35
        }
36
 
37
        $adjustedDecimalPart = (int) round((int) $decimalPart / $fractionDivisor, 0);
38
        $adjustedDecimalDivisor = $decimalDivisor / $fractionDivisor;
39
 
40
        if ((str_contains($formatIntegerPart, '0'))) {
41
            return "{$sign}{$integerPart} {$adjustedDecimalPart}/{$adjustedDecimalDivisor}";
42
        } elseif ((str_contains($formatIntegerPart, '#'))) {
43
            if ($integerPart == 0) {
44
                return "{$sign}{$adjustedDecimalPart}/{$adjustedDecimalDivisor}";
45
            }
46
 
47
            return "{$sign}{$integerPart} {$adjustedDecimalPart}/{$adjustedDecimalDivisor}";
48
        } elseif ((str_starts_with($formatIntegerPart, '? ?'))) {
49
            if ($integerPart == 0) {
50
                $integerPart = '';
51
            }
52
 
53
            return "{$sign}{$integerPart} {$adjustedDecimalPart}/{$adjustedDecimalDivisor}";
54
        }
55
 
56
        $adjustedDecimalPart += $integerPart * $adjustedDecimalDivisor;
57
 
58
        return "{$sign}{$adjustedDecimalPart}/{$adjustedDecimalDivisor}";
59
    }
60
 
61
    private static function getDecimal(string $value): string
62
    {
63
        $decimalPart = '0';
64
        if (preg_match('/^\d*[.](\d*[1-9])0*$/', $value, $matches) === 1) {
65
            $decimalPart = $matches[1];
66
        }
67
 
68
        return $decimalPart;
69
    }
70
}