|
|
@@ -0,0 +1,137 @@
|
|
|
+<?php
|
|
|
+
|
|
|
+namespace UCore\Helper;
|
|
|
+
|
|
|
+/**
|
|
|
+ * 数字助手类
|
|
|
+ *
|
|
|
+ * 提供数字格式化、转换等功能
|
|
|
+ */
|
|
|
+class Number
|
|
|
+{
|
|
|
+ /**
|
|
|
+ * 万分位数据表示转换
|
|
|
+ *
|
|
|
+ * 将数字转换为中文万分位表示法
|
|
|
+ * 例如:100020 -> "10万20"
|
|
|
+ *
|
|
|
+ * @param int|float|string $number 要转换的数字
|
|
|
+ * @return string 万分位表示的字符串
|
|
|
+ */
|
|
|
+ public static function formatToWan($number): string
|
|
|
+ {
|
|
|
+ // 转换为数字类型
|
|
|
+ $num = (float) $number;
|
|
|
+
|
|
|
+ // 处理负数
|
|
|
+ $isNegative = $num < 0;
|
|
|
+ $num = abs($num);
|
|
|
+
|
|
|
+ // 处理小数部分
|
|
|
+ $integerPart = (int) $num;
|
|
|
+ $decimalPart = $num - $integerPart;
|
|
|
+
|
|
|
+ $result = '';
|
|
|
+
|
|
|
+ // 处理整数部分的万分位转换
|
|
|
+ if ($integerPart >= 10000) {
|
|
|
+ $wan = (int) ($integerPart / 10000);
|
|
|
+ $remainder = $integerPart % 10000;
|
|
|
+
|
|
|
+ $result = $wan . '万';
|
|
|
+
|
|
|
+ // 如果余数不为0,添加余数
|
|
|
+ if ($remainder > 0) {
|
|
|
+ $result .= $remainder;
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ // 小于1万的直接显示
|
|
|
+ $result = (string) $integerPart;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 处理小数部分(如果有)
|
|
|
+ if ($decimalPart > 0) {
|
|
|
+ // 保留2位小数,去除末尾的0
|
|
|
+ $decimalStr = rtrim(sprintf('%.2f', $decimalPart), '0');
|
|
|
+ $decimalStr = rtrim($decimalStr, '.');
|
|
|
+ if ($decimalStr !== '0' && $decimalStr !== '') {
|
|
|
+ $result .= substr($decimalStr, 1); // 去掉开头的"0"
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // 添加负号
|
|
|
+ if ($isNegative) {
|
|
|
+ $result = '-' . $result;
|
|
|
+ }
|
|
|
+
|
|
|
+ return $result;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 格式化数字为千分位表示
|
|
|
+ *
|
|
|
+ * @param int|float|string $number 要格式化的数字
|
|
|
+ * @param int $decimals 小数位数,默认0
|
|
|
+ * @return string 千分位格式的字符串
|
|
|
+ */
|
|
|
+ public static function formatThousands($number, int $decimals = 0): string
|
|
|
+ {
|
|
|
+ return number_format((float) $number, $decimals);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 智能数字格式化
|
|
|
+ *
|
|
|
+ * 根据数字大小自动选择合适的格式化方式
|
|
|
+ *
|
|
|
+ * @param int|float|string $number 要格式化的数字
|
|
|
+ * @param bool $useWan 是否使用万分位表示,默认true
|
|
|
+ * @return string 格式化后的字符串
|
|
|
+ */
|
|
|
+ public static function smartFormat($number, bool $useWan = true): string
|
|
|
+ {
|
|
|
+ $num = (float) $number;
|
|
|
+
|
|
|
+ if ($useWan && abs($num) >= 10000) {
|
|
|
+ return self::formatToWan($number);
|
|
|
+ }
|
|
|
+
|
|
|
+ return self::formatThousands($number);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 将万分位表示转换回数字
|
|
|
+ *
|
|
|
+ * 例如:"10万20" -> 100020
|
|
|
+ *
|
|
|
+ * @param string $wanString 万分位表示的字符串
|
|
|
+ * @return int|float 转换后的数字
|
|
|
+ */
|
|
|
+ public static function parseFromWan(string $wanString)
|
|
|
+ {
|
|
|
+ // 处理负数
|
|
|
+ $isNegative = str_starts_with($wanString, '-');
|
|
|
+ if ($isNegative) {
|
|
|
+ $wanString = substr($wanString, 1);
|
|
|
+ }
|
|
|
+
|
|
|
+ // 查找"万"字符
|
|
|
+ $wanPos = mb_strpos($wanString, '万');
|
|
|
+
|
|
|
+ if ($wanPos === false) {
|
|
|
+ // 没有"万"字符,直接转换为数字
|
|
|
+ $result = (float) $wanString;
|
|
|
+ } else {
|
|
|
+ // 有"万"字符,分别处理万和余数部分
|
|
|
+ $wanPart = mb_substr($wanString, 0, $wanPos);
|
|
|
+ $remainderPart = mb_substr($wanString, $wanPos + 1);
|
|
|
+
|
|
|
+ $wan = (float) $wanPart;
|
|
|
+ $remainder = empty($remainderPart) ? 0 : (float) $remainderPart;
|
|
|
+
|
|
|
+ $result = $wan * 10000 + $remainder;
|
|
|
+ }
|
|
|
+
|
|
|
+ return $isNegative ? -$result : $result;
|
|
|
+ }
|
|
|
+}
|