Delphi-7:将格式为yyyymmdd(没有分隔符)的字符串转换为DateTime对象

3

我正在使用Delphi7

我的日期格式设置为yyyymmdd(可以不带分隔符使用任何日期格式)。当我尝试使用StrToDate('20170901')时,它会抛出错误。

我想支持所有有效的日期格式(不同客户端在不同区域可能使用不同格式)。

我已经尝试过VarToDateTime,但也无法正常工作。

如果对于DateToStr()也有相同的问题,请也指导一下我。


@LURD:我的错误,我已经更新了细节。如果可能的话,请删除负面评分,这样我至少可以得到我的解决方案。提前致谢。 - Pratik Soni
1
你很困惑。你只问了一个特定的格式,没有提到区域设置。你需要明确你尝试做什么,数据来自哪里等。 - David Heffernan
5
那么,02/04/2017是什么意思?是2月4日还是4月2日?那么 20112004 又是什么意思?是2011年4月20日还是2004年11月20日呢?你不可能处理所有的日期格式。你可以处理已知的格式,也可以根据用户环境和本地化来处理格式,但是不可能处理所有可能的格式 - 总会有多个可用的解释。 - J...
3
第一步是尝试理解输入数据的来源。在回答问题之前,我们甚至需要弄清楚问题是什么。这是初学者常犯的错误,他们在理解问题之前就开始编码了。您必须先停下来,深入了解问题。 - David Heffernan
1
最好使用标准化的日期格式,不受任何特定区域格式的限制,例如ISO 8601 - Remy Lebeau
显示剩余4条评论
2个回答

8

您之所以出现错误,是因为您的输入字符串与您机器的日期/时间格式设置不匹配。

通常情况下,我建议您使用SysUtils单元中的StrToDate()函数,在此之前设置其全局变量ShortDateFormatDateSeparator,然后在恢复它们(Delphi 7之前没有引入TFormatSettings记录),例如:

uses
  ..., SysUtils;

var
  OldShortDateFormat: string;
  OldDateSeparator: Char;
  input: string;
  dt: TDateTime;
begin
  input := ...;

  OldShortDateFormat := ShortDateFormat;
  OldDateSeparator := DateSeparator;
  ShortDateFormat := 'yyyymmdd'; // or whatever format you need...
  DateSeparator := '/'; // or whatever you need
  try
    dt := StrToDate(input);
  finally
    ShortDateFormat := OldShortDateFormat;
    DateSeparator := OldDateSeparator;
  end;

  // use dt as needed...
end;

很遗憾,StrToDate()函数要求输入字符串在日期元素之间有分隔符(如2017/09/01),但您的输入字符串没有分隔符(20170901)。即使ShortDateFormat格式中未指定分隔符,StrToDate()也不允许将 DateSeparator设置为#0

因此只有一种选择-手动解析字符串以提取各个组件,然后使用SysUtils单元中的EncodeDate()函数进行编码,例如:

uses
  ..., SysUtils;

var
  wYear, wMonth, wDay: Word;
  input: string;
  dt: TDateTime;
begin
  input := ...;

  wYear := StrToInt(Copy(input, 1, 4));
  wMonth := StrToInt(Copy(input, 5, 2));
  wDay := StrToInt(Copy(input, 7, 2));
  // or in whatever order you need...

  dt := EncodeDate(wYear, wMonth, wDay);

  // use dt as needed...
end;

DateToStr() 函数同样受到区域设置的影响。然而,它允许在输出中省略 DateSeparator。因此,您可以选择:

  1. use DateToStr(), setting the global ShortDateFormat variable to the desired format:

    uses
      ..., SysUtils;
    
    var
      OldShortDateFormat: string;
      dt: TDateTime;
      output: string;
    begin
      dt := ...;
    
      OldShortDateFormat := ShortDateFormat;
      ShortDateFormat := 'yyyymmdd'; // or whatever format you need...
      try
        output := DateToStr(dt);
      finally
        ShortDateFormat := OldShortDateFormat;
      end;
    
      // use output as needed...
    end;
    
  2. extract the individual date components from the TDateTime using the DecodeDate() function in the SysUtils unit, and then format your own string with the year/month/day values however you want:

    uses
      ..., SysUtils;
    
    var
      wYear, wMonth, wDay: Word;
      dt: TDateTime;
      output: string;
    begin
      dt := ...;
    
      DecodeDate(dt, wYear, wMonth, wDay);
      output := Format('%.4d%.2d%.2d', [wYear, wMonth, wDay]);
    
      // use output as needed...
    end;
    

第二种方法非常好。 - WellingtonD

5

要将该字符串转换为 TDateTime,请将字符串拆分为年、月和日组件,并将它们传递给 EncodeDate() 函数。

var
  myStr: string;
  myDate: TDate;
begin
  myStr := '20170901';
  myDate := EncodeDate(
    StrToInt(Copy(MyStr, 1, 4)),
    StrToInt(Copy(MyStr, 5, 2)),
    StrToInt(Copy(MyStr, 7, 2))
  );
  ...
end;

很遗憾,您忽略了字符串的基于1的索引。而且不使用变量来存储字符串是不够强大的。最后,提问者想做的事情远不止这些,但问题不清楚。 - David Heffernan
2
这只是一个解决他问题的建议,当然他可以应用最佳实践。我很实际。 - WellingtonD
你忽略了我评论中的细节。 - David Heffernan

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接