twitter_cldr 1.9.1 → 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (403) hide show
  1. data/Gemfile +7 -0
  2. data/History.txt +11 -0
  3. data/README.md +93 -13
  4. data/Rakefile +27 -6
  5. data/lib/twitter_cldr/formatters.rb +15 -12
  6. data/lib/twitter_cldr/formatters/base.rb +1 -1
  7. data/lib/twitter_cldr/formatters/calendars/datetime_formatter.rb +18 -3
  8. data/lib/twitter_cldr/formatters/calendars/timespan_formatter.rb +24 -26
  9. data/lib/twitter_cldr/formatters/numbers/abbreviated/abbreviated_number_formatter.rb +47 -0
  10. data/lib/twitter_cldr/formatters/numbers/abbreviated/long_decimal_formatter.rb +18 -0
  11. data/lib/twitter_cldr/formatters/numbers/abbreviated/short_decimal_formatter.rb +18 -0
  12. data/lib/twitter_cldr/formatters/numbers/currency_formatter.rb +22 -17
  13. data/lib/twitter_cldr/formatters/numbers/decimal_formatter.rb +0 -9
  14. data/lib/twitter_cldr/formatters/numbers/helpers/base.rb +1 -1
  15. data/lib/twitter_cldr/formatters/numbers/number_formatter.rb +25 -10
  16. data/lib/twitter_cldr/formatters/numbers/percent_formatter.rb +9 -6
  17. data/lib/twitter_cldr/localized/localized_datetime.rb +6 -2
  18. data/lib/twitter_cldr/localized/localized_number.rb +9 -3
  19. data/lib/twitter_cldr/localized/localized_timespan.rb +1 -1
  20. data/lib/twitter_cldr/resources.rb +13 -12
  21. data/lib/twitter_cldr/resources/custom_locales_resources_importer.rb +1 -1
  22. data/lib/twitter_cldr/resources/download.rb +1 -1
  23. data/lib/twitter_cldr/resources/locales_resources_importer.rb +10 -6
  24. data/lib/twitter_cldr/shared/bidi.rb +27 -27
  25. data/lib/twitter_cldr/shared/currencies.rb +20 -13
  26. data/lib/twitter_cldr/tokenizers.rb +10 -9
  27. data/lib/twitter_cldr/tokenizers/base.rb +33 -21
  28. data/lib/twitter_cldr/tokenizers/calendars/additional_date_format_selector.rb +86 -0
  29. data/lib/twitter_cldr/tokenizers/calendars/date_tokenizer.rb +20 -11
  30. data/lib/twitter_cldr/tokenizers/calendars/datetime_tokenizer.rb +50 -13
  31. data/lib/twitter_cldr/tokenizers/calendars/time_tokenizer.rb +19 -10
  32. data/lib/twitter_cldr/tokenizers/calendars/timespan_tokenizer.rb +32 -32
  33. data/lib/twitter_cldr/tokenizers/numbers/number_tokenizer.rb +45 -22
  34. data/lib/twitter_cldr/utils.rb +16 -1
  35. data/lib/twitter_cldr/version.rb +1 -1
  36. data/resources/collation/tailoring/af.yml +1 -0
  37. data/resources/collation/tailoring/ar.yml +3 -2
  38. data/resources/collation/tailoring/be.yml +7 -0
  39. data/resources/collation/tailoring/bg.yml +5 -0
  40. data/resources/collation/tailoring/bn.yml +9 -0
  41. data/resources/collation/tailoring/ca.yml +3 -2
  42. data/resources/collation/tailoring/cs.yml +3 -2
  43. data/resources/collation/tailoring/cy.yml +51 -0
  44. data/resources/collation/tailoring/da.yml +3 -2
  45. data/resources/collation/tailoring/de.yml +1 -0
  46. data/resources/collation/tailoring/el.yml +1 -0
  47. data/resources/collation/tailoring/en.yml +1 -0
  48. data/resources/collation/tailoring/es.yml +3 -2
  49. data/resources/collation/tailoring/eu.yml +1 -0
  50. data/resources/collation/tailoring/fa.yml +3 -2
  51. data/resources/collation/tailoring/fi.yml +3 -2
  52. data/resources/collation/tailoring/fil.yml +3 -2
  53. data/resources/collation/tailoring/fr.yml +1 -0
  54. data/resources/collation/tailoring/ga.yml +5 -0
  55. data/resources/collation/tailoring/gl.yml +5 -0
  56. data/resources/collation/tailoring/he.yml +1 -0
  57. data/resources/collation/tailoring/hi.yml +3 -2
  58. data/resources/collation/tailoring/hu.yml +3 -2
  59. data/resources/collation/tailoring/id.yml +1 -0
  60. data/resources/collation/tailoring/it.yml +1 -0
  61. data/resources/collation/tailoring/ja.yml +107 -54
  62. data/resources/collation/tailoring/ko.yml +3 -2
  63. data/resources/collation/tailoring/lv.yml +35 -0
  64. data/resources/collation/tailoring/ms.yml +1 -0
  65. data/resources/collation/tailoring/nb.yml +3 -2
  66. data/resources/collation/tailoring/nl.yml +1 -0
  67. data/resources/collation/tailoring/pl.yml +3 -2
  68. data/resources/collation/tailoring/pt.yml +1 -0
  69. data/resources/collation/tailoring/ro.yml +31 -0
  70. data/resources/collation/tailoring/ru.yml +1 -0
  71. data/resources/collation/tailoring/sk.yml +35 -0
  72. data/resources/collation/tailoring/sq.yml +65 -0
  73. data/resources/collation/tailoring/sr.yml +5 -0
  74. data/resources/collation/tailoring/sv.yml +3 -2
  75. data/resources/collation/tailoring/ta.yml +57 -0
  76. data/resources/collation/tailoring/th.yml +3 -2
  77. data/resources/collation/tailoring/tr.yml +3 -2
  78. data/resources/collation/tailoring/uk.yml +3 -2
  79. data/resources/collation/tailoring/ur.yml +3 -2
  80. data/resources/collation/tailoring/zh-Hant.yml +3 -2
  81. data/resources/collation/tailoring/zh.yml +3 -2
  82. data/resources/collation/tries/be.dump +0 -0
  83. data/resources/collation/tries/bg.dump +0 -0
  84. data/resources/collation/tries/bn.dump +0 -0
  85. data/resources/collation/tries/cy.dump +0 -0
  86. data/resources/collation/tries/ga.dump +0 -0
  87. data/resources/collation/tries/gl.dump +0 -0
  88. data/resources/collation/tries/lv.dump +0 -0
  89. data/resources/collation/tries/ro.dump +0 -0
  90. data/resources/collation/tries/sk.dump +0 -0
  91. data/resources/collation/tries/sq.dump +0 -0
  92. data/resources/collation/tries/sr.dump +0 -0
  93. data/resources/collation/tries/ta.dump +0 -0
  94. data/resources/custom/locales/ar/units.yml +6 -6
  95. data/resources/custom/locales/be/units.yml +27 -0
  96. data/resources/custom/locales/bg/units.yml +19 -0
  97. data/resources/custom/locales/bn/units.yml +7 -0
  98. data/resources/custom/locales/cs/units.yml +3 -3
  99. data/resources/custom/locales/cy/units.yml +35 -0
  100. data/resources/custom/locales/fil/units.yml +2 -2
  101. data/resources/custom/locales/ga/units.yml +24 -0
  102. data/resources/custom/locales/gl/units.yml +19 -0
  103. data/resources/custom/locales/hu/plurals.yml +3 -0
  104. data/resources/custom/locales/hu/units.yml +4 -0
  105. data/resources/custom/locales/lv/units.yml +23 -0
  106. data/resources/custom/locales/ms/units.yml +1 -1
  107. data/resources/custom/locales/ro/units.yml +23 -0
  108. data/resources/custom/locales/sk/units.yml +23 -0
  109. data/resources/custom/locales/sr/units.yml +27 -0
  110. data/resources/custom/locales/ta/units.yml +11 -0
  111. data/resources/custom/locales/th/calendars.yml +14 -0
  112. data/resources/locales/af/calendars.yml +56 -0
  113. data/resources/locales/af/currencies.yml +358 -0
  114. data/resources/locales/af/languages.yml +23 -3
  115. data/resources/locales/af/numbers.yml +22 -8
  116. data/resources/locales/af/units.yml +26 -54
  117. data/resources/locales/ar/calendars.yml +99 -6
  118. data/resources/locales/ar/currencies.yml +1491 -0
  119. data/resources/locales/ar/languages.yml +33 -6
  120. data/resources/locales/ar/numbers.yml +27 -14
  121. data/resources/locales/ar/units.yml +31 -31
  122. data/resources/locales/be/calendars.yml +229 -0
  123. data/resources/locales/be/currencies.yml +66 -0
  124. data/resources/locales/be/languages.yml +149 -0
  125. data/resources/locales/be/layout.yml +4 -0
  126. data/resources/locales/be/lists.yml +7 -0
  127. data/resources/locales/be/numbers.yml +43 -0
  128. data/resources/locales/be/plurals.yml +5 -0
  129. data/resources/locales/be/units.yml +87 -0
  130. data/resources/locales/bg/calendars.yml +220 -0
  131. data/resources/locales/bg/currencies.yml +773 -0
  132. data/resources/locales/bg/languages.yml +513 -0
  133. data/resources/locales/bg/layout.yml +4 -0
  134. data/resources/locales/bg/lists.yml +7 -0
  135. data/resources/locales/bg/numbers.yml +57 -0
  136. data/resources/locales/bg/plurals.yml +3 -0
  137. data/resources/locales/bg/units.yml +108 -0
  138. data/resources/locales/bn/calendars.yml +205 -0
  139. data/resources/locales/bn/currencies.yml +564 -0
  140. data/resources/locales/bn/languages.yml +513 -0
  141. data/resources/locales/bn/layout.yml +4 -0
  142. data/resources/locales/bn/lists.yml +7 -0
  143. data/resources/locales/bn/numbers.yml +57 -0
  144. data/resources/locales/bn/plurals.yml +3 -0
  145. data/resources/locales/bn/units.yml +108 -0
  146. data/resources/locales/ca/calendars.yml +70 -21
  147. data/resources/locales/ca/currencies.yml +904 -0
  148. data/resources/locales/ca/languages.yml +70 -5
  149. data/resources/locales/ca/numbers.yml +19 -6
  150. data/resources/locales/ca/units.yml +0 -28
  151. data/resources/locales/cs/calendars.yml +73 -27
  152. data/resources/locales/cs/currencies.yml +1063 -0
  153. data/resources/locales/cs/languages.yml +113 -31
  154. data/resources/locales/cs/numbers.yml +17 -4
  155. data/resources/locales/cs/units.yml +0 -28
  156. data/resources/locales/cy/calendars.yml +266 -0
  157. data/resources/locales/cy/currencies.yml +54 -0
  158. data/resources/locales/cy/languages.yml +92 -0
  159. data/resources/locales/cy/layout.yml +4 -0
  160. data/resources/locales/cy/lists.yml +7 -0
  161. data/resources/locales/cy/numbers.yml +49 -0
  162. data/resources/locales/cy/plurals.yml +4 -0
  163. data/resources/locales/cy/units.yml +73 -0
  164. data/resources/locales/da/calendars.yml +117 -16
  165. data/resources/locales/da/currencies.yml +814 -0
  166. data/resources/locales/da/languages.yml +66 -5
  167. data/resources/locales/da/numbers.yml +16 -3
  168. data/resources/locales/da/units.yml +21 -35
  169. data/resources/locales/de/calendars.yml +115 -17
  170. data/resources/locales/de/currencies.yml +843 -0
  171. data/resources/locales/de/languages.yml +5 -3
  172. data/resources/locales/de/numbers.yml +18 -5
  173. data/resources/locales/de/units.yml +0 -28
  174. data/resources/locales/el/calendars.yml +61 -8
  175. data/resources/locales/el/currencies.yml +866 -0
  176. data/resources/locales/el/languages.yml +61 -5
  177. data/resources/locales/el/numbers.yml +18 -5
  178. data/resources/locales/el/units.yml +7 -42
  179. data/resources/locales/en/calendars.yml +43 -4
  180. data/resources/locales/en/currencies.yml +912 -0
  181. data/resources/locales/en/languages.yml +26 -6
  182. data/resources/locales/en/numbers.yml +17 -4
  183. data/resources/locales/es/calendars.yml +60 -0
  184. data/resources/locales/es/currencies.yml +820 -0
  185. data/resources/locales/es/languages.yml +66 -1
  186. data/resources/locales/es/numbers.yml +20 -7
  187. data/resources/locales/es/units.yml +0 -28
  188. data/resources/locales/eu/calendars.yml +43 -2
  189. data/resources/locales/eu/currencies.yml +378 -0
  190. data/resources/locales/eu/languages.yml +29 -13
  191. data/resources/locales/eu/numbers.yml +17 -4
  192. data/resources/locales/eu/units.yml +22 -43
  193. data/resources/locales/fa/calendars.yml +57 -0
  194. data/resources/locales/fa/currencies.yml +449 -0
  195. data/resources/locales/fa/languages.yml +8 -3
  196. data/resources/locales/fa/numbers.yml +20 -7
  197. data/resources/locales/fa/units.yml +0 -42
  198. data/resources/locales/fi/calendars.yml +49 -1
  199. data/resources/locales/fi/currencies.yml +903 -0
  200. data/resources/locales/fi/languages.yml +58 -2
  201. data/resources/locales/fi/numbers.yml +25 -12
  202. data/resources/locales/fi/units.yml +0 -28
  203. data/resources/locales/fil/calendars.yml +51 -0
  204. data/resources/locales/fil/currencies.yml +357 -0
  205. data/resources/locales/fil/languages.yml +25 -8
  206. data/resources/locales/fil/numbers.yml +18 -5
  207. data/resources/locales/fil/units.yml +14 -28
  208. data/resources/locales/fr/calendars.yml +114 -12
  209. data/resources/locales/fr/currencies.yml +884 -0
  210. data/resources/locales/fr/languages.yml +43 -9
  211. data/resources/locales/fr/numbers.yml +22 -9
  212. data/resources/locales/fr/units.yml +2 -30
  213. data/resources/locales/ga/calendars.yml +187 -0
  214. data/resources/locales/ga/currencies.yml +513 -0
  215. data/resources/locales/ga/languages.yml +147 -0
  216. data/resources/locales/ga/layout.yml +4 -0
  217. data/resources/locales/ga/lists.yml +7 -0
  218. data/resources/locales/ga/numbers.yml +43 -0
  219. data/resources/locales/ga/plurals.yml +4 -0
  220. data/resources/locales/ga/units.yml +66 -0
  221. data/resources/locales/gl/calendars.yml +216 -0
  222. data/resources/locales/gl/currencies.yml +476 -0
  223. data/resources/locales/gl/languages.yml +213 -0
  224. data/resources/locales/gl/layout.yml +4 -0
  225. data/resources/locales/gl/lists.yml +7 -0
  226. data/resources/locales/gl/numbers.yml +57 -0
  227. data/resources/locales/gl/plurals.yml +3 -0
  228. data/resources/locales/gl/units.yml +108 -0
  229. data/resources/locales/he/calendars.yml +70 -18
  230. data/resources/locales/he/currencies.yml +497 -0
  231. data/resources/locales/he/languages.yml +301 -7
  232. data/resources/locales/he/lists.yml +2 -2
  233. data/resources/locales/he/numbers.yml +23 -8
  234. data/resources/locales/he/plurals.yml +3 -2
  235. data/resources/locales/he/units.yml +72 -30
  236. data/resources/locales/hi/calendars.yml +54 -1
  237. data/resources/locales/hi/currencies.yml +388 -0
  238. data/resources/locales/hi/languages.yml +2 -0
  239. data/resources/locales/hi/numbers.yml +21 -8
  240. data/resources/locales/hi/units.yml +15 -29
  241. data/resources/locales/hu/calendars.yml +52 -5
  242. data/resources/locales/hu/currencies.yml +640 -0
  243. data/resources/locales/hu/languages.yml +60 -4
  244. data/resources/locales/hu/numbers.yml +25 -12
  245. data/resources/locales/hu/units.yml +1 -29
  246. data/resources/locales/id/calendars.yml +125 -21
  247. data/resources/locales/id/currencies.yml +603 -0
  248. data/resources/locales/id/languages.yml +113 -51
  249. data/resources/locales/id/numbers.yml +16 -3
  250. data/resources/locales/id/units.yml +0 -28
  251. data/resources/locales/it/calendars.yml +59 -6
  252. data/resources/locales/it/currencies.yml +722 -0
  253. data/resources/locales/it/languages.yml +77 -5
  254. data/resources/locales/it/numbers.yml +22 -9
  255. data/resources/locales/it/units.yml +0 -14
  256. data/resources/locales/ja/calendars.yml +55 -5
  257. data/resources/locales/ja/currencies.yml +602 -0
  258. data/resources/locales/ja/languages.yml +103 -43
  259. data/resources/locales/ja/numbers.yml +18 -5
  260. data/resources/locales/ja/units.yml +6 -34
  261. data/resources/locales/ko/calendars.yml +50 -0
  262. data/resources/locales/ko/currencies.yml +596 -0
  263. data/resources/locales/ko/languages.yml +75 -8
  264. data/resources/locales/ko/numbers.yml +17 -4
  265. data/resources/locales/ko/units.yml +0 -28
  266. data/resources/locales/lv/calendars.yml +275 -0
  267. data/resources/locales/lv/currencies.yml +765 -0
  268. data/resources/locales/lv/languages.yml +576 -0
  269. data/resources/locales/lv/layout.yml +4 -0
  270. data/resources/locales/lv/lists.yml +7 -0
  271. data/resources/locales/lv/numbers.yml +58 -0
  272. data/resources/locales/lv/plurals.yml +4 -0
  273. data/resources/locales/lv/units.yml +136 -0
  274. data/resources/locales/ms/calendars.yml +86 -4
  275. data/resources/locales/ms/currencies.yml +341 -0
  276. data/resources/locales/ms/languages.yml +25 -3
  277. data/resources/locales/ms/numbers.yml +19 -6
  278. data/resources/locales/ms/units.yml +0 -56
  279. data/resources/locales/nb/calendars.yml +48 -1
  280. data/resources/locales/nb/currencies.yml +846 -0
  281. data/resources/locales/nb/languages.yml +44 -2
  282. data/resources/locales/nb/numbers.yml +16 -3
  283. data/resources/locales/nb/units.yml +6 -28
  284. data/resources/locales/nl/calendars.yml +110 -9
  285. data/resources/locales/nl/currencies.yml +640 -0
  286. data/resources/locales/nl/languages.yml +68 -8
  287. data/resources/locales/nl/numbers.yml +25 -12
  288. data/resources/locales/nl/units.yml +14 -28
  289. data/resources/locales/pl/calendars.yml +53 -6
  290. data/resources/locales/pl/currencies.yml +1100 -0
  291. data/resources/locales/pl/languages.yml +13 -6
  292. data/resources/locales/pl/lists.yml +2 -2
  293. data/resources/locales/pl/numbers.yml +18 -5
  294. data/resources/locales/pl/units.yml +51 -92
  295. data/resources/locales/pt/calendars.yml +121 -9
  296. data/resources/locales/pt/currencies.yml +904 -0
  297. data/resources/locales/pt/languages.yml +5 -3
  298. data/resources/locales/pt/numbers.yml +17 -4
  299. data/resources/locales/pt/units.yml +0 -28
  300. data/resources/locales/ro/calendars.yml +278 -0
  301. data/resources/locales/ro/currencies.yml +946 -0
  302. data/resources/locales/ro/languages.yml +576 -0
  303. data/resources/locales/ro/layout.yml +4 -0
  304. data/resources/locales/ro/lists.yml +7 -0
  305. data/resources/locales/ro/numbers.yml +58 -0
  306. data/resources/locales/ro/plurals.yml +3 -0
  307. data/resources/locales/ro/units.yml +136 -0
  308. data/resources/locales/ru/calendars.yml +72 -12
  309. data/resources/locales/ru/currencies.yml +1061 -0
  310. data/resources/locales/ru/languages.yml +51 -6
  311. data/resources/locales/ru/numbers.yml +21 -5
  312. data/resources/locales/ru/units.yml +0 -28
  313. data/resources/locales/sk/calendars.yml +275 -0
  314. data/resources/locales/sk/currencies.yml +713 -0
  315. data/resources/locales/sk/languages.yml +576 -0
  316. data/resources/locales/sk/layout.yml +4 -0
  317. data/resources/locales/sk/lists.yml +7 -0
  318. data/resources/locales/sk/numbers.yml +58 -0
  319. data/resources/locales/sk/plurals.yml +3 -0
  320. data/resources/locales/sk/units.yml +136 -0
  321. data/resources/locales/sq/calendars.yml +188 -0
  322. data/resources/locales/sq/currencies.yml +56 -0
  323. data/resources/locales/sq/languages.yml +17 -0
  324. data/resources/locales/sq/layout.yml +4 -0
  325. data/resources/locales/sq/lists.yml +7 -0
  326. data/resources/locales/sq/numbers.yml +43 -0
  327. data/resources/locales/sq/plurals.yml +3 -0
  328. data/resources/locales/sq/units.yml +73 -0
  329. data/resources/locales/sr/calendars.yml +285 -0
  330. data/resources/locales/sr/currencies.yml +1494 -0
  331. data/resources/locales/sr/languages.yml +513 -0
  332. data/resources/locales/sr/layout.yml +4 -0
  333. data/resources/locales/sr/lists.yml +7 -0
  334. data/resources/locales/sr/numbers.yml +59 -0
  335. data/resources/locales/sr/plurals.yml +5 -0
  336. data/resources/locales/sr/units.yml +164 -0
  337. data/resources/locales/sv/calendars.yml +59 -1
  338. data/resources/locales/sv/currencies.yml +919 -0
  339. data/resources/locales/sv/languages.yml +47 -2
  340. data/resources/locales/sv/numbers.yml +27 -12
  341. data/resources/locales/sv/units.yml +4 -32
  342. data/resources/locales/ta/calendars.yml +264 -0
  343. data/resources/locales/ta/currencies.yml +346 -0
  344. data/resources/locales/ta/languages.yml +512 -0
  345. data/resources/locales/ta/layout.yml +4 -0
  346. data/resources/locales/ta/lists.yml +7 -0
  347. data/resources/locales/ta/numbers.yml +57 -0
  348. data/resources/locales/ta/plurals.yml +3 -0
  349. data/resources/locales/ta/units.yml +108 -0
  350. data/resources/locales/th/calendars.yml +125 -27
  351. data/resources/locales/th/currencies.yml +602 -0
  352. data/resources/locales/th/languages.yml +70 -5
  353. data/resources/locales/th/numbers.yml +24 -11
  354. data/resources/locales/th/units.yml +0 -28
  355. data/resources/locales/tr/calendars.yml +62 -12
  356. data/resources/locales/tr/currencies.yml +571 -0
  357. data/resources/locales/tr/languages.yml +94 -29
  358. data/resources/locales/tr/numbers.yml +19 -6
  359. data/resources/locales/tr/units.yml +1 -29
  360. data/resources/locales/uk/calendars.yml +52 -0
  361. data/resources/locales/uk/currencies.yml +799 -0
  362. data/resources/locales/uk/languages.yml +57 -2
  363. data/resources/locales/uk/numbers.yml +18 -5
  364. data/resources/locales/uk/units.yml +0 -28
  365. data/resources/locales/ur/calendars.yml +96 -32
  366. data/resources/locales/ur/currencies.yml +360 -0
  367. data/resources/locales/ur/languages.yml +49 -32
  368. data/resources/locales/ur/numbers.yml +13 -13
  369. data/resources/locales/ur/units.yml +28 -56
  370. data/resources/locales/zh-Hant/calendars.yml +59 -1
  371. data/resources/locales/zh-Hant/currencies.yml +602 -0
  372. data/resources/locales/zh-Hant/languages.yml +74 -8
  373. data/resources/locales/zh-Hant/numbers.yml +17 -4
  374. data/resources/locales/zh-Hant/units.yml +0 -28
  375. data/resources/locales/zh/calendars.yml +95 -35
  376. data/resources/locales/zh/currencies.yml +602 -0
  377. data/resources/locales/zh/languages.yml +116 -46
  378. data/resources/locales/zh/numbers.yml +20 -7
  379. data/resources/locales/zh/units.yml +6 -34
  380. data/resources/shared/currency_digits_and_rounding.yml +187 -0
  381. data/spec/bidi/bidi_spec.rb +1 -1
  382. data/spec/collation/tailoring_spec.rb +29 -25
  383. data/spec/formatters/calendars/datetime_formatter_spec.rb +50 -2
  384. data/spec/formatters/calendars/timespan_formatter_spec.rb +52 -8
  385. data/spec/formatters/numbers/abbreviated/abbreviated_number_formatter_spec.rb +81 -0
  386. data/spec/formatters/numbers/abbreviated/long_decimal_formatter_spec.rb +37 -0
  387. data/spec/formatters/numbers/abbreviated/short_decimal_formatter_spec.rb +37 -0
  388. data/spec/formatters/numbers/currency_formatter_spec.rb +10 -1
  389. data/spec/localized/localized_date_spec.rb +11 -11
  390. data/spec/localized/localized_datetime_spec.rb +27 -3
  391. data/spec/localized/localized_number_spec.rb +34 -6
  392. data/spec/localized/localized_time_spec.rb +1 -1
  393. data/spec/readme_spec.rb +24 -3
  394. data/spec/shared/currencies_spec.rb +7 -9
  395. data/spec/spec_helper.rb +7 -0
  396. data/spec/tokenizers/base_spec.rb +71 -21
  397. data/spec/tokenizers/calendars/additional_date_format_selector_spec.rb +131 -0
  398. data/spec/tokenizers/calendars/datetime_tokenizer_spec.rb +54 -27
  399. data/spec/tokenizers/calendars/time_tokenizer_spec.rb +16 -16
  400. data/spec/tokenizers/numbers/number_tokenizer_spec.rb +9 -21
  401. data/spec/utils/yaml/yaml_spec.rb +21 -16
  402. data/spec/utils_spec.rb +6 -2
  403. metadata +218 -37
data/Gemfile CHANGED
@@ -4,6 +4,8 @@ gemspec
4
4
 
5
5
  group :development, :test do
6
6
  gem 'rake'
7
+ gem 'pry'
8
+ gem 'pry-nav'
7
9
  end
8
10
 
9
11
  group :development do
@@ -19,5 +21,10 @@ group :test do
19
21
  platform :mri_18 do
20
22
  gem 'rcov'
21
23
  end
24
+
25
+ platform :mri_19 do
26
+ gem 'simplecov'
27
+ gem 'launchy'
28
+ end
22
29
  end
23
30
 
data/History.txt CHANGED
@@ -1,3 +1,14 @@
1
+ == 2.0.0
2
+
3
+ * Added locales ga, ta, gl, cy, sr, bg, ku, ro, lv, be, sq, sk, and bn.
4
+ * Added additional date formats.
5
+ * Upgraded to CLDR 22.1.
6
+ * Imported currency symbols and formatting rules from CLDR.
7
+ * Added support for short/long numbers (eg. 1M for 1,000,000).
8
+ * Improved RCov/Simplecov support.
9
+ * Added custom Hungarian plurals rule.
10
+ * Added support for approximate timespans (relative times).
11
+
1
12
  === 1.9.1
2
13
 
3
14
  * Locale resources now exported without Unicode escape sequences.
data/README.md CHANGED
@@ -79,28 +79,40 @@ TwitterCldr::Shared::Currencies.for_country("Canada") # { :currency => "Dol
79
79
  TwitterCldr::Shared::Currencies.for_code("CAD") # { :currency => "Dollar", :symbol => "$", :country => "Canada"}
80
80
  ```
81
81
 
82
+ #### Short / Long Decimals
83
+
84
+ In addition to formatting regular decimals, TwitterCLDR supports short and long decimals. Short decimals abbreviate the notation for the appropriate power of ten, for example "1M" for 1,000,000 or "2K" for 2,000. Long decimals include the full notation, for example "1 million" or "2 thousand". Long and short decimals can be generated using the appropriate `to_` method:
85
+
86
+ ```ruby
87
+ 2337.localize.to_short_decimal.to_s # 2K
88
+ 1337123.localize.to_short_decimal.to_s # 1M
89
+
90
+ 2337.localize.to_long_decimal.to_s # 2 thousand
91
+ 1337123.localize.to_long_decimal.to_s # 1 million
92
+ ```
93
+
82
94
  ### Dates and Times
83
95
 
84
96
  `Date`, `Time`, and `DateTime` objects are supported:
85
97
 
86
98
  ```ruby
87
- DateTime.now.localize(:es).to_full_s # "lunes, 12 de diciembre de 2011 21:44:57 UTC -0800"
88
- DateTime.now.localize(:es).to_long_s # "12 de diciembre de 2011 21:44:57 -08:00"
89
- DateTime.now.localize(:es).to_medium_s # "12/12/2011 21:44:57"
90
- DateTime.now.localize(:es).to_short_s # "12/12/11 21:44"
99
+ DateTime.now.localize(:es).to_full_s # "lunes, 12 de diciembre de 2011 21:44:57 UTC -0800"
100
+ DateTime.now.localize(:es).to_long_s # "12 de diciembre de 2011 21:44:57 -08:00"
101
+ DateTime.now.localize(:es).to_medium_s # "12/12/2011 21:44:57"
102
+ DateTime.now.localize(:es).to_short_s # "12/12/11 21:44"
91
103
 
92
- Date.today.localize(:es).to_full_s # "lunes 12 de diciembre de 2011"
93
- Date.today.localize(:es).to_long_s # "12 de diciembre de 2011"
94
- Date.today.localize(:es).to_medium_s # "12/12/2011"
95
- Date.today.localize(:es).to_short_s # "12/12/11"
104
+ Date.today.localize(:es).to_full_s # "lunes 12 de diciembre de 2011"
105
+ Date.today.localize(:es).to_long_s # "12 de diciembre de 2011"
106
+ Date.today.localize(:es).to_medium_s # "12/12/2011"
107
+ Date.today.localize(:es).to_short_s # "12/12/11"
96
108
 
97
- Time.now.localize(:es).to_full_s # "21:44:57 UTC -0800"
98
- Time.now.localize(:es).to_long_s # "21:44:57 UTC"
99
- Time.now.localize(:es).to_medium_s # "21:44:57"
100
- Time.now.localize(:es).to_short_s # "21:44"
109
+ Time.now.localize(:es).to_full_s # "21:44:57 UTC -0800"
110
+ Time.now.localize(:es).to_long_s # "21:44:57 UTC"
111
+ Time.now.localize(:es).to_medium_s # "21:44:57"
112
+ Time.now.localize(:es).to_short_s # "21:44"
101
113
  ```
102
114
 
103
- The CLDR data set only includes 4 specific date formats, full, long, medium, and short, so you'll have to choose amongst them for the one that best fits your needs. Yes, it's limiting, but the 4 formats get the job done most of the time :)
115
+ The default CLDR data set only includes 4 date formats, full, long, medium, and short. See below for a list of additional formats.
104
116
 
105
117
  Behind the scenes, these convenience methods are creating instances of `LocalizedDate`, `LocalizedTime`, and `LocalizedDateTime`. You can do the same thing if you're feeling adventurous:
106
118
 
@@ -109,6 +121,62 @@ dt = TwitterCldr::Localized::LocalizedDateTime.new(DateTime.now, :es)
109
121
  dt.to_short_s # ...etc
110
122
  ```
111
123
 
124
+ #### Additional Date Formats
125
+
126
+ Besides the default date formats, CLDR supports a number of additional ones. The list of available formats varys for each locale. To get a full list, use the `additional_formats_for` method:
127
+
128
+ ```ruby
129
+ # ["EEEEd", "Ed", "GGGGyMd", "H", "Hm", "Hms", "M", "MEd", "MMM", "MMMEEEEd", "MMMEd", ... ]
130
+ TwitterCldr::Formatters::DateTimeFormatter.additional_formats_for(:ja)
131
+ ```
132
+
133
+ You can use any of the returned formats as the `:format` option when creating new instances of `LocalizedDateTime` or `DateTimeFormatter`:
134
+
135
+ ```ruby
136
+ # 2011/12/12 21:44:57
137
+ DateTime.now.localize(:ja).to_s
138
+
139
+ # 12日月曜日
140
+ DateTime.now.localize(:ja).to_s(:format => "EEEEd")
141
+ ```
142
+
143
+ It's important to know that, even though a format may not be available across locales, TwitterCLDR will do it's best to approximate if no exact match can be found.
144
+
145
+ ##### List of additional date format examples for English:
146
+
147
+ | Format | Output |
148
+ |:-------|------------------|
149
+ | EHm | Wed 17:05 |
150
+ | EHms | Wed 17:05:33 |
151
+ | Ed | 28 Wed |
152
+ | Ehm | Wed 5:05 p.m. |
153
+ | Ehms | Wed 5:05:33 p.m. |
154
+ | Gy | 2012 AD |
155
+ | H | 17 |
156
+ | Hm | 17:05 |
157
+ | Hms | 17:05:33 |
158
+ | M | 11 |
159
+ | MEd | Wed 11/28 |
160
+ | MMM | Nov |
161
+ | MMMEd | Wed Nov 28 |
162
+ | MMMd | Nov 28 |
163
+ | Md | 11/28 |
164
+ | d | 28 |
165
+ | h | 5 p.m. |
166
+ | hm | 5:05 p.m. |
167
+ | hms | 5:05:33 p.m. |
168
+ | ms | 05:33 |
169
+ | y | 2012 |
170
+ | yM | 11/2012 |
171
+ | yMEd | Wed 11/28/2012 |
172
+ | yMMM | Nov 2012 |
173
+ | yMMMEd | Wed Nov 28 2012 |
174
+ | yMMMd | Nov 28 2012 |
175
+ | yMd | 11/28/2012 |
176
+ | yQQQ | Q4 2012 |
177
+ | yQQQQ | 4th quarter 2012 |
178
+
179
+
112
180
  #### Relative Dates and Times
113
181
 
114
182
  In addition to formatting full dates and times, TwitterCLDR supports relative time spans via several convenience methods and the `LocalizedTimespan` class. TwitterCLDR tries to guess the best time unit (eg. days, hours, minutes, etc) based on the length of the time span. Unless otherwise specified, TwitterCLDR will use the current date and time as the reference point for the calculation.
@@ -154,6 +222,14 @@ ts.to_s # Vor 1 Tag
154
222
  ts.to_s(:unit => :hour) # Vor 24 Stunden
155
223
  ```
156
224
 
225
+ By default, timespans are exact representations of a given unit of elapsed time. TwitterCLDR also supports approximate timespans which round up to the nearest larger unit. For example, "44 seconds" remains "44 seconds" while "45 seconds" becomes "1 minute". To approximate, pass the `:approximate => true` option into `to_s`:
226
+
227
+ ```ruby
228
+ TwitterCldr::Localized::LocalizedTimespan.new(44).to_s(:approximate => true) # In 44 seconds
229
+ TwitterCldr::Localized::LocalizedTimespan.new(45).to_s(:approximate => true) # In 1 minute
230
+ TwitterCldr::Localized::LocalizedTimespan.new(52).to_s(:approximate => true) # In 1 minute
231
+ ```
232
+
157
233
  ### Lists
158
234
 
159
235
  TwitterCLDR supports formatting lists of strings as you might do in English by using commas, eg: "Apples, cherries, and oranges". Use the `localize` method on an array followed by a call to `to_sentence`:
@@ -565,6 +641,10 @@ No external requirements.
565
641
 
566
642
  Tests are written in RSpec using RR as the mocking framework.
567
643
 
644
+ ## Test Coverage
645
+
646
+ You can run the development test coverage suite with `bundle exec rake spec:cov`, or the full suite with `bundle exec rake spec:cov:full`. TwitterCLDR uses RCov under Ruby 1.8 and Simplecov under Ruby 1.9.
647
+
568
648
  ## JavaScript Support
569
649
 
570
650
  TwitterCLDR currently supports localization of certain textual objects in JavaScript via the twitter-cldr-js gem. See [http://github.com/twitter/twitter-cldr-js](http://github.com/twitter/twitter-cldr-js) for details.
data/Rakefile CHANGED
@@ -32,11 +32,32 @@ namespace :spec do
32
32
  end
33
33
 
34
34
  if RUBY_VERSION < '1.9.0'
35
- desc 'Run all examples with RCov'
36
- RSpec::Core::RakeTask.new('spec:rcov') do |t|
37
- t.rcov = true
38
- t.pattern = './spec/**/*_spec.rb'
39
- t.rcov_opts = %w(-T --sort coverage --exclude gems/,spec/)
35
+ desc 'Run specs with RCov'
36
+ RSpec::Core::RakeTask.new('spec:cov') do |t|
37
+ t.rcov = true
38
+ t.pattern = './spec/**/*_spec.rb'
39
+ t.rcov_opts = '-T --sort coverage --exclude gems/,spec/'
40
+ end
41
+
42
+ desc 'Run full specs suit with RCov'
43
+ task 'spec:cov:full' => %w[spec:full_spec_env spec:cov]
44
+ else
45
+ namespace :spec do
46
+ desc 'Run specs with SimpleCov'
47
+ task :cov => ['spec:simplecov_env', :spec] do
48
+ require 'launchy'
49
+ Launchy.open 'coverage/index.html'
50
+ end
51
+
52
+ desc 'Run full specs suit with SimpleCov'
53
+ task 'cov:full' => %w[spec:full_spec_env spec:cov]
54
+
55
+ task :simplecov_env do
56
+ puts 'Cleaning up coverage reports'
57
+ rm_rf 'coverage'
58
+
59
+ ENV['SCOV'] = 'true'
60
+ end
40
61
  end
41
62
  end
42
63
 
@@ -45,7 +66,7 @@ namespace :update do
45
66
  task :locales_resources, :cldr_path do |_, args|
46
67
  TwitterCldr::Resources::LocalesResourcesImporter.new(
47
68
  args[:cldr_path] || './vendor/cldr',
48
- './resources/locales'
69
+ './resources'
49
70
  ).import
50
71
  end
51
72
 
@@ -7,20 +7,23 @@ module TwitterCldr
7
7
  module Formatters
8
8
  autoload :Base, 'twitter_cldr/formatters/base'
9
9
 
10
- autoload :DateTimeFormatter, 'twitter_cldr/formatters/calendars/datetime_formatter'
11
- autoload :DateFormatter, 'twitter_cldr/formatters/calendars/date_formatter'
12
- autoload :TimeFormatter, 'twitter_cldr/formatters/calendars/time_formatter'
13
- autoload :TimespanFormatter, 'twitter_cldr/formatters/calendars/timespan_formatter'
10
+ autoload :DateTimeFormatter, 'twitter_cldr/formatters/calendars/datetime_formatter'
11
+ autoload :DateFormatter, 'twitter_cldr/formatters/calendars/date_formatter'
12
+ autoload :TimeFormatter, 'twitter_cldr/formatters/calendars/time_formatter'
13
+ autoload :TimespanFormatter, 'twitter_cldr/formatters/calendars/timespan_formatter'
14
14
 
15
- autoload :Numbers, 'twitter_cldr/formatters/numbers'
16
- autoload :NumberFormatter, 'twitter_cldr/formatters/numbers/number_formatter'
17
- autoload :DecimalFormatter, 'twitter_cldr/formatters/numbers/decimal_formatter'
18
- autoload :CurrencyFormatter, 'twitter_cldr/formatters/numbers/currency_formatter'
19
- autoload :PercentFormatter, 'twitter_cldr/formatters/numbers/percent_formatter'
15
+ autoload :Numbers, 'twitter_cldr/formatters/numbers'
16
+ autoload :NumberFormatter, 'twitter_cldr/formatters/numbers/number_formatter'
17
+ autoload :AbbreviatedNumberFormatter, 'twitter_cldr/formatters/numbers/abbreviated/abbreviated_number_formatter'
18
+ autoload :DecimalFormatter, 'twitter_cldr/formatters/numbers/decimal_formatter'
19
+ autoload :ShortDecimalFormatter, 'twitter_cldr/formatters/numbers/abbreviated/short_decimal_formatter'
20
+ autoload :LongDecimalFormatter, 'twitter_cldr/formatters/numbers/abbreviated/long_decimal_formatter'
21
+ autoload :CurrencyFormatter, 'twitter_cldr/formatters/numbers/currency_formatter'
22
+ autoload :PercentFormatter, 'twitter_cldr/formatters/numbers/percent_formatter'
20
23
 
21
- autoload :Plurals, 'twitter_cldr/formatters/plurals'
22
- autoload :PluralFormatter, 'twitter_cldr/formatters/plurals/plural_formatter'
24
+ autoload :Plurals, 'twitter_cldr/formatters/plurals'
25
+ autoload :PluralFormatter, 'twitter_cldr/formatters/plurals/plural_formatter'
23
26
 
24
- autoload :ListFormatter, 'twitter_cldr/formatters/list_formatter'
27
+ autoload :ListFormatter, 'twitter_cldr/formatters/list_formatter'
25
28
  end
26
29
  end
@@ -15,7 +15,7 @@ module TwitterCldr
15
15
  protected
16
16
 
17
17
  def process_tokens(tokens, obj)
18
- result = ''
18
+ result = ""
19
19
 
20
20
  tokens.each_with_index do |token, index|
21
21
  case token.type
@@ -48,16 +48,33 @@ module TwitterCldr
48
48
  self.send(METHODS[token.value[0].chr], date, token.value, token.value.size)
49
49
  end
50
50
 
51
+ def additional_format_selector
52
+ @tokenizer.additional_format_selector
53
+ end
54
+
55
+ def self.additional_formats_for(locale)
56
+ new(:locale => locale).additional_format_selector.patterns.map(&:to_s)
57
+ end
58
+
51
59
  protected
52
60
 
61
+ # there is incomplete era data in CLDR for certain locales like Hindi
62
+ # fall back if that happens
53
63
  def era(date, pattern, length)
54
64
  choices = case length
65
+ when 0
66
+ ["", ""]
55
67
  when 1..3
56
68
  @tokenizer.calendar[:eras][:abbr]
57
69
  else
58
70
  @tokenizer.calendar[:eras][:name]
59
71
  end
60
- choices[date.year < 0 ? 0 : 1]
72
+
73
+ if result = choices[date.year < 0 ? 0 : 1]
74
+ result
75
+ else
76
+ era(date, pattern[0..-2], length - 1)
77
+ end
61
78
  end
62
79
 
63
80
  def year(date, pattern, length)
@@ -132,10 +149,8 @@ module TwitterCldr
132
149
  when 2
133
150
  date.month.to_s.rjust(length, '0')
134
151
  when 3
135
- raise NotImplementedError, 'requires cldr\'s "multiple inheritance"'
136
152
  @tokenizer.calendar[:months][:'stand-alone'][:abbreviated][date.month]
137
153
  when 4
138
- raise NotImplementedError, 'requires cldr\'s "multiple inheritance"'
139
154
  @tokenizer.calendar[:months][:'stand-alone'][:wide][date.month]
140
155
  when 5
141
156
  @tokenizer.calendar[:months][:'stand-alone'][:narrow][date.month]
@@ -8,15 +8,16 @@ module TwitterCldr
8
8
  class TimespanFormatter < Base
9
9
 
10
10
  DEFAULT_TYPE = :default
11
+ APPROXIMATE_MULTIPLIER = 0.75
11
12
 
12
13
  TIME_IN_SECONDS = {
13
- :second => 1,
14
- :minute => 60,
15
- :hour => 3600,
16
- :day => 86400,
17
- :week => 604800,
18
- :month => 2629743.83,
19
- :year => 31556926
14
+ :second => 1,
15
+ :minute => 60,
16
+ :hour => 3600,
17
+ :day => 86400,
18
+ :week => 604800,
19
+ :month => 2629743.83,
20
+ :year => 31556926
20
21
  }
21
22
 
22
23
  def initialize(options = {})
@@ -24,10 +25,11 @@ module TwitterCldr
24
25
  @tokenizer = TwitterCldr::Tokenizers::TimespanTokenizer.new(:locale => extract_locale(options))
25
26
  end
26
27
 
27
- def format(seconds, options = {})
28
+ def format(seconds, fmt_options = {})
29
+ options = fmt_options.dup
28
30
  options[:type] ||= DEFAULT_TYPE
29
31
  options[:direction] ||= @direction || (seconds < 0 ? :ago : :until)
30
- options[:unit] ||= calculate_unit(seconds.abs)
32
+ options[:unit] ||= calculate_unit(seconds.abs, options)
31
33
 
32
34
  options[:number] = calculate_time(seconds.abs, options[:unit])
33
35
 
@@ -36,22 +38,18 @@ module TwitterCldr
36
38
  strings.join.gsub(/\{[0-9]\}/, options[:number].to_s)
37
39
  end
38
40
 
39
- def calculate_unit(seconds)
40
- if seconds < 30
41
- :second
42
- elsif seconds < 2670
43
- :minute
44
- elsif seconds < 86369
45
- :hour
46
- elsif seconds < 604800
47
- :day
48
- elsif seconds < 2591969
49
- :week
50
- elsif seconds < 31556926
51
- :month
52
- else
53
- :year
54
- end
41
+ def calculate_unit(seconds, unit_options = {})
42
+ options = unit_options.dup
43
+ options[:approximate] = false if options[:approximate].nil?
44
+ multiplier = options[:approximate] ? APPROXIMATE_MULTIPLIER : 1
45
+
46
+ if seconds < (TIME_IN_SECONDS[:minute] * multiplier) then :second
47
+ elsif seconds < (TIME_IN_SECONDS[:hour] * multiplier) then :minute
48
+ elsif seconds < (TIME_IN_SECONDS[:day] * multiplier) then :hour
49
+ elsif seconds < (TIME_IN_SECONDS[:week] * multiplier) then :day
50
+ elsif seconds < (TIME_IN_SECONDS[:month] * multiplier) then :week
51
+ elsif seconds < (TIME_IN_SECONDS[:year] * multiplier) then :month
52
+ else :year end
55
53
  end
56
54
 
57
55
  # 0 <-> 29 secs # => seconds
@@ -61,7 +59,7 @@ module TwitterCldr
61
59
  # 29 days, 23 hrs, 59 mins, 29 secs <-> 1 yr minus 1 sec # => months
62
60
  # 1 yr <-> max time or date # => years
63
61
  def calculate_time(seconds, unit)
64
- (seconds / TIME_IN_SECONDS[unit]).round.to_i
62
+ (seconds.to_f / TIME_IN_SECONDS[unit].to_f).round.to_i
65
63
  end
66
64
 
67
65
  end
@@ -0,0 +1,47 @@
1
+ # encoding: UTF-8
2
+
3
+ # Copyright 2012 Twitter, Inc
4
+ # http://www.apache.org/licenses/LICENSE-2.0
5
+
6
+ module TwitterCldr
7
+ module Formatters
8
+ class AbbreviatedNumberFormatter < NumberFormatter
9
+ NUMBER_MAX = 10 ** (TwitterCldr::Tokenizers::NumberTokenizer::ABBREVIATED_MAX_POWER + 1)
10
+ NUMBER_MIN = 10 ** TwitterCldr::Tokenizers::NumberTokenizer::ABBREVIATED_MIN_POWER
11
+
12
+ def default_format_options_for(number)
13
+ { :precision => 0 }
14
+ end
15
+
16
+ def get_tokens(obj, options = {})
17
+ type = (obj < NUMBER_MAX) && (obj >= NUMBER_MIN) ? get_type : :decimal
18
+ format = type == get_type ? get_key(obj) : nil
19
+ opts = options.merge(
20
+ :sign => obj.abs == obj ? :positive : :negative,
21
+ :type => type,
22
+ :format => format
23
+ )
24
+ @tokenizer.tokens(opts)
25
+ end
26
+
27
+ protected
28
+
29
+ def get_type
30
+ :decimal
31
+ end
32
+
33
+ def get_key(number)
34
+ "1#{"0" * (number.to_i.to_s.size - 1)}".to_i
35
+ end
36
+
37
+ def transform_number(number)
38
+ if (number < NUMBER_MAX) && (number >= NUMBER_MIN)
39
+ sig_figs = ((number.to_i.to_s.size - 1) % 3)
40
+ number.to_s[0..sig_figs].to_i
41
+ else
42
+ number
43
+ end
44
+ end
45
+ end
46
+ end
47
+ end