Skip to content

Instantly share code, notes, and snippets.

@mbijon
Created March 17, 2012 01:19
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mbijon/2054126 to your computer and use it in GitHub Desktop.
Save mbijon/2054126 to your computer and use it in GitHub Desktop.
Human-format currency $'s converted to machine floating points
<?php
/*
* Human-format currency $'s converted to machine floating points
*/
// Dollar amount via GET (not very secure)
$raw_dollar_amount = ( isset($_GET['dollar_amount']) ) ? htmlentities( $_GET['dollar_amount'], ENT_QUOTES, 'UTF-8' ) : FALSE;
if ( $raw_dollar_amount ) {
// Create a return value in case nothing done
$float_dollar_amount = $raw_dollar_amount;
// Build string of only the separators
$separators_only = preg_filter( '/[^,\.]/i', '', $raw_dollar_amount );
/*
*
* Check # of separators
* If more than one, position determines region
*
* NOTE: Am assuming no separators in the decimal portion
* That could be problem for complex #'s, but this isn't physics class after all
*
*/
if ( strlen( $separators_only ) > 1 ) {
if ( substr( $separators_only, 0, 1) == '.' ) {
$float_dollar_amount = str_replace( '.', '', $float_dollar_amount );
$float_dollar_amount = str_replace( ',', '.', $float_dollar_amount );
} else if ( substr( $separators_only, 0, 1) == ',' ) {
$float_dollar_amount = str_replace( ',', '', $float_dollar_amount );
}
} else if ( strlen( $separators_only ) == 1 && $separators_only == ',' ) {
/*
* Here's the crux assumption made for fule prices:
* That "4.99", "4.9999" or "4,999" is likely to be float "4.9{999}"
*
* Other option is to measure # digits after the separator
* ...but then we hit same problem as prev regex:
* http://www.php.net/manual/en/function.floatval.php#85346
*
*/
$float_dollar_amount = str_replace( ',', '.', $float_dollar_amount );
}
// Output trackers & processed value
echo "<h2>Raw &amp; Filtered Values</h2>";
echo "Float $-value: $float_dollar_amount<br /><br />";
echo "Raw input $-value: $raw_dollar_amount<br />";
echo "Separators from raw input: $separators_only<br /><br />";
}
// Input form
?>
<h2>Input a $-amount here</h2>
<form id="dollar_input" name="dollar_input" action="<?php echo $_SERVER['PHP_SELF']; ?>" method="get">
<input type="text" name="dollar_amount" />
<input type="submit" value="Submit" />
</form>
@Viper007Bond
Copy link

This is what I ended up doing:

Any time I made a note to not include thousands separators, I used this function because it is the most accurate (I'll explain why shortly):

<?php

    public function float_nothousands( $number ) {
        $number = str_replace( '$', '', $number );
        $number = str_replace( ',', '.', $number );

        return (float) $number;
    }

However any time it was just a random human string, this parses pretty well:

<?php

    public function human_to_float( $number ) {
        $number = str_replace( '$', '', $number );

        // By "info at marc-gutt dot de" via http://www.php.net/manual/en/function.floatval.php#85346
        $number = floatval( preg_replace( '#^([-]*[0-9\.,\' ]+?)((\.|,){1}([0-9-]{1,2}))*$#e', "str_replace(array('.', ',', \"'\", ' '), '', '\\1') . '.\\4'", $number ) );

        return $number;
    }

The only issue is when you pass three decimal points, such as a gas price of $4.039. The regex converts it to "4039". That's why I have my non-regex function.

I used this code to test the various methods I found in the php.net comments and my own personal function: https://gist.github.com/2054188

@mbijon
Copy link
Author

mbijon commented Mar 17, 2012

Mine mainly fixes your three decimal issue (4.039 stays a float), but only on the assumption that fuel prices will more frequently have three decimal places than their purchases reach thousands of dollars.

No worries either way, better use of time than flipping through Twitter links on the way home.

@Viper007Bond
Copy link

Yeah, if you're only parsing gas prices, you can make some assumptions. I'm also parsing things like mileage (54,678.9) and stuff though so I'm making my code a bit less strict.

@mbijon
Copy link
Author

mbijon commented Mar 19, 2012

Understood. I might have added different parsing code for each number type, but I saw your comment about 1,200 lines ... a lot for a plugin to track fuel & mileage.

@Viper007Bond
Copy link

I'm up past 1800 lines now. I expect to pass 2000 before the plugin gets released. Lots of fancy features. :)

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