Solved

String to TDateTime

Posted on 2006-06-29
17
2,367 Views
Last Modified: 2008-01-09
Hi everybody.

I'm trying to convert a date in a TEdit in the format dddd dd mmm yyyyy to a TDateTime and an EConvertError stops the application from running. Anybody knows what I'm doing wrong?

A sample code is hereunder for reference.

-------------------------------------------------------------------------------------------------------------

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;

type
  TForm1 = class(TForm)
    Button1: TButton;
    Edit1: TEdit;
    Label1: TLabel;
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;
  Date: TDateTime;
implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
begin
  TEdit.Text := 'WEDNESDAY 28 JUN 2006';
  Date := StrToDate(Edit1.Text);
  Label1.Caption := FormatDateTime('dddd dd mmm yyyy',Date);
end;

end.

-------------------------------------------------------------------------------------------------------------

Regards
King_Diamond
0
Comment
Question by:King_Diamond
  • 6
  • 5
  • 2
  • +2
17 Comments
 
LVL 10

Expert Comment

by:atul_parmar
ID: 17008719
First, there are some typo.

  TEdit.Text := 'WEDNESDAY 28 JUN 2006'; >> Should be Edit1.Text := .........
  Date := StrToDate(Edit1.Text); >> Date should not be used as variable name. (it's the name of delphi function)

The string you are passing to the StrToDate might not be formatted as current date time format settings. So you need to pass the date time format when you do the conversion.
e.g.

var
  fs : TFormatSettings;
begin
  GetLocaleFormatSettings(LOCALE_SYSTEM_DEFAULT, fs);
  fs.DateSeparator := >> ;
  fs.ShortDateFormat := >>;
 then you can call
  MyDate := StrToDate(Edit1.Text, fs);
end;

But in your case, above will not work. because the StrToDate function uses the ShortDateTime format and the ShortDateTime format can not have the dddd mmm style. so it will fail.

No wonder ;)
0
 

Assisted Solution

by:bjones8888
bjones8888 earned 20 total points
ID: 17008786
StrToDate has two forms.

1  function StrToDate ( const Date : string ) : TDateTime;
2  function StrToDate ( const Date : string; const FormatSettings : TFormatSettings ) : TDateTime;
 
 
The StrToDate function attempts to convert a date as a string Date into a TDateTime value.  The date string must adhere to the format of the ShortDateFormat value, and use the DateSeparator character to separate the day, month and year values.
 
The default format in the US is month/day/year, but most everywhere else is day/month/year.
 
Omitting the year results in the use of the current year.  

I've never tried using a text representation like you have here to convert directly to TDateTime.  I've always had to parse the string based on location of spaces, and create my own functions, like:


procedure TForm1.Button1Click(Sender: TObject);
begin
  TEdit.Text := 'WEDNESDAY 28 JUN 2006';
  Date := MyStrToDate(Edit1.Text);
  Label1.Caption := FormatDateTime('dddd dd mmm yyyy',Date);
end;

function TForm1.MyStrToDate(sDate: string): TDateTime;
var
  s: string;
  sDayNum, sMonth, sMonthNum, sYear: string;
  iPos: integer;
begin
  s := sDate;

  // Get day
  iPos := Pos(" ", s);
  s := Copy(s, iPos + 1, length(s));     // trims off the day name - not needed
  iPos := Pos(" ", s);
  sDayNum := RTrim(Copy(s, 1, iPos));

  // Get month
  s := Copy(s, iPos + 1, length(s));     // trims off the day number - no longer needed
  iPos := Pos(" ", s);
  sMonth := Uppercase(RTrim(Copy(s, 1, iPos)));
  if sMonth = 'JAN' then
    sMonthNum = 1
  else if sMonth = 'FEB' then
    sMonthNum = 2
  else if ....
  else
    sMonthNum = 12;

  // Get year
  s := LTrim(RTrim(Copy(s, iPos + 1, length(s))));     // trims off the month - only year remains
  result := StrToDate(sDayNum + '/' + sMonthNum + '/' + s);
end;
0
 
LVL 15

Expert Comment

by:mikelittlewood
ID: 17008810
What I don't understand is why you are converting the date at all if you are going to display it in the same format in the label as before.
Im assuming you are only doing this as an example to show your problem otherwise you would just equate the label and the edit.

Label1.Caption := Edit1.Text;



procedure TForm1.Button1Click(Sender: TObject);
var
  dDate: TDate;
begin
  Edit1.Text := 'WEDNESDAY 28 JUN 2006';
  Date := StrToDate(Edit1.Text);
  Label1.Caption := FormatDateTime('dddd dd mmm yyyy',Date);
end;

atul_parmar is right you cant use the dddd or mmm long format dates and convert these.
You would have to convert it first to something like 28/06/2006
0
 
LVL 1

Author Comment

by:King_Diamond
ID: 17008833
Thanks for the explanation and sorry for the typing.

I wondered it was something like you are saying as I tried it with a shortdate (28/06/2006) and it worked. Is it possible to convert a longdate string to a TDateTime? A function like StrToDate perhaps?
0
 
LVL 10

Expert Comment

by:atul_parmar
ID: 17008851
If you want to do that you will have to write your own routine. With standard Delphi routines you can not do it.
0
 
LVL 1

Author Comment

by:King_Diamond
ID: 17009013
Thanks to everyone for your help.

Can anyone help me with the routine to achieve this? I will increase the points by another 100 if anyone can give me the code.

bjones8888,
I tried to use your function but I have problems running it. Compiler saying undeclared identifier for RTrim. I don't know what this is. Sorry but I'm no delphi expert.

mikelittlewood,
Yes it's an example to identify what was happening. I need this date to compare it to the current date.

Any help is much appreciated.
0
 
LVL 15

Accepted Solution

by:
mikelittlewood earned 100 total points
ID: 17009016
Here is a quick function to change the long date string to a short date string useable for converting to a date

function TForm1.LongDateToShort(sDate: String): String;
var
  i: Integer;
  sl: TStringList;
  sMon: string;
begin
  try
    // split out the long string (assume always same format)
    sl := TStringList.Create;
    sl.Delimiter := ' ';
    sl.DelimitedText := sDate;
    // loop through locale short month names and find index
    for i := 1 to 12 do
      if Uppercase(ShortMonthNames[i]) = Uppercase(sl.Strings[2]) then Break;
    // correct format
    sMon := IntToStr(i);
    if Length(sMon) = 1 then
      sMon := '0' + sMon;
    // rebuild date string
    Result := Trim( sl.Strings[1] + '/' + sMon + '/' + sl.Strings[3] );
  finally
    FreeAndNil(sl)
  end;
end;
0
 
LVL 15

Expert Comment

by:mikelittlewood
ID: 17009020
You would use it like

procedure TForm1.Button1Click(Sender: TObject);
var
  s: string;
begin
  Edit1.Text := 'WEDNESDAY 28 JUN 2006';
  s:= LongDateToShort(Edit1.Text);
  Label1.Caption := FormatDateTime('dddd dd mmm yyyy', StrToDate(s));
end;
0
How to run any project with ease

Manage projects of all sizes how you want. Great for personal to-do lists, project milestones, team priorities and launch plans.
- Combine task lists, docs, spreadsheets, and chat in one
- View and edit from mobile/offline
- Cut down on emails

 

Expert Comment

by:bjones8888
ID: 17009106
My bad on the RTrim function.  I use so many programs.  RTrim is SQL format.  In Delphi just use Trim( ).
0
 
LVL 1

Author Comment

by:King_Diamond
ID: 17009253
mikelittlewood,

Thanks. Your function works fine. I just want to trap the EStringListError but I don't know where to put the ' except on E: EStringListError do ShowMessage (E.Message);' within your function. Can you help please?
0
 
LVL 26

Expert Comment

by:EddieShipman
ID: 17009576
First, on MikeLittlewood's post, the try should be AFTER the sl := TStringList.Create;
and to add the exception handler, you should add another try right after the first one
and the except block before the finally block.
0
 
LVL 26

Assisted Solution

by:EddieShipman
EddieShipman earned 30 total points
ID: 17009589
Like this:

function TForm1.LongDateToShort(sDate: String): String;
var
  i: Integer;
  sl: TStringList;
  sMon: string;
begin
  // split out the long string (assume always same format)
  sl := TStringList.Create;
    try try
    sl.Delimiter := ' ';
    sl.DelimitedText := sDate;
    // loop through locale short month names and find index
    for i := 1 to 12 do
      if Uppercase(ShortMonthNames[i]) = Uppercase(sl.Strings[2]) then Break;
    // correct format
    sMon := IntToStr(i);
    if Length(sMon) = 1 then
      sMon := '0' + sMon;
    // rebuild date string
    Result := Trim( sl.Strings[1] + '/' + sMon + '/' + sl.Strings[3] );
    except
      on E: EStringListError do
        ShowMessage (E.Message);
    end;
  finally
    FreeAndNil(sl)
  end;
end;
0
 
LVL 15

Expert Comment

by:mikelittlewood
ID: 17009733
oops .. honestly I usually do it your way Eddie! he he
Don't know WHAT came over me  :o)
0
 
LVL 1

Author Comment

by:King_Diamond
ID: 17009887
Eddie, Mike

I tried your code but the except is not tapping the error!

I was also testing different date formats and would like to add the EConvertError as well.

Can you help please?
0
 
LVL 15

Expert Comment

by:mikelittlewood
ID: 17010149
How are you trying to generate the stringlist error?
In theory the code should not generate one.

As for adding another error just extend the except block

    except
      on E: EStringListError do
        ShowMessage (E.Message);
      on E: EConvertError do
        ShowMessage (E.Message);
    end;
0
 
LVL 1

Author Comment

by:King_Diamond
ID: 17010508
mikelittlewood,

The date should always have the same format but as I'm using the date from third parties, I don't know if the date format will change. Hence, since I want the application to continue running in the case the date format is changed, I'm trying to trap any possible errors due to possible different date formats.

However, the exceptions highlighted by you and Eddie are not trapping the errors. I had tried what you mentioned but the error continued popping up so I thought that I was doing something wrong. The error is still popping up and is terminating the application and not popping up the dialog box.
0
 
LVL 1

Author Comment

by:King_Diamond
ID: 17010843
Problem solved. I had a typing error.

Thanks to everyone.
0

Featured Post

What Should I Do With This Threat Intelligence?

Are you wondering if you actually need threat intelligence? The answer is yes. We explain the basics for creating useful threat intelligence.

Join & Write a Comment

The uses clause is one of those things that just tends to grow and grow. Most of the time this is in the main form, as it's from this form that all others are called. If you have a big application (including many forms), the uses clause in the in…
Introduction I have seen many questions in this Delphi topic area where queries in threads are needed or suggested. I know bumped into a similar need. This article will address some of the concepts when dealing with a multithreaded delphi database…
Illustrator's Shape Builder tool will let you combine shapes visually and interactively. This video shows the Mac version, but the tool works the same way in Windows. To follow along with this video, you can draw your own shapes or download the file…
This video shows how to remove a single email address from the Outlook 2010 Auto Suggestion memory. NOTE: For Outlook 2016 and 2013 perform the exact same steps. Open a new email: Click the New email button in Outlook. Start typing the address: …

760 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

24 Experts available now in Live!

Get 1:1 Help Now