File size: 3,209 Bytes
b4f2238
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
"""Utility functions."""

from __future__ import annotations

import logging
from datetime import date
from decimal import Decimal
from typing import Any

logger = logging.getLogger(__name__)

# 默认日期格式
DEFAULT_DATE_FORMAT = "%Y年%m月%d日"


def format_date(d: date | str | None, fmt: str = DEFAULT_DATE_FORMAT) -> str:
    """
    格式化日期

    Args:
        d: 日期对象或 ISO 格式日期字符串(如 "2024-01-15")
        fmt: 日期格式字符串,默认为 "%Y年%m月%d日"

    Returns:
        格式化的日期字符串,如果日期为 None 则返回空字符串
    """
    if d is None:
        return ""
    try:
        if isinstance(d, str):
            from datetime import datetime

            d = datetime.strptime(d, "%Y-%m-%d").date()
        return d.strftime(fmt)
    except Exception as e:
        logger.warning("格式化日期失败: %s", e)
        return ""


def format_date_chinese(d: date | None, default_today: bool = False) -> str:
    """
    格式化日期为中文格式(月和日补零)

    Args:
        d: 日期对象
        default_today: 如果日期为 None,是否使用今天的日期

    Returns:
        格式化的日期字符串,如 "2024年01月15日"
    """
    if d is None:
        if default_today:
            d = date.today()
        else:
            return ""

    try:
        return f"{d.year}年{d.month:02d}月{d.day:02d}日"
    except Exception as e:
        logger.warning("格式化日期失败: %s", e)
        return "____年____月____日"


def format_currency(amount: Decimal | None, include_symbol: bool = False) -> str:
    """
    格式化货币金额

    Args:
        amount: 金额
        include_symbol: 是否包含货币符号

    Returns:
        格式化的金额字符串,如 "1,234.56" 或 "¥1,234.56"
    """
    if amount is None:
        return ""

    try:
        formatted = f"{amount:,.2f}"
        if include_symbol:
            return f"¥{formatted}"
        return formatted
    except Exception as e:
        logger.warning("格式化货币失败: %s", e)
        return ""


def format_percentage(rate: Decimal | None, decimal_places: int = 2) -> str:
    """
    格式化百分比

    Args:
        rate: 百分比数值(如 10 表示 10%)
        decimal_places: 小数位数

    Returns:
        格式化的百分比字符串,如 "10.00%"
    """
    if rate is None:
        return ""

    try:
        if decimal_places > 0:
            return f"{rate:.{decimal_places}f}%"
        return f"{rate}%"
    except Exception as e:
        logger.warning("格式化百分比失败: %s", e)
        return ""


def get_choice_display(value: str, choices_class: type[Any]) -> str:
    """
    获取选项的显示文本

    Args:
        value: 选项值
        choices_class: Django TextChoices 类

    Returns:
        选项的显示文本,如果找不到则返回原值
    """
    if not value:
        return ""

    try:
        result = dict(choices_class.choices).get(value, value)
        return str(result) if result is not None else value
    except Exception as e:
        logger.warning("获取选项显示文本失败: %s", e)
        return value