fix: Update patient_tracker.php (#6595)
[openemr.git] / library / classes / NumberToText.class.php
blobfde3401a5bf3c4b5906a95c3ed7726be0559b7bd
1 <?php
3 //pulled from www.djgeespot.com/php, reworked as a class
5 /** Serialized Array of big names, thousand, million, etc
6 * @package NumberToText */
8 define("N2T_BIG", serialize(array('thousand', 'million', 'billion', 'trillion', 'quadrillion', 'quintillion', 'sextillion', 'septillion', 'octillion', 'nonillion', 'decillion', 'undecillion', 'duodecillion', 'tredecillion', 'quattuordecillion', 'quindecillion', 'sexdecillion', 'septendecillion', 'octodecillion', 'novemdecillion', 'vigintillion')));
9 /** Serialized Array of medium names, twenty, thirty, etc
10 * @package NumberToText */
11 define("N2T_MEDIUM", serialize(array(2 => 'twenty', 3 => 'thirty', 4 => 'forty', 5 => 'fifty', 6 => 'sixty', 7 => 'seventy', 8 => 'eighty', 9 => 'ninety')));
12 /** Serialized Array of small names, zero, one, etc.. up to eighteen, nineteen
13 * @package NumberToText */
14 define("N2T_SMALL", serialize(array('zero', 'one', 'two', 'three', 'four', 'five', 'six', 'seven', 'eight', 'nine', 'ten', 'eleven', 'twelve', 'thirteen', 'fourteen', 'fifteen', 'sixteen', 'seventeen', 'eighteen', 'nineteen')));
15 /** Word for "dollars"
16 * @package NumberToText */
17 define("N2T_DOLLARS", "dollars");
18 /** Word for one "dollar"
19 * @package NumberToText */
20 define("N2T_DOLLARS_ONE", "dollar");
21 /** Word for "cents"
22 * @package NumberToText */
23 define("N2T_CENTS", "cents");
24 /** Word for one "cent"
25 * @package NumberToText */
26 define("N2T_CENTS_ONE", "cent");
27 /** Word for "and"
28 * @package NumberToText */
29 define("N2T_AND", "and");
30 /** Word for "negative"
31 * @package NumberToText */
32 define("N2T_NEGATIVE", "negative");
34 class NumberToText
36 var $number;
37 var $currency;
38 var $capatalize;
39 var $and;
41 function __construct($number, $currency = false, $capatalize = false, $and = false)
43 $this->number = $number;
44 $this->currency = $currency;
45 $this->capatalize = $capatalize;
46 $this->and = $and;
49 /** Number to text converter. Converts a number into a textual description, such as
50 * "one hundred thousand and twenty-five".
52 * Now supports _any_ size number, and negative numbers. To pass numbers > 2 ^32, you must
53 * pass them as a string, as PHP only has 32-bit integers.
55 * @author Greg MacLelan
56 * @version 1.1
57 * @param int $number The number to convert
58 * @param bool $currency True to convert as a dollar amount
59 * @param bool $capatalize True to capatalize every word (except "and")
60 * @param bool $and True to use "and" (ie. "one hundred AND six")
61 * @return The textual description of the number, as a string.
62 * @package NumberToText
65 function convert()
67 $number = $this->number;
68 $currency = $this->currency;
69 $capatalize = $this->capatalize;
70 $and = $this->and;
72 $big = unserialize(N2T_BIG, ['allowed_classes' => false]);
73 $small = unserialize(N2T_SMALL, ['allowed_classes' => false]);
75 // get rid of leading 0's
77 while ($number{0} == 0) {
78 $number = substr($number,1);
82 if ($number === 0) {
83 return "zero";
86 $text = "";
88 //$negative = ($number < 0); // check for negative
89 //$number = abs($number); // make sure we have a +ve number
90 if (substr($number, 0, 1) == "-") {
91 $negative = true;
92 $number = substr($number, 1); // abs()
93 } else {
94 $negative = false;
97 // get the integer and decimal parts
98 //$int_o = $int = floor($number); // store into two vars
99 if ($pos = strpos($number, ".")) {
100 $int_o = $int = substr($number, 0, $pos);
101 $decimal_o = $decimal = substr($number, $pos + 1);
102 } else {
103 $int_o = $int = $number;
104 $decimal_o = $decimal = 0;
107 // $int_o and $decimal_o are for "original value"
108 // conversion for integer part:
110 $section = 0; // $section controls "thousand" "million" etc
111 $text = '';
112 do {
113 // keep breaking down into 3 digits ($convert) and the rest
114 //$convert = $int % 1000;
115 //$int = floor($int / 1000);
117 if ($section > count($big) - 1) {
118 // ran out of names for numbers this big, call recursively
119 $text = NumberToText($int, false, false, $and) . " " . $big[$section - 1] . " " . $text;
120 $int = 0;
121 } else {
122 // we can handle it
124 if (strlen($int) < 3) {
125 $convert = $int;
126 $int = 0;
127 } else {
128 $convert = substr($int, -3); // grab the last 3 digits
129 $int = substr($int, 0, -1 * strlen($convert));
132 if ($convert > 0) {
133 // we have something here, put it in
134 if ($section > 0) {
135 $text = $this->n2t_convertthree($convert, $and, ($int > 0)) . " " . $big[$section - 1] . " " . $text;
136 } else {
137 $text = $this->n2t_convertthree($convert, $and, ($int > 0));
142 $section++;
143 } while ($int > 0);
145 // conversion for decimal part:
147 if ($currency && floor($number)) {
148 // add " dollars"
149 $text .= " " . ($int_o == 1 ? N2T_DOLLARS_ONE : N2T_DOLLARS) . " ";
152 if ($decimal && $currency) {
153 // if we have any cents, add those
154 if ($int_o > 0) {
155 $text .= " " . N2T_AND . " ";
158 $cents = substr($decimal, 0, 2); // (0.)2342 -> 23
159 $decimal = substr($decimal, 2); // (0.)2345.. -> 45..
161 $text .= $this->n2t_convertthree($cents, false, true); // explicitly show "and" if there was an $int
164 if ($decimal) {
165 // any remaining decimals (whether or not $currency is set)
166 $text .= " point";
167 for ($i = 0; $i < strlen($decimal); $i++) {
168 // go through one number at a time
169 $text .= " " . $small[$decimal[$i]];
174 if ($decimal_o && $currency) {
175 // add " cents" (if we're doing currency and had decimals)
176 $text .= " " . ($decimal_o == 1 ? N2T_CENTS_ONE : N2T_CENTS);
179 // check for negative
180 if ($negative) {
181 $text = N2T_NEGATIVE . " " . $text;
184 // capatalize words
185 if ($capatalize) {
186 // easier to capatalize all words then un-capatalize "and"
187 $text = str_replace(ucwords(N2T_AND), N2T_AND, ucwords($text));
190 return trim($text);
193 /** This is a utility function of n2t. It converts a 3-digit number
194 * into a textual description. Normally this is not called by itself.
196 * @param int $number The 3-digit number to convert (0 - 999)
197 * @param bool $and True to put the "and" in the string
198 * @param bool $preceding True if there are preceding members, puts an
199 * explicit and in (ie 1001 => one thousand AND one)
200 * @return The textual description of the number, as a string
201 * @package NumberToText
203 function n2t_convertthree($number, $and, $preceding)
205 $small = unserialize(N2T_SMALL, ['allowed_classes' => false]);
206 $medium = unserialize(N2T_MEDIUM, ['allowed_classes' => false]);
208 $text = "";
210 if ($hundreds = floor($number / 100)) {
211 // we have 100's place
212 $text .= $small[$hundreds] . " hundred ";
215 $tens = $number % 100;
216 if ($tens) {
217 // we still have values
218 if ($and && ($hundreds || $preceding)) {
219 $text .= " " . N2T_AND . " ";
222 if ($tens < 20) {
223 $text .= $small[$tens];
224 } else {
225 $text .= $medium[floor($tens / 10)];
226 if ($ones = $tens % 10) {
227 $text .= "-" . $small[$ones];
232 return $text;
235 function getmicrotime()
237 list($usec, $sec) = explode(" ", microtime());
238 return ((float)$usec + (float)$sec);