Sign in Join

Live chat for Free Pascal, Lazarus, Delphi and every Pascal programmer.

Mailing lists / fpc-pascal / 2023-04

How to use StrToDateTime() to convert a string with no delimiters?

4 messages · 3 people · –

Reply by email Subscribe to this list Your subscription

Read-only archive. Use j and k to move between messages.

Bo Berglund

I have a device that sends data over the serial port with a timestamp in this format:

(230424194642W)

This is coded as yymmddhhnnss and the last char designates daylight savings (S)ummer or normal (W)inter time. In the example above it is W for normal winter time.

What I have done so far is:
- Remove the () at start and end
- Remove the W at the end
- Add 20 (as the century) up front
- Insert a space after the 6th char (so between date and time
- Set the TFormatsettings like this (to say that there are no separators):

  FS.DateSeparator := #0; (Is this how it is done?)
  FS.TimeSeparator := #0;

- Then the call:

  Value := StrToDateTime(sValue, FS); (Value is declared as TDateTime)

This triggers an exception with the message:
"194522" is not a valid time

What is the proper way to decode a string as shown above? Since the date part could be decoded, why not also the time part, after all I separated the two with a space and set the same separators?

Bo Berglund Developer in Sweden
Thomas Kurz
to Bo Berglund

I always use ScanDateTime for such purposes:

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

You can explicitly define the pattern.

Earlier message 38 lines
----- Original Message ----- From: Bo Berglund via fpc-pascal To: Sent: Monday, April 24, 2023, 20:08:01 Subject: [fpc-pascal] How to use StrToDateTime() to convert a string with no delimiters? I have a device that sends data over the serial port with a timestamp in this format: (230424194642W) This is coded as yymmddhhnnss and the last char designates daylight savings (S)ummer or normal (W)inter time. In the example above it is W for normal winter time. What I have done so far is: - Remove the () at start and end - Remove the W at the end - Add 20 (as the century) up front - Insert a space after the 6th char (so between date and time - Set the TFormatsettings like this (to say that there are no separators): FS.DateSeparator := #0; (Is this how it is done?) FS.TimeSeparator := #0; - Then the call: Value := StrToDateTime(sValue, FS); (Value is declared as TDateTime) This triggers an exception with the message: "194522" is not a valid time What is the proper way to decode a string as shown above? Since the date part could be decoded, why not also the time part, after all I separated the two with a space and set the same separators? -- Bo Berglund Developer in Sweden
Bo Berglund
to Michael Van Canneyt
Michael Van Canneyt wrote 15 lines
On Mon, 24 Apr 2023, Thomas Kurz via fpc-pascal wrote: > I always use ScanDateTime for such purposes: > > https://www.freepascal.org/docs-html/rtl/dateutils/scandatetime.html > > You can explicitly define the pattern. Correct. This is the only correct way to do this. StrToDateTime is very limited in what it accepts. Michael.

Thanks, I did not know about this before, but now it is inserted in my code and works fine. :-)

So now I can just specify the pattern of data to be scanned using the y, m, h, n and s letters.
But I am adding 20 on front of the telegram value because that uses only a 2-digit year and I had problems on my new RPiZero until I added the two yy in front of the pattern making it a 4-char year and the 20 in front of the telegram.

Then all works fine.

Bo Berglund Developer in Sweden