UConv.pm 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494
  1. # $Id: UConv.pm 12996 2017-01-07 10:10:49Z loredo $
  2. package main;
  3. use strict;
  4. use warnings;
  5. sub UConv_Initialize() {
  6. }
  7. package UConv;
  8. use Scalar::Util qw(looks_like_number);
  9. use Data::Dumper;
  10. ####################
  11. # Translations
  12. my %compasspoint_txt = (
  13. "en" => [
  14. 'N', 'NNE', 'NE', 'ENE', 'E', 'ESE', 'SE', 'SSE',
  15. 'S', 'SSW', 'SW', 'WSW', 'W', 'WNW', 'NW', 'NNW'
  16. ],
  17. "de" => [
  18. 'N', 'NNO', 'NO', 'ONO', 'O', 'OSO', 'SO', 'SSO',
  19. 'S', 'SSW', 'SW', 'WSW', 'W', 'WNW', 'NW', 'NNW'
  20. ],
  21. "nl" => [
  22. 'N', 'NNO', 'NO', 'ONO', 'O', 'OZO', 'ZO', 'ZZO',
  23. 'Z', 'ZZW', 'ZW', 'WZW', 'W', 'WNW', 'NW', 'NNW'
  24. ],
  25. "fr" => [
  26. 'N', 'NNE', 'NE', 'ENE', 'E', 'ESE', 'SE', 'SSE',
  27. 'S', 'SSO', 'SO', 'OSO', 'O', 'ONO', 'NO', 'NNO'
  28. ],
  29. "pl" => [
  30. 'N', 'NNE', 'NE', 'ENE', 'E', 'ESE', 'SE', 'SSE',
  31. 'S', 'SSW', 'SW', 'WSW', 'W', 'WNW', 'NW', 'NNW'
  32. ],
  33. );
  34. my %wdays_txt_en = (
  35. "en" => {
  36. 'Mon' => 'Mon',
  37. 'Tue' => 'Tue',
  38. 'Wed' => 'Wed',
  39. 'Thu' => 'Thu',
  40. 'Fri' => 'Fri',
  41. 'Sat' => 'Sat',
  42. 'Sun' => 'Sun',
  43. },
  44. "de" => {
  45. 'Mon' => 'Mo',
  46. 'Tue' => 'Di',
  47. 'Wed' => 'Mi',
  48. 'Thu' => 'Do',
  49. 'Fri' => 'Fr',
  50. 'Sat' => 'Sa',
  51. 'Sun' => 'So',
  52. },
  53. "nl" => {
  54. 'Mon' => 'Maa',
  55. 'Tue' => 'Din',
  56. 'Wed' => 'Woe',
  57. 'Thu' => 'Don',
  58. 'Fri' => 'Vri',
  59. 'Sat' => 'Zat',
  60. 'Sun' => 'Zon',
  61. },
  62. "fr" => {
  63. 'Mon' => 'Lun',
  64. 'Tue' => 'Mar',
  65. 'Wed' => 'Mer',
  66. 'Thu' => 'Jeu',
  67. 'Fri' => 'Ven',
  68. 'Sat' => 'Sam',
  69. 'Sun' => 'Dim',
  70. },
  71. "pl" => {
  72. 'Mon' => 'Pon',
  73. 'Tue' => 'Wt',
  74. 'Wed' => 'Śr',
  75. 'Thu' => 'Czw',
  76. 'Fri' => 'Pt',
  77. 'Sat' => 'Sob',
  78. 'Sun' => 'Nie',
  79. },
  80. );
  81. #################################
  82. ### Inner metric conversions
  83. ###
  84. # Temperature: convert Celsius to Kelvin
  85. sub c2k($;$) {
  86. my ( $data, $rnd ) = @_;
  87. return roundX( $data + 273.15, $rnd );
  88. }
  89. # Temperature: convert Kelvin to Celsius
  90. sub k2c($;$) {
  91. my ( $data, $rnd ) = @_;
  92. return roundX( $data - 273.15, $rnd );
  93. }
  94. # Speed: convert km/h (kilometer per hour) to m/s (meter per second)
  95. sub kph2mps($;$) {
  96. my ( $data, $rnd ) = @_;
  97. return roundX( $data / 3.6, $rnd );
  98. }
  99. # Speed: convert m/s (meter per second) to km/h (kilometer per hour)
  100. sub mps2kph($;$) {
  101. my ( $data, $rnd ) = @_;
  102. return roundX( $data * 3.6, $rnd );
  103. }
  104. # Pressure: convert hPa (hecto Pascal) to mmHg (milimeter of Mercury)
  105. sub hpa2mmhg($;$) {
  106. my ( $data, $rnd ) = @_;
  107. return roundX( $data * 0.00750061561303, $rnd );
  108. }
  109. #################################
  110. ### Metric to angloamerican conversions
  111. ###
  112. # Temperature: convert Celsius to Fahrenheit
  113. sub c2f($;$) {
  114. my ( $data, $rnd ) = @_;
  115. return roundX( $data * 1.8 + 32, $rnd );
  116. }
  117. # Temperature: convert Kelvin to Fahrenheit
  118. sub k2f($;$) {
  119. my ( $data, $rnd ) = @_;
  120. return roundX( ( $data - 273.15 ) * 1.8 + 32, $rnd );
  121. }
  122. # Pressure: convert hPa (hecto Pascal) to in (inches of Mercury)
  123. sub hpa2inhg($;$) {
  124. my ( $data, $rnd ) = @_;
  125. return roundX( $data * 0.02952998751, $rnd );
  126. }
  127. # Pressure: convert hPa (hecto Pascal) to PSI (Pound force per square inch)
  128. sub hpa2psi($;$) {
  129. my ( $data, $rnd ) = @_;
  130. return roundX( $data * 100.00014504, $rnd );
  131. }
  132. # Speed: convert km/h (kilometer per hour) to mph (miles per hour)
  133. sub kph2mph($;$) {
  134. my ( $data, $rnd ) = @_;
  135. return roundX( $data * 0.621, $rnd );
  136. }
  137. # Length: convert mm (milimeter) to in (inch)
  138. sub mm2in($;$) {
  139. my ( $data, $rnd ) = @_;
  140. return roundX( $data * 0.039370, $rnd );
  141. }
  142. # Length: convert cm (centimeter) to in (inch)
  143. sub cm2in($;$) {
  144. my ( $data, $rnd ) = @_;
  145. return roundX( $data * 0.39370, $rnd );
  146. }
  147. # Length: convert m (meter) to ft (feet)
  148. sub m2ft($;$) {
  149. my ( $data, $rnd ) = @_;
  150. return roundX( $data * 3.2808, $rnd );
  151. }
  152. #################################
  153. ### Inner Angloamerican conversions
  154. ###
  155. # Speed: convert mph (miles per hour) to ft/s (feet per second)
  156. sub mph2fts($;$) {
  157. my ( $data, $rnd ) = @_;
  158. return roundX( $data * 1.467, $rnd );
  159. }
  160. # Speed: convert ft/s (feet per second) to mph (miles per hour)
  161. sub fts2mph($;$) {
  162. my ( $data, $rnd ) = @_;
  163. return roundX( $data / 1.467, $rnd );
  164. }
  165. #################################
  166. ### Angloamerican to Metric conversions
  167. ###
  168. # Temperature: convert Fahrenheit to Celsius
  169. sub f2c($;$) {
  170. my ( $data, $rnd ) = @_;
  171. return roundX( ( $data - 32 ) * 0.5556, $rnd );
  172. }
  173. # Temperature: convert Fahrenheit to Kelvin
  174. sub f2k($;$) {
  175. my ( $data, $rnd ) = @_;
  176. return roundX( ( $data - 32 ) / 1.8 + 273.15, $rnd );
  177. }
  178. # Pressure: convert in (inches of Mercury) to hPa (hecto Pascal)
  179. sub inhg2hpa($;$) {
  180. my ( $data, $rnd ) = @_;
  181. return roundX( $data * 33.8638816, $rnd );
  182. }
  183. # Pressure: convert PSI (Pound force per square inch) to hPa (hecto Pascal)
  184. sub psi2hpa($;$) {
  185. my ( $data, $rnd ) = @_;
  186. return roundX( $data / 100.00014504, $rnd );
  187. }
  188. # Speed: convert mph (miles per hour) to km/h (kilometer per hour)
  189. sub mph2kph($;$) {
  190. my ( $data, $rnd ) = @_;
  191. return roundX( $data * 1.609344, $rnd );
  192. }
  193. # Length: convert in (inch) to mm (milimeter)
  194. sub in2mm($;$) {
  195. my ( $data, $rnd ) = @_;
  196. return roundX( $data * 25.4, $rnd );
  197. }
  198. # Length: convert in (inch) to cm (centimeter)
  199. sub in2cm($;$) {
  200. my ( $data, $rnd ) = @_;
  201. return roundX( $data / 0.39370, $rnd );
  202. }
  203. # Length: convert ft (feet) to m (meter)
  204. sub ft2m($;$) {
  205. my ( $data, $rnd ) = @_;
  206. return roundX( $data / 3.2808, $rnd );
  207. }
  208. #################################
  209. ### Angular conversions
  210. ###
  211. # convert direction in degree to point of the compass
  212. sub direction2compasspoint($;$) {
  213. my ( $azimuth, $lang ) = @_;
  214. my $directions_txt_i18n;
  215. if ( $lang && defined( $compasspoint_txt{$lang} ) ) {
  216. $directions_txt_i18n = $compasspoint_txt{$lang};
  217. }
  218. else {
  219. $directions_txt_i18n = $compasspoint_txt{en};
  220. }
  221. return @$directions_txt_i18n[
  222. int( ( ( $azimuth + 11.25 ) % 360 ) / 22.5 )
  223. ];
  224. }
  225. #################################
  226. ### Solar conversions
  227. ###
  228. # Power: convert uW/cm2 (micro watt per square centimeter) to UV-Index
  229. sub uwpscm2uvi($) {
  230. my ($data) = @_;
  231. # Forum topic,44403.msg501704.html#msg501704
  232. return int( ( $data - 100 ) / 450 + 1 );
  233. }
  234. # Power: convert lux to W/m2 (watt per square meter)
  235. sub lux2wpsm($;$) {
  236. my ( $data, $rnd ) = @_;
  237. # Forum topic,44403.msg501704.html#msg501704
  238. return roundX( $data / 126.7, $rnd );
  239. }
  240. #################################
  241. ### Nautic unit conversions
  242. ###
  243. # Speed: convert km/h to knots
  244. sub kph2kn($;$) {
  245. my ( $data, $rnd ) = @_;
  246. return roundX( $data * 0.539956803456, $rnd );
  247. }
  248. # Speed: convert km/h to Beaufort wind force scale
  249. sub kph2bft($) {
  250. my ($data) = @_;
  251. my $v = "0";
  252. if ( $data >= 118 ) {
  253. $v = "12";
  254. }
  255. elsif ( $data >= 103 ) {
  256. $v = "11";
  257. }
  258. elsif ( $data >= 89 ) {
  259. $v = "10";
  260. }
  261. elsif ( $data >= 75 ) {
  262. $v = "9";
  263. }
  264. elsif ( $data >= 62 ) {
  265. $v = "8";
  266. }
  267. elsif ( $data >= 50 ) {
  268. $v = "7";
  269. }
  270. elsif ( $data >= 39 ) {
  271. $v = "6";
  272. }
  273. elsif ( $data >= 29 ) {
  274. $v = "5";
  275. }
  276. elsif ( $data >= 20 ) {
  277. $v = "4";
  278. }
  279. elsif ( $data >= 12 ) {
  280. $v = "3";
  281. }
  282. elsif ( $data >= 6 ) {
  283. $v = "2";
  284. }
  285. elsif ( $data >= 1 ) {
  286. $v = "1";
  287. }
  288. return $v;
  289. }
  290. # Speed: convert mph (miles per hour) to Beaufort wind force scale
  291. sub mph2bft($) {
  292. my ($data) = @_;
  293. my $v = "0";
  294. if ( $data >= 73 ) {
  295. $v = "12";
  296. }
  297. elsif ( $data >= 64 ) {
  298. $v = "11";
  299. }
  300. elsif ( $data >= 55 ) {
  301. $v = "10";
  302. }
  303. elsif ( $data >= 47 ) {
  304. $v = "9";
  305. }
  306. elsif ( $data >= 39 ) {
  307. $v = "8";
  308. }
  309. elsif ( $data >= 32 ) {
  310. $v = "7";
  311. }
  312. elsif ( $data >= 25 ) {
  313. $v = "6";
  314. }
  315. elsif ( $data >= 19 ) {
  316. $v = "5";
  317. }
  318. elsif ( $data >= 13 ) {
  319. $v = "4";
  320. }
  321. elsif ( $data >= 8 ) {
  322. $v = "3";
  323. }
  324. elsif ( $data >= 4 ) {
  325. $v = "2";
  326. }
  327. elsif ( $data >= 1 ) {
  328. $v = "1";
  329. }
  330. return $v;
  331. }
  332. #################################
  333. ### Textual unit conversions
  334. ###
  335. # Condition: convert humidity (percent) to humidity condition
  336. sub humidity2condition($) {
  337. my ($data) = @_;
  338. my $v = "dry";
  339. if ( $data >= 80 ) {
  340. $v = "wet";
  341. }
  342. elsif ( $data >= 70 ) {
  343. $v = "high";
  344. }
  345. elsif ( $data >= 50 ) {
  346. $v = "optimal";
  347. }
  348. elsif ( $data >= 40 ) {
  349. $v = "low";
  350. }
  351. return $v;
  352. }
  353. # Condition: convert UV-Index to UV condition
  354. sub uvi2condition($) {
  355. my ($data) = @_;
  356. my $v = "low";
  357. if ( $data > 11 ) {
  358. $v = "extreme";
  359. }
  360. elsif ( $data > 8 ) {
  361. $v = "veryhigh";
  362. }
  363. elsif ( $data > 6 ) {
  364. $v = "high";
  365. }
  366. elsif ( $data > 3 ) {
  367. $v = "moderate";
  368. }
  369. return $v;
  370. }
  371. sub values2weathercondition($$$$$) {
  372. my ( $temp, $hum, $light, $isday, $israining ) = @_;
  373. my $condition = "clear";
  374. if ( $israining eq "1" ) {
  375. $condition = "rain";
  376. }
  377. elsif ( $light > 40000 ) {
  378. $condition = "sunny";
  379. }
  380. elsif ( $isday eq "1" ) {
  381. $condition = "cloudy";
  382. }
  383. $condition = "nt_" . $condition if ( !$isday );
  384. return $condition;
  385. }
  386. #TODO rewrite for Unit.pm
  387. sub fmtTime($) {
  388. my ($value) = @_;
  389. my $suffix = ' s';
  390. if ( $value >= 60 ) {
  391. $value = sprintf( "%.1f", $value / 60 );
  392. $suffix = ' min';
  393. if ( $value >= 60 ) {
  394. $value = sprintf( "%.1f", $value / 60 );
  395. $suffix = ' h';
  396. }
  397. }
  398. return ( $value, $suffix ) if (wantarray);
  399. return $value . $suffix;
  400. }
  401. ####################
  402. # HELPER FUNCTIONS
  403. sub decimal_mark ($$) {
  404. my ( $v, $f ) = @_;
  405. return $v unless ( looks_like_number($v) && $f );
  406. my $text = reverse $v;
  407. if ( $f eq "2" ) {
  408. $text =~ s:\.:,:g;
  409. $text =~ s/(\d\d\d)(?=\d)(?!\d*,)/$1./g;
  410. }
  411. else {
  412. $text =~ s/(\d\d\d)(?=\d)(?!\d*\.)/$1,/g;
  413. }
  414. return scalar reverse $text;
  415. }
  416. sub roundX($;$) {
  417. my ( $v, $n ) = @_;
  418. $n = 1 if ( !$n );
  419. return sprintf( "%.${n}f", $v );
  420. }
  421. 1;