Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.8/site-packages/pendulum/formatting/difference_formatter.py: 9%

85 statements  

« prev     ^ index     » next       coverage.py v7.2.7, created at 2023-06-07 06:35 +0000

1import typing 

2 

3import pendulum 

4 

5from pendulum.utils._compat import decode 

6 

7from ..locales.locale import Locale 

8 

9 

10class DifferenceFormatter(object): 

11 """ 

12 Handles formatting differences in text. 

13 """ 

14 

15 def __init__(self, locale="en"): 

16 self._locale = Locale.load(locale) 

17 

18 def format( 

19 self, diff, is_now=True, absolute=False, locale=None 

20 ): # type: (pendulum.Period, bool, bool, typing.Optional[str]) -> str 

21 """ 

22 Formats a difference. 

23 

24 :param diff: The difference to format 

25 :type diff: pendulum.period.Period 

26 

27 :param is_now: Whether the difference includes now 

28 :type is_now: bool 

29 

30 :param absolute: Whether it's an absolute difference or not 

31 :type absolute: bool 

32 

33 :param locale: The locale to use 

34 :type locale: str or None 

35 

36 :rtype: str 

37 """ 

38 if locale is None: 

39 locale = self._locale 

40 else: 

41 locale = Locale.load(locale) 

42 

43 count = diff.remaining_seconds 

44 

45 if diff.years > 0: 

46 unit = "year" 

47 count = diff.years 

48 

49 if diff.months > 6: 

50 count += 1 

51 elif diff.months == 11 and (diff.weeks * 7 + diff.remaining_days) > 15: 

52 unit = "year" 

53 count = 1 

54 elif diff.months > 0: 

55 unit = "month" 

56 count = diff.months 

57 

58 if (diff.weeks * 7 + diff.remaining_days) >= 27: 

59 count += 1 

60 elif diff.weeks > 0: 

61 unit = "week" 

62 count = diff.weeks 

63 

64 if diff.remaining_days > 3: 

65 count += 1 

66 elif diff.remaining_days > 0: 

67 unit = "day" 

68 count = diff.remaining_days 

69 

70 if diff.hours >= 22: 

71 count += 1 

72 elif diff.hours > 0: 

73 unit = "hour" 

74 count = diff.hours 

75 elif diff.minutes > 0: 

76 unit = "minute" 

77 count = diff.minutes 

78 elif 10 < diff.remaining_seconds <= 59: 

79 unit = "second" 

80 count = diff.remaining_seconds 

81 else: 

82 # We check if the "a few seconds" unit exists 

83 time = locale.get("custom.units.few_second") 

84 if time is not None: 

85 if absolute: 

86 return time 

87 

88 key = "custom" 

89 is_future = diff.invert 

90 if is_now: 

91 if is_future: 

92 key += ".from_now" 

93 else: 

94 key += ".ago" 

95 else: 

96 if is_future: 

97 key += ".after" 

98 else: 

99 key += ".before" 

100 

101 return locale.get(key).format(time) 

102 else: 

103 unit = "second" 

104 count = diff.remaining_seconds 

105 

106 if count == 0: 

107 count = 1 

108 

109 if absolute: 

110 key = "translations.units.{}".format(unit) 

111 else: 

112 is_future = diff.invert 

113 

114 if is_now: 

115 # Relative to now, so we can use 

116 # the CLDR data 

117 key = "translations.relative.{}".format(unit) 

118 

119 if is_future: 

120 key += ".future" 

121 else: 

122 key += ".past" 

123 else: 

124 # Absolute comparison 

125 # So we have to use the custom locale data 

126 

127 # Checking for special pluralization rules 

128 key = "custom.units_relative" 

129 if is_future: 

130 key += ".{}.future".format(unit) 

131 else: 

132 key += ".{}.past".format(unit) 

133 

134 trans = locale.get(key) 

135 if not trans: 

136 # No special rule 

137 time = locale.get( 

138 "translations.units.{}.{}".format(unit, locale.plural(count)) 

139 ).format(count) 

140 else: 

141 time = trans[locale.plural(count)].format(count) 

142 

143 key = "custom" 

144 if is_future: 

145 key += ".after" 

146 else: 

147 key += ".before" 

148 

149 return locale.get(key).format(decode(time)) 

150 

151 key += ".{}".format(locale.plural(count)) 

152 

153 return decode(locale.get(key).format(count))