Skip to content

Instantly share code, notes, and snippets.

@ratiw
Last active July 19, 2021 09:31
Show Gist options
  • Star 5 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ratiw/2dda8a02801212b824d9 to your computer and use it in GitHub Desktop.
Save ratiw/2dda8a02801212b824d9 to your computer and use it in GitHub Desktop.
convert number to thai baht text
<?php
/**
* Convert number amount to Thai text as in Excel
*
* author: Rati Wannapanop
* email: rati.wannapanop@gmail.com
* since: 2014-09-06
*/
// 0 ศูนย์
// 1 หนึ่ง
// 2 สอง
// 9 เก้า
// 10 สิบ =\= หนึ่งสิบศูนย์ ==> เลข 1 ที่หลักสิบ ให้เป็น ''
// 11 สิบเอ็ด =\= หนึ่งสิบเอ็ด
// 12 สิบสอง
// 20 ยี่สิบ =\= สองสิบ ==> เลข 2 ที่หลักสิบ ให้เป็น 'ยี่'
// 21 ยี่สิบเอ็ด
// 22 ยี่สิบสอง
// 30 สามสิบ ==> เลข 0 ที่ทุกหลัก ให้เป็น ''
// 31 สามสิบเอ็ด
// 32 สามสิบสอง
// 100 หนึ่งร้อย
// 101 หนึ่งร้อยหนึ่ง =\= หนึ่งร้อยเอ็ด
// 200 สองร้อย
// 1000 หนึ่งพัน
// '1230' --> หนึ่งพันสองร้อยสามสิบ
// '1000000' --> หนึ่งล้าน
class Bahttext
{
protected static $numbers = ['', 'หนึ่ง', 'สอง', 'สาม', 'สี่', 'ห้า', 'หก', 'เจ็ด', 'แปด', 'เก้า'];
protected static $digits = ['สิบ', 'ร้อย', 'พัน', 'หมื่น', 'แสน', 'ล้าน'];
protected static $one_at_oneth = 'เอ็ด';
protected static $two_at_tenth = 'ยี่';
public static function convert($amount)
{
if ((int) $amount == 0) return 'ศูนย์บาท';
$amount = (string) $amount;
// find stang portion
if (($dot = strpos($amount, '.')) > 0)
{
$stang = substr($amount, $dot+1);
$amount = substr($amount, 0, $dot);
}
else{
$stang = '';
}
// pad string to multiple of 6
$amount = str_pad($amount, ceil(strlen($amount) / 6) * 6, ' ', STR_PAD_LEFT);
$chunks = str_split($amount, 6);
$text = '';
while ( ! empty($chunks))
{
$segment = array_pop($chunks);
$text = static::convertSegment($segment) . $text;
if ( ! empty($chunks))
{
$text = 'ล้าน'.$text;
}
}
return $text . 'บาท' . (empty($stang) ? '' : (static::convertSegment($stang) . 'สตางค์'));
}
protected static function convertSegment($segment)
{
$segment = trim($segment);
$length = strlen($segment);
$last_digit = $length -1;
if ($length == 1) return static::$numbers[(int)$segment];
$text = '';
for ($nth = $last_digit; $nth >= 0; $nth--)
{
// any zero in any digit
if ($segment[$nth] == '0') continue;
// oneth digit
if ($nth === $last_digit)
{
$digit = '';
$number = ($segment[$nth] == '1' and $segment[$nth -1] != '0')
? static::$one_at_oneth
: static::$numbers[(int)$segment[$nth]];
}
// tenth digit
elseif ($nth === $last_digit-1)
{
$digit = static::$digits[$last_digit - $nth -1];
if ($segment[$nth] === '1')
{
$number = '';
}
elseif ($segment[$nth] === '2')
{
$number = static::$two_at_tenth;
}
else
{
$number = static::$numbers[(int)$segment[$nth]];
}
}
// other digits
else
{
$number = static::$numbers[(int)$segment[$nth]];
$digit = static::$digits[$last_digit - $nth -1];
}
$text = ($number . $digit) . $text;
}
return $text;
}
}
@takaruz
Copy link

takaruz commented Mar 16, 2017

line : 47

$amount = (string) $amount;

choose change to

$amount = number_format($amount, 2);

because when use

convert(1.20)

it will return

หนึ่งบาทสองสตางค์

@kaweepatt
Copy link

Bahttext::convert(15) return 'หนึ่งสิบห้าบาทถ้วน' which is not correct.

@medunla
Copy link

medunla commented Apr 25, 2018

ถ้า Bahttext::convert(0.25) จะเป็น 'ศูนย์บาท' ซึ่งผิดครับ
Line 45
if ((int) $amount == 0) return 'ศูนย์บาท';
เป็น
if ( $amount == 0.0 ) return 'ศูนย์บาท';

Line 76
return $text . 'บาท' . (empty($stang) ? '' : (static::convertSegment($stang) . 'สตางค์'));
เป็น
if ( $text !== '' ) { $text .= 'บาท'; }
return $text . (empty($stang) ? '' : (static::convertSegment($stang) . 'สตางค์'));

และถ้ามากกว่า 9,999,999,999.99 เช่น 119,999,999,999.50 จะพังเรื่องหาสตางค์ครับ เพราะ double เก็บได้ไม่ไหวครับ มันจะแปลงเป็น E+ แทน ซึ่งอันนี้ผมยังไม่ได้หาทางแก้ครับ

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment