00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030 #include "opimtimezone.h"
00031
00032
00033 #include <opie2/odebug.h>
00034
00035
00036 #include <stdio.h>
00037 #include <stdlib.h>
00038 #include <sys/types.h>
00039
00040 namespace Opie
00041 {
00042
00043
00044
00045
00046
00047
00048 static QString setTimeZone( const QString& zone) {
00049 QString old;
00050 char *org = ::getenv( "TZ" );
00051 if( org )
00052 old = QString::fromLocal8Bit( org );
00053
00054 ::setenv( "TZ", zone.local8Bit(), true );
00055 ::tzset();
00056
00057 return old;
00058 }
00059
00060 static void resetTimeZone( const QString& zone ) {
00061 ::setenv( "TZ", zone.local8Bit(), true );
00062 }
00063
00064 static QDateTime utcTime( time_t t )
00065 {
00066 tm * broken = ::gmtime( &t );
00067 QDateTime ret;
00068 ret.setDate( QDate( broken->tm_year + 1900, broken->tm_mon + 1, broken->tm_mday ) );
00069 ret.setTime( QTime( broken->tm_hour, broken->tm_min, broken->tm_sec ) );
00070 return ret;
00071 }
00072
00073 static QDateTime utcTime( time_t t, const QString& zone )
00074 {
00075
00076 #ifndef Q_OS_MACX // Following line causes bus errors on Mac
00077 QString old = setTimeZone( zone );
00078 tm* broken = ::localtime( &t );
00079 resetTimeZone( old );
00080 #else
00081 #warning "Need a replacement for MacOSX!!"
00082
00083 tm* broken = ::localtime( &t );
00084 #endif
00085
00086 QDateTime ret;
00087 ret.setDate( QDate( broken->tm_year + 1900, broken->tm_mon + 1, broken->tm_mday ) );
00088 ret.setTime( QTime( broken->tm_hour, broken->tm_min, broken->tm_sec ) );
00089
00090 return ret;
00091 }
00092
00093
00094 static time_t to_Time_t( const QDateTime& utc, const QString& str )
00095 {
00096 QDate d = utc.date();
00097 QTime t = utc.time();
00098
00099 tm broken;
00100 broken.tm_year = d.year() - 1900;
00101 broken.tm_mon = d.month() - 1;
00102 broken.tm_mday = d.day();
00103 broken.tm_hour = t.hour();
00104 broken.tm_min = t.minute();
00105 broken.tm_sec = t.second();
00106
00107 #ifndef Q_OS_MACX // Following line causes bus errors on Mac
00108 QString old = setTimeZone( str );
00109 time_t ti = ::mktime( &broken );
00110 resetTimeZone( old );
00111 #else
00112 #warning "Need a replacement for MacOSX!!"
00113
00114 time_t ti = ::mktime( &broken );
00115 #endif
00116
00117 return ti;
00118 }
00119 }
00120
00121 namespace Opie
00122 {
00123 OPimTimeZone::OPimTimeZone( const ZoneName& zone )
00124 : m_name( zone )
00125 {}
00126
00127
00128 OPimTimeZone::~OPimTimeZone()
00129 {}
00130
00131
00132 bool OPimTimeZone::isValid() const
00133 {
00134 return !m_name.isEmpty();
00135 }
00136
00137
00138
00139
00140
00141 QDateTime OPimTimeZone::toLocalDateTime( const QDateTime& dt )
00142 {
00143 return OPimTimeZone::current().toDateTime( dt, *this );
00144 }
00145
00146
00147 QDateTime OPimTimeZone::toUTCDateTime( const QDateTime& dt )
00148 {
00149 return OPimTimeZone::utc().toDateTime( dt, *this );
00150 }
00151
00152
00153 QDateTime OPimTimeZone::fromUTCDateTime( time_t t )
00154 {
00155 return utcTime( t );
00156 }
00157
00158
00159 QDateTime OPimTimeZone::toDateTime( time_t t )
00160 {
00161 return utcTime( t, m_name );
00162 }
00163
00164
00165
00166
00167
00168
00169 QDateTime OPimTimeZone::toDateTime( const QDateTime& dt, const OPimTimeZone& zone )
00170 {
00171 time_t utc = to_Time_t( dt, m_name );
00172 return utcTime( utc, zone.m_name );
00173 }
00174
00175
00176 time_t OPimTimeZone::fromDateTime( const QDateTime& time )
00177 {
00178 return to_Time_t( time, m_name );
00179 }
00180
00181
00182 time_t OPimTimeZone::fromUTCDateTime( const QDateTime& time )
00183 {
00184 return to_Time_t( time, "Europe/London" );
00185 }
00186
00187
00188 OPimTimeZone OPimTimeZone::current()
00189 {
00190 QCString str = ::getenv( "TZ" );
00191 OPimTimeZone zone( str );
00192 return zone;
00193 }
00194
00195
00196 OPimTimeZone OPimTimeZone::utc()
00197 {
00198 return OPimTimeZone( "Europe/London" );
00199 }
00200
00201
00202 QString OPimTimeZone::timeZone() const
00203 {
00204 return m_name;
00205 }
00206
00207 }