Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Converting a string to TDateTime based on an arbitrary format

Is there any way in Delphi 5 to convert a string to a TDateTime where you can specify the actual format to use?

I'm working on a jobprocessor, which accepts tasks from various workstations. The tasks have a range of parameters, some of which are dates, but (unfortunately, and out of my control) they're passed as strings. Since the jobs can come from different workstations, the actual datetime format used to format the dates as a string might (and, of course, actual do) differ.

Googling around, the only quick solutions I found was to sneakily change the ShortDateFormat variable, and restore it to its original value afterwards. Since ShortDateFormat is a global variable, and I'm working in a threaded environment the only way this would work is by synchronizing every access to it, which is completely unacceptable (and undoable).

I could copy the library code from the SysUtils unit into my own methods, and tweak them to work with a specified format instead of the global variables, but I'm just wondering if there's something more adequate out there that I missed.

UPDATE

To put it more succinctly:

I need something like StrToDate (or StrToDateTime), with the added option of specifying the exact format it should use to convert the string to a TDateTime.

like image 375
Willem van Rumpt Avatar asked Sep 24 '10 12:09

Willem van Rumpt


2 Answers

Use VarToDateTime instead. It supports many more date formats in the string and converts them automatically.

var
  DateVal: TDateTime;
begin
  DateVal := VarToDateTime('23 Sep 2010');
  ShowMessage(DateToStr(DateVal));
end;

I see you're using Delphi 5. Some versions of Delphi will need to add Variants to the uses clause; most later versions add it for you. I don't remember which category Delphi 5 fell into.

like image 159
Ken White Avatar answered Nov 13 '22 03:11

Ken White


I created such routine for FreePascal's dateutils unit, and it should easy to port, if porting is needed at all.

Code:

http://svn.freepascal.org/cgi-bin/viewvc.cgi/trunk/packages/rtl-objpas/src/inc/dateutil.inc?revision=30628&view=co

(code is the last (huge) procedure at the end of the file)

documentation:

http://www.freepascal.org/docs-html/rtl/dateutils/scandatetime.html

Note that it is not a complete inverse of formatdatetime, and it has some extensions:

  • An inverse of FormatDateTime is not 100% an inverse, simply because one can put e.g. time tokens twice in the format string,and scandatetime wouldn't know which time to pick.

  • Strings like hn can't be reversed safely. E.g. 1:2 (2 minutes after 1) delivers 12 which is parsed as 12:00 and then misses chars for the "n" part.

    • trailing characters are ignored.
    • no support for Eastern Asian formatting characters since they are windows only.
    • no MBCS support.
  • Extensions

    • #9 eats whitespace.
    • whitespace at the end of a pattern is optional.
    • ? matches any char.
    • Quote the above chars to really match the char.

(I believe these comments are slightly outdated in the sense hat some Asian support was added later but I am not sure)

like image 8
Marco van de Voort Avatar answered Nov 13 '22 03:11

Marco van de Voort