首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Delphi XE2 FormatDateTime通过-693594

Delphi XE2 FormatDateTime通过-693594
EN

Stack Overflow用户
提问于 2012-02-13 11:46:06
回答 1查看 1.9K关注 0票数 3

我们这里有一个小问题。我们已经从Delphi2006升级到Delphi XE2,并且正在转换我们的代码。

问题是,我们在应用程序和数据库记录中使用值-693594来表示没有日期(零日期)。在Delphi2006中,FormatDateTime函数会正确地将其格式化为00/00/0000 (给定日期格式为dd/mm/yyyy)。

然而,在Delphi XE2中,他们在System.SysUtils的DateTImeToTimeStamp函数中添加了对ValidateTimeStampDate的调用,这会引发错误“无效的浮点操作”。传递任何大于-693594的值,比如-693593,都可以正常工作。

有没有其他人遇到过这个问题,或者有没有人知道解决方法?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2012-02-14 07:15:32

如果你真的不顾一切地想要回到之前的行为,你可以使用这样的东西:

代码语言:javascript
复制
unit Unit1;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls;

type
  TForm1 = class(TForm)
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure PatchCode(Address: Pointer; const NewCode; Size: Integer);
var
  OldProtect: DWORD;
begin
  if VirtualProtect(Address, Size, PAGE_EXECUTE_READWRITE, OldProtect) then
  begin
    Move(NewCode, Address^, Size);
    FlushInstructionCache(GetCurrentProcess, Address, Size);
    VirtualProtect(Address, Size, OldProtect, @OldProtect);
  end;
end;

type
  PInstruction = ^TInstruction;
  TInstruction = packed record
    Opcode: Byte;
    Offset: Integer;
  end;

procedure RedirectProcedure(OldAddress, NewAddress: Pointer);
var
  NewCode: TInstruction;
begin
  NewCode.Opcode := $E9;//jump relative
  NewCode.Offset := NativeInt(NewAddress)-NativeInt(OldAddress)-SizeOf(NewCode);
  PatchCode(OldAddress, NewCode, SizeOf(NewCode));
end;

function DateTimeToTimeStamp(DateTime: TDateTime): TTimeStamp;
const
  FMSecsPerDay: Single = MSecsPerDay;
  IMSecsPerDay: Integer = MSecsPerDay;
var
  LTemp, LTemp2: Int64;
begin
  LTemp := Round(DateTime * FMSecsPerDay);
  LTemp2 := (LTemp div IMSecsPerDay);
  Result.Date := DateDelta + LTemp2;
  Result.Time := Abs(LTemp) mod IMSecsPerDay;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
  ShowMessage(FormatDateTime('dd/mm/yyyy', -693594));
end;

initialization
  RedirectProcedure(@System.SysUtils.DateTimeToTimeStamp, @DateTimeToTimeStamp);

end.

这将适用于32位代码。如果旧函数和新函数都驻留在同一可执行模块中,则它也适用于64位代码。否则跳跃距离可能超过32位整数的范围。如果您的RTL驻留在运行时包中,它也不会工作。这两个限制都可以很容易地解决。

此代码所做的是将所有对SysUtils.DateTimeToTimeStamp的调用重新路由到此单元中实现的版本。本单元中的代码只是来自XE2源代码的PUREPASCAL版本。

满足您评论中列出的需求的唯一其他方法是修改和重新编译SysUtils单元本身,但我个人避免这种解决方案。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/9255337

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档