00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00034 #include "kmime_dateformatter.h"
00035
00036 #include <config-kmime.h>
00037
00038 #include <stdlib.h>
00039
00040 #include <QtCore/QTextStream>
00041
00042 #include <kglobal.h>
00043 #include <klocale.h>
00044 #include <kcalendarsystem.h>
00045
00046 using namespace KMime;
00047
00048
00049 int DateFormatter::mDaylight = -1;
00050
00051 DateFormatter::DateFormatter( FormatType ftype )
00052 : mFormat( ftype ), mCurrentTime( 0 )
00053 {
00054 }
00055
00056 DateFormatter::~DateFormatter()
00057 {
00058 }
00059
00060 DateFormatter::FormatType DateFormatter::format() const
00061 {
00062 return mFormat;
00063 }
00064
00065 void DateFormatter::setFormat( FormatType ftype )
00066 {
00067 mFormat = ftype;
00068 }
00069
00070 QString DateFormatter::dateString( time_t t , const QString &lang ,
00071 bool shortFormat, bool includeSecs ) const
00072 {
00073 switch ( mFormat ) {
00074 case Fancy:
00075 return fancy( t );
00076 break;
00077 case Localized:
00078 return localized( t, shortFormat, includeSecs, lang );
00079 break;
00080 case CTime:
00081 return cTime( t );
00082 break;
00083 case Iso:
00084 return isoDate( t );
00085 break;
00086 case Rfc:
00087 return rfc2822( t );
00088 break;
00089 case Custom:
00090 return custom( t );
00091 break;
00092 }
00093 return QString();
00094 }
00095
00096 QString DateFormatter::dateString( const QDateTime &dt, const QString &lang,
00097 bool shortFormat, bool includeSecs ) const
00098 {
00099 return dateString( qdateToTimeT( dt ), lang, shortFormat, includeSecs );
00100 }
00101
00102 QString DateFormatter::rfc2822( time_t t ) const
00103 {
00104 QDateTime tmp;
00105 QString ret;
00106
00107 tmp.setTime_t( t );
00108
00109 ret = tmp.toString( "ddd, dd MMM yyyy hh:mm:ss " ).toLatin1();
00110 ret += zone( t );
00111
00112 return ret;
00113 }
00114
00115 QString DateFormatter::custom( time_t t ) const
00116 {
00117 if ( mCustomFormat.isEmpty() ) {
00118 return QString();
00119 }
00120
00121 int z = mCustomFormat.indexOf( 'Z' );
00122 QDateTime d;
00123 QString ret = mCustomFormat;
00124
00125 d.setTime_t( t );
00126 if ( z != -1 ) {
00127 ret.replace( z, 1, zone( t ) );
00128 }
00129
00130 ret = d.toString( ret );
00131
00132 return ret;
00133 }
00134
00135 void DateFormatter::setCustomFormat( const QString &format )
00136 {
00137 mCustomFormat = format;
00138 mFormat = Custom;
00139 }
00140
00141 QString DateFormatter::customFormat() const
00142 {
00143 return mCustomFormat;
00144 }
00145
00146 QByteArray DateFormatter::zone( time_t t ) const
00147 {
00148 #if defined(HAVE_TIMEZONE) || defined(HAVE_TM_GMTOFF)
00149 struct tm *local = localtime( &t );
00150 #endif
00151
00152 #if defined(HAVE_TIMEZONE)
00153
00154
00155 int secs = abs( timezone );
00156 int neg = (timezone > 0) ? 1 : 0;
00157 int hours = secs / 3600;
00158 int mins = (secs - hours*3600) / 60;
00159
00160
00161 if ( local->tm_isdst > 0 ) {
00162 mDaylight = 1;
00163 if ( neg ) {
00164 --hours;
00165 } else {
00166 ++hours;
00167 }
00168 } else {
00169 mDaylight = 0;
00170 }
00171
00172 #elif defined(HAVE_TM_GMTOFF)
00173
00174 int secs = abs( local->tm_gmtoff );
00175 int neg = (local->tm_gmtoff < 0) ? 1 : 0;
00176 int hours = secs / 3600;
00177 int mins = (secs - hours * 3600) / 60;
00178
00179 if ( local->tm_isdst > 0 ) {
00180 mDaylight = 1;
00181 } else {
00182 mDaylight = 0;
00183 }
00184
00185 #else
00186
00187 QDateTime d1 = QDateTime::fromString( asctime( gmtime( &t ) ) );
00188 QDateTime d2 = QDateTime::fromString( asctime( localtime( &t ) ) );
00189 int secs = d1.secsTo( d2 );
00190 int neg = ( secs < 0 ) ? 1 : 0;
00191 secs = abs( secs );
00192 int hours = secs / 3600;
00193 int mins = (secs - hours * 3600) / 60;
00194
00195
00196 #endif
00197
00198 QByteArray ret;
00199 QTextStream s( &ret, QIODevice::WriteOnly );
00200 s << ( neg ? '-' : '+' )
00201 << qSetFieldWidth( 2 ) << qSetPadChar( '0' ) << right << hours << mins;
00202
00203
00204 return ret;
00205 }
00206
00207 time_t DateFormatter::qdateToTimeT( const QDateTime &dt ) const
00208 {
00209 QDateTime epoch( QDate( 1970, 1, 1 ), QTime( 00, 00, 00 ) );
00210 time_t t;
00211 time( &t );
00212
00213 QDateTime d1 = QDateTime::fromString( asctime( gmtime( &t ) ) );
00214 QDateTime d2 = QDateTime::fromString( asctime( localtime( &t ) ) );
00215 time_t drf = epoch.secsTo( dt ) - d1.secsTo( d2 );
00216
00217 return drf;
00218 }
00219
00220 QString DateFormatter::fancy( time_t t ) const
00221 {
00222 KLocale *locale = KGlobal::locale();
00223
00224 if ( t <= 0 ) {
00225 return i18nc( "invalid time specified", "unknown" );
00226 }
00227
00228 if ( !mCurrentTime ) {
00229 time( &mCurrentTime );
00230 mDate.setTime_t( mCurrentTime );
00231 }
00232
00233 QDateTime old;
00234 old.setTime_t( t );
00235
00236
00237 if ( mCurrentTime + 60 * 60 >= t ) {
00238 time_t diff = mCurrentTime - t;
00239
00240 if ( diff < 24 * 60 * 60 ) {
00241 if ( old.date().year() == mDate.date().year() &&
00242 old.date().dayOfYear() == mDate.date().dayOfYear() )
00243 return i18n( "Today %1", locale->
00244 formatTime( old.time(), true ) );
00245 }
00246 if ( diff < 2 * 24 * 60 * 60 ) {
00247 QDateTime yesterday( mDate.addDays( -1 ) );
00248 if ( old.date().year() == yesterday.date().year() &&
00249 old.date().dayOfYear() == yesterday.date().dayOfYear() )
00250 return i18n( "Yesterday %1", locale->
00251 formatTime( old.time(), true) );
00252 }
00253 for ( int i = 3; i < 7; i++ ) {
00254 if ( diff < i * 24 * 60 * 60 ) {
00255 QDateTime weekday( mDate.addDays( -i + 1 ) );
00256 if ( old.date().year() == weekday.date().year() &&
00257 old.date().dayOfYear() == weekday.date().dayOfYear() )
00258 return i18nc( "1. weekday, 2. time", "%1 %2" ,
00259 locale->calendar()->weekDayName( old.date() ) ,
00260 locale->formatTime( old.time(), true) );
00261 }
00262 }
00263 }
00264
00265 return locale->formatDateTime( old );
00266
00267 }
00268
00269 QString DateFormatter::localized( time_t t, bool shortFormat, bool includeSecs,
00270 const QString &lang ) const
00271 {
00272 QDateTime tmp;
00273 QString ret;
00274 KLocale *locale = KGlobal::locale();
00275
00276 tmp.setTime_t( t );
00277
00278 if ( !lang.isEmpty() ) {
00279 locale = new KLocale( lang, lang, lang);
00280 ret = locale->formatDateTime( tmp, (shortFormat ? KLocale::ShortDate : KLocale::LongDate), includeSecs );
00281 delete locale;
00282 } else {
00283 ret = locale->formatDateTime( tmp, (shortFormat ? KLocale::ShortDate : KLocale::LongDate), includeSecs );
00284 }
00285
00286 return ret;
00287 }
00288
00289 QString DateFormatter::cTime( time_t t ) const
00290 {
00291 return QString::fromLatin1( ctime( &t ) ).trimmed();
00292 }
00293
00294 QString DateFormatter::isoDate( time_t t ) const
00295 {
00296 char cstr[64];
00297 strftime( cstr, 63, "%Y-%m-%d %H:%M:%S", localtime( &t ) );
00298 return QString( cstr );
00299 }
00300
00301 void DateFormatter::reset()
00302 {
00303 mCurrentTime = 0;
00304 }
00305
00306 QString DateFormatter::formatDate( FormatType ftype, time_t t,
00307 const QString &data, bool shortFormat,
00308 bool includeSecs )
00309 {
00310 DateFormatter f( ftype );
00311 if ( ftype == Custom ) {
00312 f.setCustomFormat( data );
00313 }
00314 return f.dateString( t, data, shortFormat, includeSecs );
00315 }
00316
00317 QString DateFormatter::formatCurrentDate( FormatType ftype, const QString &data,
00318 bool shortFormat, bool includeSecs )
00319 {
00320 DateFormatter f( ftype );
00321 if ( ftype == Custom ) {
00322 f.setCustomFormat( data );
00323 }
00324 return f.dateString( time( 0 ), data, shortFormat, includeSecs );
00325 }
00326
00327 bool DateFormatter::isDaylight()
00328 {
00329 if ( mDaylight == -1 ) {
00330 time_t ntime = time( 0 );
00331 struct tm *local = localtime( &ntime );
00332 if ( local->tm_isdst > 0 ) {
00333 mDaylight = 1;
00334 return true;
00335 } else {
00336 mDaylight = 0;
00337 return false;
00338 }
00339 } else if ( mDaylight != 0 ) {
00340 return true;
00341 } else {
00342 return false;
00343 }
00344 }