1

在 Delphi XE2 中,我在格式化Currency. 使用Double按预期工作。

看起来当使用%For %N(浮点数或数字)时,即使您请求的数量更少,您也总是得到 3 个十进制数字。

  • 使用 format'%.1f'Double3.1415将变为'3.1',但 的Currency3.1415将变为'3.142'(假设 en-US 区域设置)。
  • 使用 format'%4.0n'Double3.1415将变为' 3',但 的Currency3.1415将变为'3.142'(假设 en-US 区域设置)。

我写了下面的快速 DUnit 测试用例,明天将进一步调查。

这个特定的项目不能更改为 Delphi XE2 以外的任何东西(大公司在他们使用的工具上并不灵活),所以我正在寻找在 Delphi XE2 中解决这个问题的解决方案。

同时:你的想法是什么?

unit TestSysUtilsFormatUnit;

interface

uses
  TestFramework, System.SysUtils;

type
  TestSysUtilsFormat = class(TTestCase)
  strict private
    DoublePi: Double;
    CurrencyPi: Currency;
    FloatFormat: string;
    NumericFormat: string;
    Expected_Format_F: string;
    Expected_Format_N: string;
  public
    procedure SetUp; override;
    procedure TearDown; override;
  published
    procedure Test_Format_F_Double;
    procedure Test_Format_F_Currency;
    procedure Test_Format_N_Double;
    procedure Test_Format_N_Currency;
  end;

implementation

procedure TestSysUtilsFormat.Test_Format_F_Double;
var
  ReturnValue: string;
begin
  ReturnValue := System.SysUtils.Format(FloatFormat, [DoublePi]);
  Self.CheckEqualsString(Expected_Format_F, ReturnValue); // actual '3.1'
end;

procedure TestSysUtilsFormat.Test_Format_F_Currency;
var
  ReturnValue: string;
begin
  ReturnValue := System.SysUtils.Format(FloatFormat, [CurrencyPi]);
  Self.CheckEqualsString(Expected_Format_F, ReturnValue); // actual '3.142'
end;

procedure TestSysUtilsFormat.Test_Format_N_Double;
var
  ReturnValue: string;
begin
  ReturnValue := System.SysUtils.Format(NumericFormat, [DoublePi]);
  Self.CheckEqualsString(Expected_Format_N, ReturnValue); // actual '   3'
end;

procedure TestSysUtilsFormat.Test_Format_N_Currency;
var
  ReturnValue: string;
begin
  ReturnValue := System.SysUtils.Format(NumericFormat, [CurrencyPi]);
  Self.CheckEqualsString(Expected_Format_N, ReturnValue); // actual '3.142'
end;

procedure TestSysUtilsFormat.SetUp;
begin
  DoublePi := 3.1415;
  CurrencyPi := 3.1415;
  FloatFormat := '%.1f';
  Expected_Format_F := '3.1';
  NumericFormat := '%4.0n';
  Expected_Format_N := '   3';
end;

procedure TestSysUtilsFormat.TearDown;
begin
end;

initialization
  RegisterTest(TestSysUtilsFormat.Suite);
end.
4

2 回答 2

1

在对上述问题的评论中,应提问者的要求将其发布为答案。)

我无法使用普通控制台应用程序在 XE2 或 XE3 上重现该问题。(为我设置起来更快。)

这是我完全使用的代码(在 XE2/XE3 上):

program Project1;

{$APPTYPE CONSOLE}

{$R *.res}

uses
  SysUtils;

const
  DoublePi: Double = 3.1415;
  CurrencyPi: Currency = 3.1415;
  FloatFormat = '%.1f';
  NumericFormat = '%4.0n';
begin
  WriteLn(Format('Double   (.1f) : '#9 + FloatFormat, [DoublePi]));
  WriteLn(Format('Currency (.1f) : '#9 + FloatFormat, [CurrencyPi]));
  WriteLn(Format('Currency (4.0n): '#9 + NumericFormat, [CurrencyPi]));
  ReadLn;
end.

这是 XE2 运行的输出(Delphi® XE2 版本 16.0.4429.46931):

格式化货币控制台应用程序输出

于 2013-04-17T10:57:26.223 回答
0

这是这些方法中早期 Delphi XE 2 版本中的一个错误:

function WideFormatBuf(var Buffer; BufLen: Cardinal; const Format;
  FmtLen: Cardinal; const Args: array of const;
  const AFormatSettings: TFormatSettings): Cardinal;

function FormatBuf(var Buffer; BufLen: Cardinal; const Format;
  FmtLen: Cardinal; const Args: array of const;
  const AFormatSettings: TFormatSettings): Cardinal;

失败:

  • Embarcadero® RAD Studio XE2 版本 16.0.4256.43595(更新 2)

(奇怪的是:该版本在开始“检查更新”时表示“没有可用的更新”)

我没有时间检查中间版本。

作品:

  • Embarcadero® RAD Studio XE2 版本 16.0.4429.46931(更新 4))
  • Embarcadero® Delphi® XE2 版本 16.0.4504.48759(更新 4 修补程序 1)

XE2 Update 4(带有或不带有修补程序)破坏的一件事是创建标准(非 IntraWeb)单元测试项目。

缺少此菜单项:File -> New -> Other -> Unit Test -> Test Project

提醒我自己,这是快速开始使用缺少的测试项目条目的框架代码:

program UnitTest1;
{

  Delphi DUnit Test Project
  -------------------------
  This project contains the DUnit test framework and the GUI/Console test runners.
  Add "CONSOLE_TESTRUNNER" to the conditional defines entry in the project options
  to use the console test runner.  Otherwise the GUI test runner will be used by
  default.

}

{$IFDEF CONSOLE_TESTRUNNER}
{$APPTYPE CONSOLE}
{$ENDIF}

uses
  Forms,
  TestFramework,
  GUITestRunner,
  TextTestRunner;

{$R *.RES}

begin
  Application.Initialize;
  if IsConsole then
    with TextTestRunner.RunRegisteredTests do
      Free
  else
    GUITestRunner.RunRegisteredTests;
end.
于 2013-04-19T11:21:17.070 回答