Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

FloatToStr when decimal separator is not a dot #12

Open
lainz opened this issue Dec 12, 2019 · 6 comments
Open

FloatToStr when decimal separator is not a dot #12

lainz opened this issue Dec 12, 2019 · 6 comments

Comments

@lainz
Copy link

lainz commented Dec 12, 2019

Hi, for example when the system locale is Spanish we use comma as decimal separator "," instead of dot "." that causes a problem when using FloatToStr and StrToFloat.

@skrzacikus
Copy link

@lainz use DefaultFormatSettings.DecimalSeparator := ','

@lainz
Copy link
Author

lainz commented Dec 12, 2019

That's not a solution. The solution must be in JsonTools. We already patched it, so it always uses dot instead of comma. But I'm reporting so others doesn't have the same issue.

Our patch is like this:

function StrToFloatDecDef(s: string; rDefault: real):Double;
var sTemp:string;
begin
   sTemp:=StringReplace(s,'.',DecimalSeparator,[rfReplaceAll]);
   result:=StrToFloatDef(sTemp, rDefault);
end;


function FloattoStrDec(aValor: Real): String;
var
  sTmp: string;
begin
    sTmp := FormatFloat('0.0000',aValor);
    sTmp := StringReplace(sTmp, ThousandSeparator, '', [rfReplaceAll, rfIgnoreCase]);
    Result := StringReplace(sTmp, DecimalSeparator, '.',[rfReplaceAll, rfIgnoreCase]);
end;  

procedure TJsonNode.SetAsNumber(Value: Double);
begin
  if FParent = nil then
    Error(SRootNodeKind);
  if FKind <> nkNumber then
  begin
    Clear;
    FKind := nkNumber;
  end;
  FValue := FloattoStrDec(Value);
end;   

function TJsonNode.Add(const Name: string; const N: Double): TJsonNode; overload;
begin
  Result := Add(nkNumber, Name, FloattoStrDec(N));
end;   

function TJsonNode.GetAsNumber: Double;
begin
  if FParent = nil then
    Error(SRootNodeKind);
  if FKind <> nkNumber then
  begin
    Clear;
    FKind := nkNumber;
    FValue := '0';
    Exit(0);
  end;
  Result := StrToFloatDecDef(FValue, 0);
end;  

@hafedh-trimeche
Copy link

Using TFormatSettings would be the solution:

procedure TJsonDataHelper.SetFloat(const Path:string;const AValue:Extended);
var
  FormatSettings : TFormatSettings;
  JsonData       : TJsonData;
begin
  Lock;
  JsonData := PathToObject(Path,nkNumber);
  if Assigned(JsonData) then
  begin
    {$IFDEF DCC}
    FormatSettings := TFormatSettings.Create;
    {$ENDIF}
    FormatSettings.DecimalSeparator := '.';
    try
      JsonData.Value := FormatFloat('0.0'+StringOfChar('#',30),AValue,FormatSettings);
    except
      JsonData.AsNull;
    end;
  end;
  Unlock;
end;

@JacoFourie
Copy link

@lainz I have the same issue. I found I had to change the locale of the machine to have a . as a decimal place.
Do you have a pas file with your path applied?

@JacoFourie
Copy link

OK I added it myself and all is working. Thanks for this.

@lainz
Copy link
Author

lainz commented Apr 2, 2021

You're welcome. I don't share my unit since I think I modified a bit more, and it requires some of the project files, so I can't share.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants