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 ), mTodayOneSecondBeforeMidnight( 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 ( mTodayOneSecondBeforeMidnight < time( 0 ) ) {
00229
00230 const QDateTime today( QDate::currentDate(), QTime( 23, 59, 59 ) );
00231 mTodayOneSecondBeforeMidnight = today.toTime_t();
00232 }
00233
00234 QDateTime old;
00235 old.setTime_t( t );
00236
00237 if ( mTodayOneSecondBeforeMidnight >= t ) {
00238 const time_t diff = mTodayOneSecondBeforeMidnight - t;
00239 if ( diff < 7 * 24 * 60 * 60 ) {
00240 if ( diff < 24 * 60 * 60 ) {
00241 return i18n( "Today %1",
00242 locale->formatTime( old.time(), true ) );
00243 }
00244 if ( diff < 2 * 24 * 60 * 60 ) {
00245 return i18n( "Yesterday %1",
00246 locale->formatTime( old.time(), true ) );
00247 }
00248 for ( int i = 3; i < 8; i++ ) {
00249 if ( diff < i * 24 * 60 * 60 ) {
00250 return i18nc( "1. weekday, 2. time", "%1 %2" ,
00251 locale->calendar()->weekDayName( old.date() ) ,
00252 locale->formatTime( old.time(), true ) );
00253 }
00254 }
00255 }
00256 }
00257
00258 return locale->formatDateTime( old );
00259 }
00260
00261 QString DateFormatter::localized( time_t t, bool shortFormat, bool includeSecs,
00262 const QString &lang ) const
00263 {
00264 QDateTime tmp;
00265 QString ret;
00266 KLocale *locale = KGlobal::locale();
00267
00268 tmp.setTime_t( t );
00269
00270 if ( !lang.isEmpty() ) {
00271 locale = new KLocale( lang, lang, lang);
00272 ret = locale->formatDateTime( tmp, (shortFormat ? KLocale::ShortDate : KLocale::LongDate), includeSecs );
00273 delete locale;
00274 } else {
00275 ret = locale->formatDateTime( tmp, (shortFormat ? KLocale::ShortDate : KLocale::LongDate), includeSecs );
00276 }
00277
00278 return ret;
00279 }
00280
00281 QString DateFormatter::cTime( time_t t ) const
00282 {
00283 return QString::fromLatin1( ctime( &t ) ).trimmed();
00284 }
00285
00286 QString DateFormatter::isoDate( time_t t ) const
00287 {
00288 char cstr[64];
00289 strftime( cstr, 63, "%Y-%m-%d %H:%M:%S", localtime( &t ) );
00290 return QString( cstr );
00291 }
00292
00293 void DateFormatter::reset()
00294 {
00295 mTodayOneSecondBeforeMidnight = 0;
00296 }
00297
00298 QString DateFormatter::formatDate( FormatType ftype, time_t t,
00299 const QString &data, bool shortFormat,
00300 bool includeSecs )
00301 {
00302 DateFormatter f( ftype );
00303 if ( ftype == Custom ) {
00304 f.setCustomFormat( data );
00305 }
00306 return f.dateString( t, data, shortFormat, includeSecs );
00307 }
00308
00309 QString DateFormatter::formatCurrentDate( FormatType ftype, const QString &data,
00310 bool shortFormat, bool includeSecs )
00311 {
00312 DateFormatter f( ftype );
00313 if ( ftype == Custom ) {
00314 f.setCustomFormat( data );
00315 }
00316 return f.dateString( time( 0 ), data, shortFormat, includeSecs );
00317 }
00318
00319 bool DateFormatter::isDaylight()
00320 {
00321 if ( mDaylight == -1 ) {
00322 time_t ntime = time( 0 );
00323 struct tm *local = localtime( &ntime );
00324 if ( local->tm_isdst > 0 ) {
00325 mDaylight = 1;
00326 return true;
00327 } else {
00328 mDaylight = 0;
00329 return false;
00330 }
00331 } else if ( mDaylight != 0 ) {
00332 return true;
00333 } else {
00334 return false;
00335 }
00336 }