Many thanks Angus and Michael. In the end I decided to use the code
from OverbyteIcsSmtpSrv.pas.
In order to understand how it worked (I'd not seen the secret TParser class
before) I decided to translate the code into C++. The constructor for
TParser is slightly different (requires 2 parameters), but otherwise the
code is the same. I've copied the code below in the hope that it might be
of use someone else who stumbles across this when googling for a C++
solution.

Thanks again,

Richard

//---------------------------------------------------------------------------
bool __fastcall Utilities::GetMonth(TParser* Parser, int& Month)
{
UnicodeString Months[] = {"Jan", "Feb", "Mar", "Apr",
  "May", "Jun", "Jul", "Aug",
  "Sep", "Oct", "Nov", "Dec", ""};
Month = 1;
while(!Parser->TokenSymbolIs(Months[Month - 1]) && Month < 13)
++Month;

return Month < 13;
}
//---------------------------------------------------------------------------
void __fastcall Utilities::GetTime(TParser* Parser, int& Hour, int& Min,
int& Sec)
{
Hour = Parser->TokenInt();
Parser->NextToken();
if(Parser->Token == ':')
Parser->NextToken();

Min = Parser->TokenInt();
Parser->NextToken();

if(Parser->Token == ':')   // Angus, allow missing seconds
{
Parser->NextToken();
Sec = Parser->TokenInt();
Parser->NextToken();
}
}
//---------------------------------------------------------------------------
bool __fastcall Utilities::ParseRFC822Date (UnicodeString DateStr,
TDateTime& DateTime, UnicodeString& ErrorMessage)
{
if(!DateStr.Length())
{
ErrorMessage = "Zero length date string.";
return false;
}

// Add a fictitious day name if one is missing from the start of the string
- courtesy of Angus
if(DateStr[1] >= '0' && DateStr[1] <= '9')
DateStr = "Sun, " + DateStr;

TParser* Parser;
TStringStream* StringStream;

try
{
try
{
StringStream = new TStringStream(DateStr);

// Create a NULL TParserErrorEvent object to pass into the TParser
constructor.
// TParser will still generate an exception on error.
TParserErrorEvent p = NULL;
Parser = new TParser(StringStream, p);

Parser->NextToken();

if(Parser->Token == ':')
Parser->NextToken();

Parser->NextToken();

if(Parser->Token == ',')
Parser->NextToken();

int Month, Day, Year, Hour, Min, Sec;

if(GetMonth(Parser, Month))
{
Parser->NextToken();
Day = Parser->TokenInt();
Parser->NextToken();
GetTime(Parser, Hour, Min, Sec);
Year = Parser->TokenInt();
}
else
{
Day = Parser->TokenInt();
Parser->NextToken();
if(Parser->Token == '-')
Parser->NextToken();
GetMonth(Parser, Month);
Parser->NextToken();
if(Parser->Token == '-')
Parser->NextToken();
Year = Parser->TokenInt();

if(Year < 50)
Year += 2000;
if(Year < 100)
Year += 1900;

Parser->NextToken();

GetTime(Parser, Hour, Min, Sec);
}

TDateTime temptime;
if( TryEncodeDate (Year, Month, Day, DateTime))
if( TryEncodeTime (Hour, Min, Sec, 0, temptime))
DateTime = DateTime + temptime ;
}
catch(Exception& e)
{
ErrorMessage = e.Message;
return false;
}
}
__finally
{
delete StringStream;
delete Parser;
}

return true;
}
//---------------------------------------------------------------------------


On 30 January 2014 17:18, Michael Gasser <michael_gas...@bluewin.ch> wrote:

>
>
> Hi Richard
>
>
> maybe you should check the "user made" component LASTMOD.ZIP from
> http://www.overbyte.be/frame_index.html?redirTo=/products/usermade.html
>
> _______________________________________________________________
>
> I use this code in two programs.
>
> My programs did send me some error feedback while parsing 'LAST-MODIFIED:'
> (html downloads with ICS HttpCli) with the "inet component" above (5
> errors, ~>500'000 downloads).
>
> Therefore I had to slightly modify the code:
> Two modifications - see 1., 3.
> _______________________________________________________________
> 1.
> Right after "begin" add:
> INetDate := trim( INetDate );
>
> (2.)
> If you use XEn:
> if Uppercase(MonthName) = string(Months[IX]) then
> instead of
> if Uppercase(MonthName) = Months[IX] then
>
> 3.
> after line
> Delete(InetDate,1,Pos(' ',InetDate));
> add this line:
> if pos( ' ', inetdate ) = 0 then inetdate := inetdate + ' ';
> _______________________________________________________________
>
>
> If you  f.e. want to catch the value of LAST-MODIFIED of a html file using
> a THttpCli :
>
> modify : event "httpgetHeaderEnd"
>
>
> procedure TsjOnlineForm.httpgetHeaderEnd(Sender: TObject);
> VAR
>  IX : INteger;
>  hst, ST : STring;
>  szgmt, DT : tDateTime;
>
> try
>  for IX := 0 to Httpget.RcvdHeader.count-1 do
>    BEGIN
>      hst := Httpget.RcvdHeader.Strings[IX];
>
>      if Pos('Content-Length:',hst) > 0 then
>        BEGIN
>          ST := hst;
>          Delete(ST,1,Pos(' ',ST));
>        END
>       else
>        if Pos('LAST-MODIFIED:',Uppercase(hst)) > 0 then
>        BEGIN
>          ST := hst;
>          Delete(ST,1,Pos(':',ST));
>          DT.:= 0;
>         try
>          DT := InetStdDateToDateTime(ST);
>         except
>               senderrorFeedback_eMail_to_RichardGallois( 'cannot parse
> t=' + ST );
>        end,
> _______________________________________________________________
>
>
> Best regards
> Michael
>
>
> ----- Original Message ----- From: "Richard Gallois" <g...@llois.com>
> To: <twsoc...@elists.org>
> Sent: Thursday, January 30, 2014 1:29 PM
> Subject: [twsocket] RFC 822 Date Time Conversion
>
>
>  Hi,
>>
>> Has anyone got a solid method of converting RFC 822 date times (e.g. Thu,
>> 30 Jan 2014 05:48:07 +0800) to a TDateTime. I've found a function in Indy
>> to do this, but I'd rather not compile Indy into my project if there is an
>> ICS way to do this.
>>
>> Many thanks,
>>
>> Richard
>> --
>> To unsubscribe or change your settings for TWSocket mailing list
>> please goto http://lists.elists.org/cgi-bin/mailman/listinfo/twsocket
>> Visit our website at http://www.overbyte.be
>>
>
> --
> To unsubscribe or change your settings for TWSocket mailing list
> please goto http://lists.elists.org/cgi-bin/mailman/listinfo/twsocket
> Visit our website at http://www.overbyte.be
>
-- 
To unsubscribe or change your settings for TWSocket mailing list
please goto http://lists.elists.org/cgi-bin/mailman/listinfo/twsocket
Visit our website at http://www.overbyte.be

Reply via email to