XSharpPublic icon indicating copy to clipboard operation
XSharpPublic copied to clipboard

XBase++ compiler: unexpected Transform() behaviour. SetLocale() implementation

Open Danila2903 opened this issue 3 years ago • 2 comments

Problem

I've tried to run example code from XBase++ documentation: https://doc.alaska-software.com/content/fdc_xppfcref_transform.html In several cases XSharp is misbehaving. I use XSharp 2.9a, compile code with xsc.exe.

Test 1:

Picture "@(" doesn't remove minus from negative number:

Code

xValue := -1234.56
? Transform( xValue, "@("          )

Expected behavior ( 1234.56)

Result ( -1234,56) The same goes with picture "@)", but without leading blank spaces.

Test 2:

Picture "@L" doesn't fill with characters from the left:

Code

xValue := -1234.56
? Transform( xValue, "@Lm 999,999.99")

Expected behavior m-1,234.56

XSharp behavior -1234,56

Test 3:

Picture "@Lx" doesn't work right:

Code

xValue := -1234.56
? Transform( xValue, "@Lx 999,999.99")

Expected behavior xx-1,234.56

XBase++ compiler behavior xx1234.56 DB

XSharp behavior -1234,56 DB It seems that both XBase++ and XSharp compilers work wrong: they recognized "@Lx" not like "Filling numeric values from the left with the character x", but like "@L" and "@X", so they wrote Debet in the end.

Also, picture "@X" removes minus in XBase++ compiler. Maybe it behaves that way because of accounting calculations (Debet with Credit), but I cannot say exactly. XSharp doesn't remove.

Test 4:

Country-specific formatting of numbers. Comments from source code are taken from documentation

Code

local nNumber, nNumberA, nNumberB, cStringA, cStringB
nNumber  := 12.345
cStringA := Transform( nNumber, "@N" )  // may result in
                                                    // "12,345" or "12.345"
cStringB := Str( nNumber, 6, 3 )                 // is always "12.345"

nNumberA := Val( cStringA ) * 10              // may result in
                                            // 120 or 123.45
nNumberB := Val( cStringB ) * 10               // is always 123.45
? 'nNumber ', nNumber
? 'cStringA ', cStringA
? 'cStringB ', cStringB
? 'nNumberA ', nNumberA
? 'nNumberB ', nNumberB

Expected behavior

nNumber 12.345
cStringA 12.345
cStringB 12.345
nNumberA 123.450
nNumberB 123.450

XSharp behavior

nNumber 12,35
cStringA 12,35
cStringB 12,345
nNumberA 123,50
nNumberB 123,450
  1. I haven't found the way to set decimal separator '.', because "setlocale()" doesn't exist in XSharp (https://doc.alaska-software.com/content/fdc_xppfcref_setlocale.html) Are you going to implement it or is there any way to set culture info in XSharp?
  2. Is it expected rounding?

Danila2903 avatar Jan 25 '22 09:01 Danila2903

The default settings for decimal and thousand separators are read from the settings for the current user in windows. You can change that with SetInternational() SetInternational("Windows") copies the settings from the current user. SetInternational("Clipper") sets them to default values from the runtime. SetInternational("Windows") is the default and reads settings for date format, time format, separators AM/PM setting etc.

To change specific settings you can use

SetDecimal() to set the decimal separator SetThousandSep() to set the thousand separator SetDateFormat() to set the date format SetTimeFormat() to set the time format SetTimeSep() to set the separator for time strings SetAmPm() and SetAmExt() and SetPmExt() for the time suffix

RobertvanderHulst avatar Jan 25 '22 13:01 RobertvanderHulst

We can probably also implement the SetLocale() function

RobertvanderHulst avatar Jan 25 '22 13:01 RobertvanderHulst