如何在Delphi中将字符串转换为日期时间(非英语)

如何在Delphi中将字符串转换为日期时间(非英语),delphi,Delphi,我无法将字符串格式日期(法语)转换为TDateTime格式。我正在处理包含英语和其他语言字符串格式日期的文件 例如,2021年3月1日的英文文件为1 mars 2021,法文文件为1 mars 2021 var _标准日期:字符串; _MyDateTime:TDateTime; 开始 _标准日期:=“2021年3月1日”;//英语 _MyDateTime:=VarToDateTime(_StrDate);//完美 _标准日期:='1 mars 2021';//法语 _MyDateTime:=Va

我无法将字符串格式日期(法语)转换为
TDateTime
格式。我正在处理包含英语和其他语言字符串格式日期的文件

例如,2021年3月1日的英文文件为
1 mars 2021
,法文文件为
1 mars 2021

var
_标准日期:字符串;
_MyDateTime:TDateTime;
开始
_标准日期:=“2021年3月1日”;//英语
_MyDateTime:=VarToDateTime(_StrDate);//完美
_标准日期:='1 mars 2021';//法语
_MyDateTime:=VarToDateTime(_StrDate);//错误
结束;
我收到这个错误消息:

无法将类型(Unicode Destring)的变量转换为类型(日期)


我为您的特定格式编写了一个解析器。嗯,我已经完成了基本的工作,你必须修改它,例如,使用法语和英语的月份名称以及短名称。您还应该添加一些测试来过滤无效值。而且可能会以月份的名义忽略字符大小写

const
    MonthsFR : array [1..12] of String = (
        'janvier', 'février', 'mars', 'avril', 'mai', 'juin', 'juillet',
        'août', 'septembre', 'octobre', 'novembre', 'décembre');

function StrToDateFR(const S : String; out ADate : TDateTime) : Boolean;
var
    A : TStringDynArray;
    D : Word;
    M : Word;
    Y : Word;
begin
    ADate  := 0;
    Result := FALSE;
    A := SplitString(S, ' ');
    if Length(A) <> 3 then
        Exit;
    D := StrToInt(A[0]);
    M := High(MonthsFR);
    while (M > Low(MonthsFR)) and (A[1] <> MonthsFR[M]) do
        Dec(M);
    if M < Low(MonthsFR) then
        Exit;
    Y := StrToInt(A[2]);

    ADate  := EncodeDate(Y, M, D);
    Result := TRUE;
end;
const
MonthsFR:字符串的数组[1..12](
“janvier”、“février”、“mars”、“avril”、“mai”、“juin”、“juillet”,
‘aoāt’、‘septembre’、‘octobre’、‘novenbre’、‘décembre’;
函数StrToDateFR(常量S:String;out-ADate:TDateTime):布尔值;
变量
A:TStringDynArray;
D:单词;
M:字;
Y:单词;
开始
ADate:=0;
结果:=假;
A:=拆分字符串,';
如果长度(A)为3,则
出口
D:=stroint(A[0]);
M:=高(月数);
而(M>Low(MonthsFR))和(A[1]MonthsFR[M])则
12月(M);
如果M<低(月数),则
出口
Y:=stroint(A[2]);
日期:=编码日期(Y,M,D);
结果:=真;
结束;
扩展代码的一个想法是为其他语言提供几个类似的函数。由于函数仅在识别格式时返回TRUE,因此您可以依次调用各种版本,直到其中一个返回TRUE。

函数strodatefr(const S:String;out ADate:TDateTime):Boolean;
function StrToDateFR(const S: String; out ADate: TDateTime): Boolean;
var

  A: TStringDynArray;
  D: Word;
  M: Word;
  Y: Word;
  i: integer;

begin

  ADate := 0;
  Result := FALSE;
 A := SplitString(S, ' ');
 if Length(A) <> 3 then
    Exit;
  D := StrToInt(A[0]);
  M := 0;

  for i := Low(MonthsFR) to High(MonthsFR) do
  begin
    if SameText(A[1], MonthsFR[i]) then
    begin
      M := i;
      Break
    end;
  end;

  if M = 0 then
    Exit;
  Y := StrToInt(A[2]);

 ADate := EncodeDate(Y, M, D);
 Result := TRUE;

end;
变量 A:TStringDynArray; D:单词; M:字; Y:单词; i:整数; 开始 ADate:=0; 结果:=假; A:=拆分字符串,'; 如果长度(A)为3,则 出口 D:=stroint(A[0]); M:=0; 对于i:=低(月)至高(月)do 开始 如果SameText(A[1],MonthsFR[i]),则 开始 M:=i; 打破 结束; 结束; 如果M=0,则 出口 Y:=stroint(A[2]); 日期:=编码日期(Y,M,D); 结果:=真; 结束;
为您的特定格式编写一个解析器。使用设置为法语的库语言编译您的程序可能会有所帮助。欢迎使用日期和时间格式地狱。恐怕您必须为此编写自己的解析器。据我所知,没有人能够理解所有甚至许多格式,特别是因为它们是模棱两可的。你至少知道每个字符串使用哪种格式,这样你就不需要猜测了吗?如果你不知道文件中的日期格式,甚至如果每个文件可以包含不同的格式,那你就倒霉了。要破译日期是不可能的。例如,“20/06/21”可能是去年的2020-06-21或今年的2021-06-20。更糟糕的是,“20/06/05”可能是去年的2020-06-05、大约16年前的2005-06-20、去年的2020-05-06或大约15年前的2006-05-20。您是否尝试将默认formatsettings设置为使用“French”:
formatsettings:=TFormatSettings.Create(1036)。您的答案很有用,我修改了您复制了我的答案,将while循环替换为for循环。您应该删除您自己问题的答案,并将我的答案标记为已接受。您的答案已接受,但区别在于当我们传递值“10 avril 2021”时,回报将为10/12/2021。但在修改的部分M:=i;将给出月份部分,因此答案将为2021年4月10日。谢谢,while状态中还有一个“not”。现在移除。谢谢