首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >格式为mmm/yy的TryStrToDate失败

格式为mmm/yy的TryStrToDate失败
EN

Stack Overflow用户
提问于 2017-02-01 07:23:14
回答 2查看 1.1K关注 0票数 2

我试图使用TDateTime函数将mmm/yy格式的字符串转换为TryStrToDate。然而,它似乎总是失败。

我创建格式设置记录,并设置日期分隔符和短日期格式。我设置了长日期格式,以显示问题发生,无论我设置短日期格式还是长日期格式。

如果我将示例更改为使用dd/mm/yyyy,并在2017年02月1日通过,那么它就成功了,所以我相信这个问题可能是格式。我使用下面的链接作为引用来创建格式字符串

http://www.delphibasics.co.uk/RTL.asp?Name=formatdatetime

我制作了一个演示控制台应用程序来展示我想要做的事情。

代码语言:javascript
运行
复制
uses
   System.SysUtils;

function ValidateDate(ADate: string): boolean;
var
    fs: TFormatSettings;
    DateTime: TDateTime;
begin
    fs := TFormatSettings.Create();
    fs.DateSeparator := '/';
    fs.ShortDateFormat := 'mmm/yy';
    fs.LongDateFormat := 'mmm/yy';

    result := true;
    if not TryStrToDate(ADate, DateTime, fs) then
        result := false;
end;

begin
    try
        if not ValidateDate('Oct/16') then
            WriteLn('Failed to convert')
    except
        on E: Exception do
            Writeln(E.ClassName, ': ', E.Message);
    end;
end.

我想知道为什么这样做失败了

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2017-02-03 02:12:56

根据David的建议,我创建了一个函数,该函数将把字符串ie Jan转换为01,然后调用TryStrToDate来获取转换日期。如果格式字符串不包含一天,则默认为01。

代码语言:javascript
运行
复制
function ParseDate(ADate: string; AFormatSettings: TFormatSettings): TDateTime;
var
    DateData, FormatData: TStringList;
    Month, Day, Year: string;
    ConvertedDate: Double;
    i: integer;

    function ConvertMonth(AMonth: string; ALongMonth: boolean = false): string;
    var
        i: integer;
    begin
        Result := '-1'; // default to invalid month
        if ALongMonth then
        begin
            for i := 1 to high(AFormatSettings.LongMonthNames) do
            begin
                if AFormatSettings.LongMonthNames[i] = AMonth then
                begin
                    Result := inttostr(i); // MonthArray starts at index 1 which matches the month
                    break;
                end;
            end;
        end
        else
        begin
            for i := 1 to high(AFormatSettings.ShortMonthNames) do
            begin
                if AFormatSettings.ShortMonthNames[i] = AMonth then
                begin
                    Result := inttostr(i); // MonthArray starts at index 1 which matches the month
                    break;
                end;
            end;
        end;
    end;
begin
    DateData := TStringList.Create();
    FormatData := TStringList.Create();
    try
        DateData.Delimiter := AFormatSettings.DateSeparator;
        DateData.StrictDelimiter := true;
        DateData.DelimitedText := ADate;

        FormatData.Delimiter := AFormatSettings.DateSeparator;
        FormatData.StrictDelimiter := true;
        FormatData.DelimitedText := AFormatSettings.ShortDateFormat;

        Day := '01';
        Month := '01';
        Year := '01';

        for i := 0 to FormatData.Count - 1 do
        begin
            if FormatData[i].IndexOf('d') <> -1 then
                Day := DateData[i]
            else if FormatData[i].IndexOf('m') <> -1 then
            begin
                if FormatData[i] = 'mmm' then
                    Month := ConvertMonth(DateData[i])
                else if FormatData[i] = 'mmmm' then
                    Month := ConvertMonth(DateData[i], true)
                else
                    Month := DateData[i]
            end
            else if FormatData[i].IndexOf('y') <> -1 then
                Year := DateData[i]
        end;

        ADate := Day + AFormatSettings.DateSeparator + Month + AFormatSettings.DateSeparator + Year;

        AFormatSettings.ShortDateFormat := 'dd' + AFormatSettings.DateSeparator + 'mm' + AFormatSettings.DateSeparator + 'yyyy';
        TryStrToDate(ADate, Result, AFormatSettings);
    finally
        DateData.free();
        FormatData.free();
    end;
end;

如果有人能看到任何改进或优化,请告诉我。

票数 -1
EN

Stack Overflow用户

发布于 2017-02-01 07:27:50

格式字符串无效。这些格式字符串必须编码日、月和年。你省略了不允许的一天。

您为转换提供的字符串允许省略年份。在这种情况下,假定是本年度。

如果希望将这些字符串转换为仅几个月和一年,那么在传递给TryStrToDate的字符串中包含一个假的日期,例如1。然后使用DecodeDate获取月份和年份的数值,忽略日期。

因此,使用'd/mmm/yy'作为格式,传递'1/' + ADate作为要转换的字符串。

还请注意,用于将字符串转换为date的是短日期字符串格式,因此这是您需要设置的唯一格式。

最后,这是一种非常简单的格式,您可以很容易地直接解析它。

更新

正如您在注释中所看到的,RTL功能是通过调用ScanDate实现的,它只支持数字月份格式。因此,不幸的是,你所尝试的整个方法注定要失败。即使你解决了我发现的问题。

我的建议是自己简单地解析字符串,因为它的格式非常简单。

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

https://stackoverflow.com/questions/41974096

复制
相关文章

相似问题

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