|
|
|
|
|
|
||
|
/* ** Author: Samuel R. Blackburn (http://www.codeproject.com/library/wfc.asp) ** Internet: wfc@pobox.com ** ** You can use it any way you like as long as you don't try to sell it. ** ** Any attempt to sell WFC in source code form must have the permission ** of the original author. You can produce commercial executables with ** WFC but you can't sell WFC. ** ** Copyright, 2000, Samuel R. Blackburn ** ** $Workfile: wfc_parse_iso_8601_string.cpp $ ** $Revision: 7 $ ** $Modtime: 1/24/00 6:11p $ ** $Reuse Tracing Code: 1 $ */
/****************************************************************************/ /** **/ /** Modified
2005 by Diodia Software (http://www.diodia.com/) **/ /**
**/ /****************************************************************************/ #include "stdafx.h"
#include "RssHelpers.h"
static BOOL __parse_ymdhms( LPCTSTR time_string, int& year, int& month, int& day, int& hours, int& minutes, int& seconds, TCHAR& offset_character, int& offset_hours, int& offset_minutes ) { // Here's a sample ISO8601 date string // // 1969-07-20T22:56:15-04:00
// Do a little idiot checking
if ( time_string == NULL ) return( FALSE );
// Start with some believable defaults
year = 0; month = 1; day = 1; hours = 0; minutes = 0; seconds = 0; offset_character = TEXT( 'Z' ); offset_hours = 0; offset_minutes = 0;
// We were passed a pointer, don't trust it
try { if ( _tcslen( time_string ) < 4 ) { // There ain't enough characters to even attempt to parse return( FALSE ); }
// OK, let's start parsing
if ( _istdigit( time_string[ 0 ] ) == 0 ) { // First character is not a digit return( FALSE ); }
if ( _istdigit( time_string[ 1 ] ) == 0 ) { // Second character is not a digit return( FALSE ); }
if ( _istdigit( time_string[ 2 ] ) == 0 ) { // Third character is not a digit" return( FALSE ); }
if ( _istdigit( time_string[ 3 ] ) == 0 ) { // Fourth character is not a digit return( FALSE ); }
// If we get here, it means we've got 4 good digits
TCHAR temp_string[ 5 ];
temp_string[ 0 ] = time_string[ 0 ]; temp_string[ 1 ] = time_string[ 1 ]; temp_string[ 2 ] = time_string[ 2 ]; temp_string[ 3 ] = time_string[ 3 ]; temp_string[ 4 ] = 0x00;
year = _ttoi( temp_string );
DWORD index = 4;
// index should be pointing here // | // v // 1969-07-20T22:56:15-04:00
if ( time_string[ index ] == 0x00 ) { // We're at the end of the string
return( TRUE ); }
if ( time_string[ index ] != TEXT( '-' ) ) { // The separator between year and month is not - return( FALSE ); }
index++;
// index should be pointing here // | // v // 1969-07-20T22:56:15-04:00
if ( time_string[ index ] == 0x00 ) { // We're at the end of the string return( TRUE ); }
if ( _istdigit( time_string[ index ] ) == 0 ) { // First digit of month field isn't a digit at all return( FALSE ); }
index++;
// index should be pointing here // | // v // 1969-07-20T22:56:15-04:00
// This test is safe because we could be sitting on a NULL
if ( _istdigit( time_string[ index ] ) == 0 ) { // Second digit of month field isn't a digit at all return( FALSE ); }
temp_string[ 0 ] = time_string[ index - 1 ]; temp_string[ 1 ] = time_string[ index ]; temp_string[ 2 ] = 0x00;
month = _ttoi( temp_string );
// Do a little idiot proofing
if ( month < 1 || month > 12 ) { // Funky month return( FALSE ); }
index++;
// index should be pointing here // | // v // 1969-07-20T22:56:15-04:00
if ( time_string[ index ] == 0x00 ) { return( TRUE ); }
if ( time_string[ index ] != TEXT( '-' ) ) { // The separator between month and day fields is not - return( FALSE ); }
index++;
// index should be pointing here // | // v // 1969-07-20T22:56:15-04:00
if ( time_string[ index ] == 0x00 ) { // Odd, but not illegal return( TRUE ); }
if ( _istdigit( time_string[ index ] ) == 0 ) { // First digit of day field isn't a digit at all return( FALSE ); }
index++;
// index should be pointing here // | // v // 1969-07-20T22:56:15-04:00
// This test is safe because we could be sitting on a NULL
if ( _istdigit( time_string[ index ] ) == 0 ) { // Second digit of month field isn't a digit at all return( FALSE ); }
temp_string[ 0 ] = time_string[ index - 1 ]; temp_string[ 1 ] = time_string[ index ];
// We don't need to set temp_string[ 2 ] because we did that at line 158 above
day = _ttoi( temp_string );
// Do a very little bit of error checking
if ( day < 1 || day > 31 ) { // Funky day return( FALSE ); }
index++;
// index should be pointing here // | // v // 1969-07-20T22:56:15-04:00
if ( time_string[ index ] == 0x00 ) { // Odd, but not illegal return( TRUE ); }
if ( time_string[ index ] != TEXT( 'T' ) ) { // Separator between date and time ain't T return( FALSE ); }
index++;
// index should be pointing here // | // v // 1969-07-20T22:56:15-04:00
if ( time_string[ index ] == 0x00 ) { // Odd, but not illegal return( TRUE ); }
if ( _istdigit( time_string[ index ] ) == 0 ) { // First digit of hours field isn't a digit at all return( FALSE ); }
index++;
// index should be pointing here // | // v // 1969-07-20T22:56:15-04:00
// This test is safe because we could be sitting on a NULL
if ( _istdigit( time_string[ index ] ) == 0 ) { // Second digit of month field isn't a digit at all return( FALSE ); }
temp_string[ 0 ] = time_string[ index - 1 ]; temp_string[ 1 ] = time_string[ index ];
// We don't need to set temp_string[ 2 ] because we did that at line 158 above
hours = _ttoi( temp_string );
index++;
// index should be pointing here // | // v // 1969-07-20T22:56:15-04:00
if ( time_string[ index ] == 0x00 ) { // Odd, but not illegal return( TRUE ); }
if ( time_string[ index ] != TEXT( ':' ) ) { // Separator between hours and minutes ain't : return( FALSE ); }
index++;
// index should be pointing here // | // v // 1969-07-20T22:56:15-04:00
if ( time_string[ index ] == 0x00 ) { // Odd, but not illegal return( TRUE ); }
if ( _istdigit( time_string[ index ] ) == 0 ) { // First digit of time ain't no digit return( FALSE ); }
index++;
// index should be pointing here // | // v // 1969-07-20T22:56:15-04:00
if ( _istdigit( time_string[ index ] ) == 0 ) { // First digit of time ain't no digit return( FALSE ); }
temp_string[ 0 ] = time_string[ index - 1 ]; temp_string[ 1 ] = time_string[ index ];
minutes = _ttoi( temp_string );
index++;
// index should be pointing here // | // v // 1969-07-20T22:56:15-04:00
if ( time_string[ index ] == 0x00 ) { return( TRUE ); }
if ( time_string[ index ] != TEXT( ':' ) ) { // Separator between minutes and seconds ain't : return( FALSE ); }
index++;
// index should be pointing here // | // v // 1969-07-20T22:56:15-04:00
if ( time_string[ index ] == 0x00 ) { // Odd, but not illegal return( TRUE ); }
if ( _istdigit( time_string[ index ] ) == 0 ) { // First digit of seconds ain't no digit return( FALSE ); }
index++;
// index should be pointing here // | // v // 1969-07-20T22:56:15-04:00
if ( _istdigit( time_string[ index ] ) == 0 ) { // Second digit of seconds ain't no digit return( FALSE ); }
temp_string[ 0 ] = time_string[ index - 1 ]; temp_string[ 1 ] = time_string[ index ];
seconds = _ttoi( temp_string );
index++;
// index should be pointing here // | // v // 1969-07-20T22:56:15-04:00
if ( time_string[ index ] == 0x00 || time_string[ index ] == TEXT( 'Z' ) ) { return( TRUE ); }
// OK, now is the time when parsing gets interesting // The current index may be sitting on a partial second. // Since CTime can't deal with partial seconds, we // will just skip that part entirely.
if ( time_string[ index ] == TEXT( '.' ) ) { index++;
BOOL exit_loop = FALSE;
while( exit_loop == FALSE ) { if ( time_string[ index ] == 0x00 ) { return( TRUE ); }
if ( _istdigit( time_string[ index ] ) == 0 ) { exit_loop = TRUE; } else { index++; } } }
// If we get here, we should be sitting on a Z, + or -
if ( time_string[ index ] == TEXT( 'Z' ) ) { return( TRUE ); }
if ( time_string[ index ] != TEXT( '+' ) && time_string[ index ] != TEXT( '-' ) ) { // Time zone designator ain't beginning with + or - return( FALSE ); }
offset_character = time_string[ index ];
index++;
// index should be pointing here // | // v // 1969-07-20T22:56:15-04:00
if ( _istdigit( time_string[ index ] ) == 0 ) { // first digit of hours offset ain't a digit return( FALSE ); }
index++;
// index should be pointing here // | // v // 1969-07-20T22:56:15-04:00
if ( _istdigit( time_string[ index ] ) == 0 ) { // second digit of hours offset ain't a digit return( FALSE ); }
temp_string[ 0 ] = time_string[ index - 1 ]; temp_string[ 1 ] = time_string[ index ];
offset_hours = _ttoi( temp_string );
index++;
// index should be pointing here // | // v // 1969-07-20T22:56:15-04:00
if ( time_string[ index ] != TEXT( ':' ) ) { // Separator between offset hours and minutes ain't a : return( FALSE ); }
index++;
// index should be pointing here // | // v // 1969-07-20T22:56:15-04:00
if ( _istdigit( time_string[ index ] ) == 0 ) { // First digit of minutes offset ain't a digit return( FALSE ); }
index++;
// index should be pointing here // | // v // 1969-07-20T22:56:15-04:00
if ( _istdigit( time_string[ index ] ) == 0 ) { // Second digit of minutes offset ain't a digit return( FALSE ); }
temp_string[ 0 ] = time_string[ index - 1 ]; temp_string[ 1 ] = time_string[ index ];
offset_minutes = _ttoi( temp_string );
return( TRUE ); } catch( ... ) { return( FALSE ); } }
BOOL wfc_parse_iso_8601_string( LPCTSTR time_string, FILETIME& the_time ) { the_time.dwHighDateTime = 0; the_time.dwLowDateTime = 0;
SYSTEMTIME system_time;
if ( wfc_parse_iso_8601_string( time_string, system_time ) == FALSE ) { return( FALSE ); }
SystemTimeToFileTime(&system_time, &the_time);
return( TRUE ); }
BOOL wfc_parse_iso_8601_string( LPCTSTR time_string, COleDateTime& the_time ) { the_time = COleDateTime( static_cast< time_t >( 0 ) );
// Do a little idiot checking
if ( time_string == NULL ) { // time_string is NULL! return( FALSE ); }
int year = 0; int month = 0; int day = 0; int hours = 0; int minutes = 0; int seconds = 0;
TCHAR offset_character = 0;
int offset_hours = 0; int offset_minutes = 0;
if ( __parse_ymdhms( time_string, year, month, day, hours, minutes, seconds, offset_character, offset_hours, offset_minutes ) == FALSE ) { // Can't parse string return( FALSE ); }
the_time = COleDateTime( year, month, day, hours, minutes, seconds );
if ( offset_character != TEXT( 'Z' ) ) { COleDateTimeSpan time_zone_offset( 0, offset_hours, offset_minutes, 0 );
if ( offset_character == TEXT( '-' ) ) { the_time += time_zone_offset; } else if ( offset_character == TEXT( '+' ) ) { the_time -= time_zone_offset; } }
return( TRUE ); }
BOOL wfc_parse_iso_8601_string( LPCTSTR time_string, SYSTEMTIME& the_time ) {
the_time.wYear = 0; the_time.wMonth = 0; the_time.wDay = 0; the_time.wDayOfWeek = 0; the_time.wHour = 0; the_time.wMinute = 0; the_time.wSecond = 0; the_time.wMilliseconds = 0;
// Do a little idiot checking
if ( time_string == NULL ) { // time_string is NULL! return( FALSE ); }
int year = 0; int month = 0; int day = 0; int hours = 0; int minutes = 0; int seconds = 0;
TCHAR offset_character = 0;
int offset_hours = 0; int offset_minutes = 0;
if ( __parse_ymdhms( time_string, year, month, day, hours, minutes, seconds, offset_character, offset_hours, offset_minutes ) == FALSE ) { // Can't parse string return( FALSE ); }
CTime ole_time = CTime( year, month, day, hours, minutes, seconds );
if ( offset_character != TEXT( 'Z' ) ) { CTimeSpan time_zone_offset( 0, offset_hours, offset_minutes, 0 );
if ( offset_character == TEXT( '-' ) ) | ||