3
votes

I am migrating Delphi 7 application to Delphi XE4. DateToStr function is behaving differently in both the versions.

For example:

DateToStr(IncDay(Today, -9)) evaluates to 11/30/2013 in Delphi 7 while 30/11/3013 in Delphi XE4.

It means, Delphi 7 takes date as mm/dd/yyyy while Delphi XE4 takes it as dd/mm/yyyy. Where in Delphi XE4, Can I set it to mm/dd/yyyy?

Note: I don't want to modify the code with formatsettings in each and every place where this conversion has been made. I just want to make this change at one place may be some setting file of Delphi XE4.

1
what's up with the downvote?whosrdaddy
Safest would be to use FormatDateTime('yyyyddmm',TDateTime) explicitly. That way you don't have to rely on formatsettings, which for instance can break your application when it's used in another region. (of FormatDateTime('mm/dd/yyyy',TDateTime) ofcourse, but I have a strong preference for yyyymmdd)Pieter B
@PieterB There is a two parameter overload of DateToStr as wellDavid Heffernan
@DavidHeffernan which will also work. I just don't like relying on global format-settings, so I'm always explicit.Pieter B
@PieterB It depends on what your needs are. If you want to use locale of the user, then it's fine to rely on FormatSettings. That's what they are for. If you want a culture invariant format then obviously you need to be explicit.David Heffernan

1 Answers

8
votes

For both Delphi 7 and Delphi XE4, the one parameter overload of DateToStr uses the global format settings of your application. The XE4 implementation is:

function DateToStr(const DateTime: TDateTime): string;
begin
  Result := DateToStr(DateTime, FormatSettings);
end;

So, it calls the two parameter overload passing the global, shared, FormatSettings variable.

The two parameter overload looks like this:

function DateToStr(const DateTime: TDateTime;
  const AFormatSettings: TFormatSettings): string;
begin
  DateTimeToString(Result, AFormatSettings.ShortDateFormat, DateTime,
    AFormatSettings);
end;

So, the short date format is used.

The Delphi 7 implementation is slightly different, but completely equivalent.

So, the two versions of Delphi do exactly the same thing. They format the date based on the global format settings. And those format settings are initialised from the user's locale settings. From which the only reasonable conclusion is that the difference is not down to the Delphi version but rather because your programs differ.

To be quite clear I am saying that this statement from the question is incorrect:

It means, Delphi 7 takes date as mm/dd/yyyy while Delphi XE4 takes it as dd/mm/yyyy.

Clearly your two programs have different short date formats. You need to work out why the two programs have different short date formats to understand this difference in behaviour. You can check that what I say is correct by running this program on both of the Delphi versions:

{$APPTYPE CONSOLE}

uses
  SysUtils;

begin
  Writeln(DateToStr(Date));
end.

You will discover that programs compiled with any Delphi versions give the same output when run under the same user on the same machine.


Now, you are wanting to call a function to create a human readable date. And you do not want to specify a format. So you have to ask yourself what the program is meant to do. Different people have different preferences for how a date is formatted. This is a regional issue. Americans like to put the month before the day, and the British like the day before the month. And there are many more variations than just these.

When you call the one parameter version of DateToStr the library interprets that as you asking for the date formatted in the preferred way of the current user. Call DateToStr on a vanilla British machine and you will get a different result from that you get when you do so on an American machine.

So, if you want to have a pre-determined format that is always the same irrespective of the user's preferences, then you have to specify that format. You can do so by changing the global FormatSettings variable, or by passing the format to the two parameter variant of DateToStr.

Clearly modifying FormatSettings has a global impact on your application. You need to decide whether or not that is desirable.


The key thing for you to take away from this is that date and time formatting vary from region to region, from machine to machine and from user to user. Unless you take explicit steps otherwise, when you format dates and times, you will have output that depends on the locale of the user that executes the code.