Thread View: borland.public.cppbuilder.nativeapi
5 messages
5 total messages
Started by Robert G. Hoover
Tue, 19 Jun 2007 18:10
TDateTime & GMT
Author: Robert G. Hoover
Date: Tue, 19 Jun 2007 18:10
Date: Tue, 19 Jun 2007 18:10
12 lines
1140 bytes
1140 bytes
Hi All, Is there an easy way to convert the current time to a different timezone? Something like this...? AnsiString TimeString = Now().FormatString(GMT); Or do I have to use a TIME_ZONE_INFORMATION object or something? Thanks! Rob
Re: TDateTime & GMT
Author: Bob Gonder
Date: Tue, 19 Jun 2007 21:10
Date: Tue, 19 Jun 2007 21:10
12 lines
1315 bytes
1315 bytes
Robert G. Hoover wrote: >Is there an easy way to convert the current time to a different >timezone? Something like this...? > >AnsiString TimeString = Now().FormatString(GMT); I don't think so. >Or do I have to use a TIME_ZONE_INFORMATION object or something? I think SystemTimeToTzSpecificLocalTime()
Re: TDateTime & GMT
Author: Dennis Jones
Date: Wed, 20 Jun 2007 00:10
Date: Wed, 20 Jun 2007 00:10
174 lines
6362 bytes
6362 bytes
"Robert G. Hoover" <not.a.real.address@anywhere.sorry> wrote in message
news:46781ca0@newsgroups.borland.com...
> Hi All,
>
> Is there an easy way to convert the current time to a different
> timezone? Something like this...?
>
> AnsiString TimeString = Now().FormatString(GMT);
Unfortunately, no.
> Or do I have to use a TIME_ZONE_INFORMATION object or something?
Yeah, or something. I was looking at this a couple of years ago, and I
thought if you just knew the offset, you could get whatever you wanted. But
it turns out that each time zone has its own way of handling
standard/daylight time, so just knowing the timezone's offset isn't enough
to get an accurate conversion -- you also have to know its rules for
handling standard/daylight time.
So, what you have to do is:
1) Get the timezone information from the registry for both the source and
target timezones.
Note: The timezone information is in: HKLM\Software\Microsoft\Windows
NT\Time Zones\CurrentVersion. For an explanation of the format of the time
zone information in the registry, see:
http://support.microsoft.com/kb/115231
2) Convert the time from the source time zone to UTC (see:
TzSpecificLocalTimeToSystemTime).
3) Convert from UTC to the time in the target timezone (see:
SystemTimeToTzSpecificLocalTime).
If you can guarantee that your code will run on XP or higher, you can use
TzSpecificLocalTimeToSystemTime. If not, you'll have to roll your own or
get one from somewhere else. A good place to find source code for this kind
of thing is the Wine project. You will find an implementation for
TzSpecificLocalTimeToSystemTime in wine\dlls\kernel32\time.c.
Here's a quick and dirty implementation of GetTimeZoneInfoFromRegistry:
struct TZI
{
int Bias;
int StandardBias;
int DaylightBias;
SYSTEMTIME StandardDate;
SYSTEMTIME DaylightDate;
};
bool GetTimeZoneInfoFromRegistry(TIME_ZONE_INFORMATION &tzinfo, const
AnsiString &TZName)
{
static TIME_ZONE_INFORMATION _tzinfo;
tzinfo = _tzinfo;
bool bResult = false;
boost::scoped_ptr<TRegistry> pRegistry( new TRegistry );
pRegistry->RootKey = HKEY_LOCAL_MACHINE;
AnsiString TimeZonesKey = "Software\\Microsoft\\Windows
NT\\CurrentVersion\\Time Zones";
if ( pRegistry->OpenKey( TimeZonesKey, false ) )
{
boost::scoped_ptr<TStringList> pZones( new TStringList );
pRegistry->GetKeyNames( pZones.get() );
pRegistry->CloseKey();
int Index = pZones->IndexOf( TZName );
if ( Index != -1 )
{
AnsiString KeyToOpen = TimeZonesKey + "\\" + pZones->Strings[Index];
if ( pRegistry->OpenKey( KeyToOpen, false ) )
{
if ( pRegistry->ValueExists( "TZI" ) )
{
TZI tzi = { 0 };
if ( pRegistry->ReadBinaryData( "TZI", &tzi, sizeof(tzi) ) )
{
if ( pRegistry->ValueExists( "Std" ) )
{
AnsiString StandardName = pRegistry->ReadString( "Std" );
StandardName.WideChar( tzinfo.StandardName,
sizeof(tzinfo.StandardName) );
if ( pRegistry->ValueExists( "Dlt" ) )
{
AnsiString DaylightName = pRegistry->ReadString( "Dlt" );
DaylightName.WideChar( tzinfo.DaylightName,
sizeof(tzinfo.DaylightName) );
tzinfo.Bias = tzi.Bias;
tzinfo.StandardBias = tzi.StandardBias;
tzinfo.DaylightBias = tzi.DaylightBias;
tzinfo.StandardDate = tzi.StandardDate;
tzinfo.DaylightDate = tzi.DaylightDate;
bResult = true;
}
}
}
}
pRegistry->CloseKey();
}
}
}
return bResult;
}
Then, with some helper functions, conversion from one timezone to another is
fairly straightforward:
static void DateTimeToFileTime( const TDateTime &dt, FILETIME *ft )
{
SYSTEMTIME st;
DateTimeToSystemTime( dt, st );
SystemTimeToFileTime( &st, ft );
}
static void FileTimeToDateTime( const FILETIME *ft, TDateTime &dt )
{
SYSTEMTIME st;
FileTimeToSystemTime( ft, &st );
dt = SystemTimeToDateTime( st );
}
bool ConvertTimeZone( TDateTime &DateTime, const AnsiString &source_tz,
const AnsiString &target_tz )
{
TIME_ZONE_INFORMATION source_tzinfo;
if ( !GetTimeZoneInfoFromRegistry( source_tzinfo, source_tz ) ) return
false;
TIME_ZONE_INFORMATION target_tzinfo;
if ( !GetTimeZoneInfoFromRegistry( target_tzinfo, target_tz ) ) return
false;
FILETIME FileTime;
DateTimeToFileTime( DateTime, &FileTime );
SYSTEMTIME SystemTime;
FileTimeToSystemTime( &FileTime, &SystemTime );
SYSTEMTIME UniversalTime;
if ( !TzSpecificLocalTimeToSystemTime( &source_tzinfo, &SystemTime,
&UniversalTime ) ) return false;
if ( !SystemTimeToTzSpecificLocalTime( &target_tzinfo, &UniversalTime,
&SystemTime ) ) return false;
DateTime = SystemTimeToDateTime( SystemTime );
return true;
}
#pragma argsused
int main(int argc, char* argv[])
{
TDateTime now = Now();
printf( "The current time in Portland, Oregon is: %s\n",
now.FormatString( "hh:nn:ss" ).c_str() );
// get the current time in Bangalore, India
ConvertTimeZone( now, "Pacific Standard Time", "India Standard Time" );
printf( "The current time in Bangalore, India is: %s\n",
now.FormatString( "hh:nn:ss" ).c_str() );
return 0;
}
HTH,
- Dennis
Re: TDateTime & GMT
Author: Robert G. Hoover
Date: Wed, 20 Jun 2007 20:01
Date: Wed, 20 Jun 2007 20:01
4 lines
1192 bytes
1192 bytes
Wow! Outstanding! I'm going to have to set aside some time to work through this. Thanks so much! Rob
Re: TDateTime & GMT
Author: Dennis Jones
Date: Wed, 20 Jun 2007 20:18
Date: Wed, 20 Jun 2007 20:18
12 lines
1499 bytes
1499 bytes
"Robert G. Hoover" <not.a.real.address@anywhere.sorry> wrote in message news:46798807@newsgroups.borland.com... > Wow! Outstanding! I'm going to have to set aside some time to work > through this. Thanks so much! You're very welcome. Don't assume the code is perfect though, or as if it has been fully tested-- it hasn't. I threw it together rather quickly and just ran a few tests on it. Though it does appear to give correct results, I wouldn't trust it without more testing. - Dennis
Thread Navigation
This is a paginated view of messages in the thread with full content displayed inline.
Messages are displayed in chronological order, with the original post highlighted in green.
Use pagination controls to navigate through all messages in large threads.
Back to All Threads