【问题标题】:How to change the system shortdatetime format using delphi xe3如何使用delphi xe3更改系统短日期时间格式
【发布时间】:2014-02-18 11:31:14
【问题描述】:

我会尽量让问题尽可能简单。

我如何将系统日期转换为我想要的格式,并且仍然将其保留为日期而不是字符串。 或者我如何获取系统的日期格式,以相应地调整我的日期。

当我打电话时

FormatShortdateTime('d/M/yyyy',Date);

我得到正确的日期作为字符串,但无法将其转换回 Tdate 并使用它,然后它与系统日期设置冲突。

如果我能得到系统短日期格式,问题就解决了。

【问题讨论】:

  • 可以通过FormatSettings变量访问,所以写成FormatSettings.ShortDateFormat := ...。此外,根据本地设置更改全局配置解决了哪些问题?我想可能有一个解决方案而不是解决方法。
  • 这听起来不像是解决任何问题的方法
  • @TLama 我试过 FormatSettings.ShortDateFormat:='d/M/yyyy';比较日期时仍然出现错误:“18/2/2014”不是有效日期。我比较了很多不同的日期格式,基本上可以是任何格式,希望我的软件基本上将所有日期转换为 1 种常量格式。最好不要更改系统日期,但如有必要我会更改系统日期格式
  • 最好是声明一个保存全局格式设置的变量并将此格式传递给所有格式化函数。但是,我无法解释您为什么“遇到错误”,至少因为我不知道上下文也不知道您遇到的错误。
  • 问题是我的系统日期,它是 d-M-yyyy。所以 datetostr 和 strtodate 不断报错

标签: delphi date


【解决方案1】:

更新

下面的答案是指您提出的原始问题。您现在已经多次编辑问题以提出不同的问题。你真的不应该这样做,这表明你应该在提问之前花更多的时间来理解问题。

即便如此,答案的最后一部分,可能仍然包含您需要的建议。即停止使用依赖于全局FormatSettings 变量的转换函数,始终使用以格式设置作为参数传递的转换函数。


您数据库中的日期值未以您期望的格式存储。这个程序:

{$APPTYPE CONSOLE}

uses
  System.SysUtils;

var
  fs: TFormatSettings;
begin
  fs := TFormatSettings.Create;
  fs.ShortDateFormat := 'd/M/yyyy';
  Writeln(DateToStr(StrToDate('18/2/2014', fs)));
end.

在我的机器上产生以下输出:

18/02/2014

我猜在您的机器上它会产生不同的输出,因为您的短日期格式与我的不同。但关键是对StrToDate 的调用成功了。

很明显,存储在您的数据库中的值不是您声称的形式。因为您声称上述代码会导致调用StrToDate时出现日期转换错误。


让我们退后一步,看看你问题的开头部分:

我想知道如何在不让系统日期影响软件的情况下转换日期。

上面答案中的代码为您提供了如何执行此操作的示例。现代版本的 Delphi 重载了日期和时间转换功能。有接受TFormatSettings 参数的重载,也有没有这样参数的重载。 TFormatSettings 参数用于控制用于转换的格式。不接收此类参数的重载使用SysUtils 单元中声明的全局FormatSettings 实例。

为了避免系统设置影响您的转换,您应该只使用接受格式设置参数的转换函数。

另一方面,如果您希望系统设置影响您的转换,请随意调用使用全局格式设置变量的重载。

我上面的代码说明了两者。从字符串到日期的转换需要固定格式,不随本地系统设置而变化。从日期到字符串的转换旨在使用流行的本地系统设置显示日期。

【讨论】:

  • if (StrToDate(Datalive.users.Fieldbyname('last_backup').AsString))
  • 该评论对我来说完全不透明。您声称您的日期以'18/2/2014' 的格式存储在数据库中。而且,当您使用 StrToDate'd/M/yyyy' 的短日期格式时,对 StrToDate 的调用将失败。鉴于这些信息,我的结论是数据库中的字符串不是您认为的格式。或者,也许你读错了。或者您告诉我们的信息可能完全错误。
  • 好的,让我试着说清楚。我需要将从系统获得的日期转换为我使用的日期格式。并将其保留为日期而不是字符串。如果我调用 formatdatetime('d/M/yyyy',Date),我会得到正确的字符串格式,但是如果我说 Strtodate(formatdatetime('d/M/yyyy',Date)),那就是当我得到错误。理解?我可以将其转换为正确格式的字符串,尝试将其用作日期,给我错误
  • 不在 cmets 中。您需要做的是在问题中给我们一个 SSCCE。回到我之前的评论,请你解决我提出的观点。 您声称您的日期以'18/2/2014' 的格式存储在数据库中。而且当您使用StrToDate'd/M/yyyy' 的短日期格式时,对StrToDate 的调用会失败。 我的回答表明您的声明不正确,并且您不了解问题并且不要不知道你在处理什么价值观。下一步是进行一些调试。然后提供明确的 SSCCE。
  • 我知道最初的问题,但我努力适应你的方法失败了。当我尝试 StrToDate(FormatShortdate('d/M/yyyy',Date)) 时,我的系统格式是 d-M-yyyy。系统设置和我的冲突。那么你知道如何获取系统日期设置吗?我可以左右摆动,适应系统。
【解决方案2】:

我建议创建自己的 TFormatSettings 变量

旧的 delphi 版本

var
  fs: TFormatSettings;
begin
  fs := TFormatSettings.Create;
  GetLocaleFormatSettings(LOCALE_SYSTEM_DEFAULT, fs);
end.

这将创建您自己的 formatSettings(填充系统格式),因此您不会更改默认设置。

现在重要的是 shortDateFormat 中的 '/' 将被 dateSeparator 替换,所以如果你这样做

fs.ShortDateFormat:='M/d/yyyy';
fs.dateSeparator:='?';

你的输入应该是这样的

strtodate('12?30?1899', fs);

或者如果你以其他方式结束你的字符串:'12?30?1899';

我认为您的问题源于您没有询问使用了什么 dateSeparator。如果程序期望的是“30-12-1899”,但他从您那里得到“30/12/1899”,那将导致问题。

【讨论】:

  • 我想知道为什么我被否决了......我会很高兴知道我错在哪里。