libkmime

kmime_util.cpp
1/*
2 kmime_util.cpp
3
4 KMime, the KDE internet mail/usenet news message library.
5 Copyright (c) 2001 the KMime authors.
6 See file AUTHORS for details
7
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2 of the License, or
11 (at your option) any later version.
12 You should have received a copy of the GNU General Public License
13 along with this program; if not, write to the Free Software Foundation,
14 Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, US
15*/
16
17#ifdef HAVE_CONFIG_H
18#include <config.h>
19#endif
20
21#include "kmime_util.h"
22
23#include <kmdcodec.h> // for KCodec::{quotedPrintableDe,base64{En,De}}code
24#include <tdeglobal.h>
25#include <tdelocale.h>
26#include <kcharsets.h>
27#include <tdeversion.h>
28#if KDE_IS_VERSION( 3, 1, 90 )
29#include <kcalendarsystem.h>
30#endif
31
32#include <tqtextcodec.h>
33#include <tqstrlist.h> // for TQStrIList
34#include <tqregexp.h>
35#include <tqdatetime.h>
36
37#include <stdlib.h>
38#include <ctype.h>
39#include <time.h> // for time()
40#include <unistd.h> // for getpid()
41
42using namespace KMime;
43
44namespace KMime {
45
46TQStrIList c_harsetCache;
47TQStrIList l_anguageCache;
48
49const char* cachedCharset(const TQCString &name)
50{
51 int idx=c_harsetCache.find(name.data());
52 if(idx>-1)
53 return c_harsetCache.at(idx);
54
55 c_harsetCache.append(name.upper().data());
56 //kdDebug() << "KNMimeBase::cachedCharset() number of cs " << c_harsetCache.count() << endl;
57 return c_harsetCache.last();
58}
59
60const char* cachedLanguage(const TQCString &name)
61{
62 int idx=l_anguageCache.find(name.data());
63 if(idx>-1)
64 return l_anguageCache.at(idx);
65
66 l_anguageCache.append(name.upper().data());
67 //kdDebug() << "KNMimeBase::cachedCharset() number of cs " << c_harsetCache.count() << endl;
68 return l_anguageCache.last();
69}
70
71bool isUsAscii(const TQString &s)
72{
73 uint sLength = s.length();
74 for (uint i=0; i<sLength; i++)
75 if (s.at(i).latin1()<=0) // c==0: non-latin1, c<0: non-us-ascii
76 return false;
77
78 return true;
79}
80
81// "(),.:;<>@[\]
82const uchar specialsMap[16] = {
83 0x00, 0x00, 0x00, 0x00, // CTLs
84 0x20, 0xCA, 0x00, 0x3A, // SPACE ... '?'
85 0x80, 0x00, 0x00, 0x1C, // '@' ... '_'
86 0x00, 0x00, 0x00, 0x00 // '`' ... DEL
87};
88
89// "(),:;<>@[\]/=?
90const uchar tSpecialsMap[16] = {
91 0x00, 0x00, 0x00, 0x00, // CTLs
92 0x20, 0xC9, 0x00, 0x3F, // SPACE ... '?'
93 0x80, 0x00, 0x00, 0x1C, // '@' ... '_'
94 0x00, 0x00, 0x00, 0x00 // '`' ... DEL
95};
96
97// all except specials, CTLs, SPACE.
98const uchar aTextMap[16] = {
99 0x00, 0x00, 0x00, 0x00,
100 0x5F, 0x35, 0xFF, 0xC5,
101 0x7F, 0xFF, 0xFF, 0xE3,
102 0xFF, 0xFF, 0xFF, 0xFE
103};
104
105// all except tspecials, CTLs, SPACE.
106const uchar tTextMap[16] = {
107 0x00, 0x00, 0x00, 0x00,
108 0x5F, 0x36, 0xFF, 0xC0,
109 0x7F, 0xFF, 0xFF, 0xE3,
110 0xFF, 0xFF, 0xFF, 0xFE
111};
112
113// none except a-zA-Z0-9!*+-/
114const uchar eTextMap[16] = {
115 0x00, 0x00, 0x00, 0x00,
116 0x40, 0x35, 0xFF, 0xC0,
117 0x7F, 0xFF, 0xFF, 0xE0,
118 0x7F, 0xFF, 0xFF, 0xE0
119};
120
121#if defined(_AIX) && defined(truncate)
122#undef truncate
123#endif
124
125TQString decodeRFC2047String(const TQCString &src, const char **usedCS,
126 const TQCString &defaultCS, bool forceCS)
127{
128 TQCString result, str;
129 TQCString declaredCS;
130 const char *beg, *end, *mid, *pos=0;
131 char *dest, *endOfLastEncWord=0;
132 char encoding = '\0';
133 bool valid, onlySpacesSinceLastWord=false;
134 const int maxLen=400;
135 int i;
136
137 if(src.find("=?") < 0)
138 result = src.copy();
139 else {
140 result.truncate(src.length());
141 for (pos=src.data(), dest=result.data(); *pos; pos++)
142 {
143 if (pos[0]!='=' || pos[1]!='?')
144 {
145 *dest++ = *pos;
146 if (onlySpacesSinceLastWord)
147 onlySpacesSinceLastWord = (pos[0]==' ' || pos[1]=='\t');
148 continue;
149 }
150 beg = pos+2;
151 end = beg;
152 valid = TRUE;
153 // parse charset name
154 declaredCS="";
155 for (i=2,pos+=2; i<maxLen && (*pos!='?'&&(ispunct(*pos)||isalnum(*pos))); i++) {
156 declaredCS+=(*pos);
157 pos++;
158 }
159 if (*pos!='?' || i<4 || i>=maxLen) valid = FALSE;
160 else
161 {
162 // get encoding and check delimiting question marks
163 encoding = toupper(pos[1]);
164 if (pos[2]!='?' || (encoding!='Q' && encoding!='B'))
165 valid = FALSE;
166 pos+=3;
167 i+=3;
168 }
169 if (valid)
170 {
171 mid = pos;
172 // search for end of encoded part
173 while (i<maxLen && *pos && !(*pos=='?' && *(pos+1)=='='))
174 {
175 i++;
176 pos++;
177 }
178 end = pos+2;//end now points to the first char after the encoded string
179 if (i>=maxLen || !*pos) valid = FALSE;
180 }
181
182 if (valid) {
183 // cut all linear-white space between two encoded words
184 if (onlySpacesSinceLastWord)
185 dest=endOfLastEncWord;
186
187 if (mid < pos) {
188 str = TQCString(mid, (int)(pos - mid + 1));
189 if (encoding == 'Q')
190 {
191 // decode quoted printable text
192 for (i=str.length()-1; i>=0; i--)
193 if (str[i]=='_') str[i]=' ';
194 str = KCodecs::quotedPrintableDecode(str);
195 }
196 else
197 {
198 str = KCodecs::base64Decode(str);
199 }
200 if (!str.isNull()) {
201 for (i=0; str[i]; i++) {
202 *dest++ = str[i];
203 }
204 }
205 }
206
207 endOfLastEncWord=dest;
208 onlySpacesSinceLastWord=true;
209
210 pos = end -1;
211 }
212 else
213 {
214 pos = beg - 2;
215 *dest++ = *pos++;
216 *dest++ = *pos;
217 }
218 }
219 *dest = '\0';
220 }
221
222 //find suitable TQTextCodec
223 TQTextCodec *codec=0;
224 bool ok=true;
225 if (forceCS || declaredCS.isEmpty()) {
226 codec=TDEGlobal::charsets()->codecForName(defaultCS);
227 (*usedCS)=cachedCharset(defaultCS);
228 }
229 else {
230 codec=TDEGlobal::charsets()->codecForName(declaredCS, ok);
231 if(!ok) { //no suitable codec found => use default charset
232 codec=TDEGlobal::charsets()->codecForName(defaultCS);
233 (*usedCS)=cachedCharset(defaultCS);
234 }
235 else
236 (*usedCS)=cachedCharset(declaredCS);
237 }
238
239 return codec->toUnicode(result.data(), result.length());
240}
241
242TQString decodeRFC2047String(const TQCString &src)
243{
244 const char *usedCS;
245 return decodeRFC2047String(src, &usedCS, "utf-8", false);
246}
247
248TQCString encodeRFC2047String(const TQString &src, const char *charset,
249 bool addressHeader, bool allow8BitHeaders)
250{
251 TQCString encoded8Bit, result, usedCS;
252 unsigned int start=0,end=0;
253 bool nonAscii=false, ok=true, useTQEncoding=false;
254 TQTextCodec *codec=0;
255
256 usedCS=charset;
257 codec=TDEGlobal::charsets()->codecForName(usedCS, ok);
258
259 if(!ok) {
260 //no codec available => try local8Bit and hope the best ;-)
261 usedCS=TDEGlobal::locale()->encoding();
262 codec=TDEGlobal::charsets()->codecForName(usedCS, ok);
263 }
264
265 if (usedCS.find("8859-")>=0) // use "B"-Encoding for non iso-8859-x charsets
266 useTQEncoding=true;
267
268 encoded8Bit=codec->fromUnicode(src);
269
270 if(allow8BitHeaders)
271 return encoded8Bit;
272
273 uint encoded8BitLength = encoded8Bit.length();
274 for (unsigned int i=0; i<encoded8BitLength; i++) {
275 if (encoded8Bit[i]==' ') // encoding starts at word boundaries
276 start = i+1;
277
278 // encode escape character, for japanese encodings...
279 if (((signed char)encoded8Bit[i]<0) || (encoded8Bit[i] == '\033') ||
280 (addressHeader && (strchr("\"()<>@,.;:\\[]=",encoded8Bit[i])!=0))) {
281 end = start; // non us-ascii char found, now we determine where to stop encoding
282 nonAscii=true;
283 break;
284 }
285 }
286
287 if (nonAscii) {
288 while ((end<encoded8Bit.length())&&(encoded8Bit[end]!=' ')) // we encode complete words
289 end++;
290
291 for (unsigned int x=end;x<encoded8Bit.length();x++)
292 if (((signed char)encoded8Bit[x]<0) || (encoded8Bit[x] == '\033') ||
293 (addressHeader && (strchr("\"()<>@,.;:\\[]=",encoded8Bit[x])!=0))) {
294 end = encoded8Bit.length(); // we found another non-ascii word
295
296 while ((end<encoded8Bit.length())&&(encoded8Bit[end]!=' ')) // we encode complete words
297 end++;
298 }
299
300 result = encoded8Bit.left(start)+"=?"+usedCS;
301
302 if (useTQEncoding) {
303 result += "?Q?";
304
305 char c,hexcode; // implementation of the "Q"-encoding described in RFC 2047
306 for (unsigned int i=start;i<end;i++) {
307 c = encoded8Bit[i];
308 if (c == ' ') // make the result readable with not MIME-capable readers
309 result+='_';
310 else
311 if (((c>='a')&&(c<='z'))|| // paranoid mode, we encode *all* special characters to avoid problems
312 ((c>='A')&&(c<='Z'))|| // with "From" & "To" headers
313 ((c>='0')&&(c<='9')))
314 result+=c;
315 else {
316 result += "="; // "stolen" from KMail ;-)
317 hexcode = ((c & 0xF0) >> 4) + 48;
318 if (hexcode >= 58) hexcode += 7;
319 result += hexcode;
320 hexcode = (c & 0x0F) + 48;
321 if (hexcode >= 58) hexcode += 7;
322 result += hexcode;
323 }
324 }
325 } else {
326 result += "?B?"+KCodecs::base64Encode(encoded8Bit.mid(start,end-start), false);
327 }
328
329 result +="?=";
330 result += encoded8Bit.right(encoded8Bit.length()-end);
331 }
332 else
333 result = encoded8Bit;
334
335 return result;
336}
337
338TQCString uniqueString()
339{
340 static char chars[] = "0123456789abcdefghijklmnopqrstuvxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
341 time_t now;
342 TQCString ret;
343 char p[11];
344 int pos, ran;
345 unsigned int timeval;
346
347 p[10]='\0';
348 now=time(0);
349 ran=1+(int) (1000.0*rand()/(RAND_MAX+1.0));
350 timeval=(now/ran)+getpid();
351
352 for(int i=0; i<10; i++){
353 pos=(int) (61.0*rand()/(RAND_MAX+1.0));
354 //kdDebug(5003) << pos << endl;
355 p[i]=chars[pos];
356 }
357 ret.sprintf("%d.%s", timeval, p);
358
359 return ret;
360}
361
362
363TQCString multiPartBoundary()
364{
365 TQCString ret;
366 ret="nextPart"+uniqueString();
367 return ret;
368}
369
370TQCString extractHeader(const TQCString &src, const char *name)
371{
372 TQCString n=TQCString(name)+":";
373 int pos1=-1, pos2=0, len=src.length()-1;
374 bool folded(false);
375
376 if (n.lower() == src.left(n.length()).lower()) {
377 pos1 = 0;
378 } else {
379 n.prepend("\n");
380 pos1 = src.find(n.data(),0,false);
381 }
382
383 if (pos1>-1) { //there is a header with the given name
384 pos1+=n.length(); //skip the name
385 // skip the usual space after the colon
386 if ( src.at( pos1 ) == ' ' )
387 ++pos1;
388 pos2=pos1;
389
390 if (src[pos2]!='\n') { // check if the header is not empty
391 while(1) {
392 pos2=src.find("\n", pos2+1);
393 if(pos2==-1 || pos2==len || ( src[pos2+1]!=' ' && src[pos2+1]!='\t') ) //break if we reach the end of the string, honor folded lines
394 break;
395 else
396 folded = true;
397 }
398 }
399
400 if(pos2<0) pos2=len+1; //take the rest of the string
401
402 if (!folded)
403 return src.mid(pos1, pos2-pos1);
404 else
405 return (src.mid(pos1, pos2-pos1).replace(TQRegExp("\\s*\\n\\s*")," "));
406 }
407 else {
408 return TQCString(0); //header not found
409 }
410}
411
412
413TQCString CRLFtoLF(const TQCString &s)
414{
415 TQCString ret=s.copy();
416 ret.replace(TQRegExp("\\r\\n"), "\n");
417 return ret;
418}
419
420
421TQCString CRLFtoLF(const char *s)
422{
423 TQCString ret=s;
424 ret.replace(TQRegExp("\\r\\n"), "\n");
425 return ret;
426}
427
428
429TQCString LFtoCRLF(const TQCString &s)
430{
431 TQCString ret=s.copy();
432 ret.replace(TQRegExp("\\n"), "\r\n");
433 return ret;
434}
435
436
437void removeQuots(TQCString &str)
438{
439 // Removes any quote or backslash caracter
440 str.replace(TQRegExp("[\\\"]"), "");
441}
442
443
444void removeQuots(TQString &str)
445{
446 // Removes any quote or backslash caracter
447 str.replace(TQRegExp("[\\\"]"), "");
448}
449
450
451void addQuotes(TQCString &str, bool forceQuotes)
452{
453 if ( forceQuotes || TQString(str).contains( TQRegExp( TQString( "\"|\\\\|=|\\]|\\[|:|;|,|\\.|,|@|<|>|\\)|\\(" ) ) ) ) {
454 // Adds a backslash in front of any existing quote or backslash caracter
455 str.replace(TQRegExp("([\\\"])"), "\\\\1");
456 // Adds quote at beginning and end of thestring
457 str.insert(0,'"');
458 str.append("\"");
459 }
460}
461
462int DateFormatter::mDaylight = -1;
464 : mFormat( fType ), mCurrentTime( 0 )
465{
466
467}
468
469DateFormatter::~DateFormatter()
470{/*empty*/}
471
472DateFormatter::FormatType
474{
475 return mFormat;
476}
477
478void
480{
481 mFormat = t;
482}
483
484TQString
485DateFormatter::dateString( time_t otime , const TQString& lang ,
486 bool shortFormat, bool includeSecs ) const
487{
488 switch ( mFormat ) {
489 case Fancy:
490 return fancy( otime );
491 break;
492 case Localized:
493 return localized( otime, shortFormat, includeSecs, lang );
494 break;
495 case CTime:
496 return cTime( otime );
497 break;
498 case Iso:
499 return isoDate( otime );
500 break;
501 case Custom:
502 return custom( otime );
503 break;
504 }
505 return TQString();
506}
507
508TQString
509DateFormatter::dateString(const TQDateTime& dtime, const TQString& lang,
510 bool shortFormat, bool includeSecs ) const
511{
512 return DateFormatter::dateString( qdateToTimeT(dtime), lang, shortFormat, includeSecs );
513}
514
515TQCString
516DateFormatter::rfc2822(time_t otime) const
517{
518 TQDateTime tmp;
519 TQCString ret;
520
521 tmp.setTime_t(otime);
522
523 ret = tmp.toString("ddd, dd MMM yyyy hh:mm:ss ").latin1();
524 ret += zone(otime);
525
526 return ret;
527}
528
529TQString
531{
532 if ( mCustomFormat.isEmpty() )
533 return TQString();
534
535 int z = mCustomFormat.find("Z");
536 TQDateTime d;
537 TQString ret = mCustomFormat;
538
539 d.setTime_t(t);
540 if ( z != -1 ) {
541 ret.replace(z,1,zone(t));
542 }
543
544 ret = d.toString(ret);
545
546 return ret;
547}
548
549void
550DateFormatter::setCustomFormat(const TQString& format)
551{
552 mCustomFormat = format;
553 mFormat = Custom;
554}
555
556TQString
557DateFormatter::getCustomFormat() const
558{
559 return mCustomFormat;
560}
561
562
563TQCString
564DateFormatter::zone(time_t otime) const
565{
566 TQCString ret;
567#if defined(HAVE_TIMEZONE) || defined(HAVE_TM_GMTOFF)
568 struct tm *local = localtime( &otime );
569#endif
570
571#if defined(HAVE_TIMEZONE)
572
573 //hmm, could make hours & mins static
574 int secs = abs(timezone);
575 int neg = (timezone>0)?1:0;
576 int hours = secs/3600;
577 int mins = (secs - hours*3600)/60;
578
579 // adjust to daylight
580 if ( local->tm_isdst > 0 ) {
581 mDaylight = 1;
582 if ( neg )
583 --hours;
584 else
585 ++hours;
586 } else
587 mDaylight = 0;
588
589 ret.sprintf("%c%.2d%.2d",(neg)?'-':'+', hours, mins);
590
591#elif defined(HAVE_TM_GMTOFF)
592
593 int secs = abs( local->tm_gmtoff );
594 int neg = (local->tm_gmtoff<0)?1:0; //no, I don't know why it's backwards :o
595 int hours = secs/3600;
596 int mins = (secs - hours*3600)/60;
597
598 if ( local->tm_isdst > 0 )
599 mDaylight = 1;
600 else
601 mDaylight = 0;
602
603 ret.sprintf("%c%.2d%.2d",(neg)?'-':'+', hours, mins);
604
605#else
606
607 TQDateTime d1 = TQDateTime::fromString( asctime(gmtime(&otime)) );
608 TQDateTime d2 = TQDateTime::fromString( asctime(localtime(&otime)) );
609 int secs = d1.secsTo(d2);
610 int neg = (secs<0)?1:0;
611 secs = abs(secs);
612 int hours = secs/3600;
613 int mins = (secs - hours*3600)/60;
614 // daylight should be already taken care of here
615 ret.sprintf("%c%.2d%.2d",(neg)?'-':'+', hours, mins);
616
617#endif /* HAVE_TIMEZONE */
618
619 return ret;
620}
621
622time_t
623DateFormatter::qdateToTimeT(const TQDateTime& dt) const
624{
625 TQDateTime epoch( TQDate(1970, 1,1), TQTime(00,00,00) );
626 time_t otime;
627 time( &otime );
628
629 TQDateTime d1 = TQDateTime::fromString( asctime(gmtime(&otime)) );
630 TQDateTime d2 = TQDateTime::fromString( asctime(localtime(&otime)) );
631 time_t drf = epoch.secsTo( dt ) - d1.secsTo( d2 );
632
633 return drf;
634}
635
636TQString
637DateFormatter::fancy(time_t otime) const
638{
639 TDELocale *locale = TDEGlobal::locale();
640
641 if ( otime <= 0 )
642 return i18n( "unknown" );
643
644 if ( !mCurrentTime ) {
645 time( &mCurrentTime );
646 mDate.setTime_t( mCurrentTime );
647 }
648
649 TQDateTime old;
650 old.setTime_t( otime );
651
652 // not more than an hour in the future
653 if ( mCurrentTime + 60 * 60 >= otime ) {
654 time_t diff = mCurrentTime - otime;
655
656 if ( diff < 24 * 60 * 60 ) {
657 if ( old.date().year() == mDate.date().year() &&
658 old.date().dayOfYear() == mDate.date().dayOfYear() )
659 return i18n( "Today %1" ).arg( locale->
660 formatTime( old.time(), true ) );
661 }
662 if ( diff < 2 * 24 * 60 * 60 ) {
663 TQDateTime yesterday( mDate.addDays( -1 ) );
664 if ( old.date().year() == yesterday.date().year() &&
665 old.date().dayOfYear() == yesterday.date().dayOfYear() )
666 return i18n( "Yesterday %1" ).arg( locale->
667 formatTime( old.time(), true) );
668 }
669 for ( int i = 3; i < 7; i++ )
670 if ( diff < i * 24 * 60 * 60 ) {
671 TQDateTime weekday( mDate.addDays( -i + 1 ) );
672 if ( old.date().year() == weekday.date().year() &&
673 old.date().dayOfYear() == weekday.date().dayOfYear() )
674 return i18n( "1. weekday, 2. time", "%1 %2" ).
675#if KDE_IS_VERSION( 3, 1, 90 )
676 arg( locale->calendar()->weekDayName( old.date() ) ).
677#else
678 arg( locale->weekDayName( old.date().dayOfWeek() ) ).
679#endif
680 arg( locale->formatTime( old.time(), true) );
681 }
682 }
683
684 return locale->formatDateTime( old );
685
686}
687
688TQString
689DateFormatter::localized(time_t otime, bool shortFormat, bool includeSecs,
690 const TQString& localeLanguage ) const
691{
692 TQDateTime tmp;
693 TQString ret;
694 TDELocale *locale = TDEGlobal::locale();
695
696 tmp.setTime_t( otime );
697
698
699 if ( !localeLanguage.isEmpty() ) {
700 locale=new TDELocale(localeLanguage);
701 locale->setLanguage(localeLanguage);
702 locale->setCountry(localeLanguage);
703 ret = locale->formatDateTime( tmp, shortFormat, includeSecs );
704 delete locale;
705 } else {
706 ret = locale->formatDateTime( tmp, shortFormat, includeSecs );
707 }
708
709 return ret;
710}
711
712TQString
713DateFormatter::cTime(time_t otime) const
714{
715 return TQString::fromLatin1( ctime( &otime ) ).stripWhiteSpace() ;
716}
717
718TQString
719DateFormatter::isoDate(time_t otime) const
720{
721 char cstr[64];
722 strftime( cstr, 63, "%Y-%m-%d %H:%M:%S", localtime(&otime) );
723 return TQString( cstr );
724}
725
726
727void
729{
730 mCurrentTime = 0;
731}
732
733TQString
734DateFormatter::formatDate(DateFormatter::FormatType t, time_t otime,
735 const TQString& data, bool shortFormat, bool includeSecs )
736{
737 DateFormatter f( t );
738 if ( t == DateFormatter::Custom ) {
739 f.setCustomFormat( data );
740 }
741 return f.dateString( otime, data, shortFormat, includeSecs );
742}
743
744TQString
745DateFormatter::formatCurrentDate( DateFormatter::FormatType t, const TQString& data,
746 bool shortFormat, bool includeSecs )
747{
748 DateFormatter f( t );
749 if ( t == DateFormatter::Custom ) {
750 f.setCustomFormat( data );
751 }
752 return f.dateString( time(0), data, shortFormat, includeSecs );
753}
754
755TQCString
757{
759 return f.rfc2822( t );
760}
761
762bool
763DateFormatter::isDaylight()
764{
765 if ( mDaylight == -1 ) {
766 time_t ntime = time( 0 );
767 struct tm *local = localtime( &ntime );
768 if ( local->tm_isdst > 0 ) {
769 mDaylight = 1;
770 return true;
771 } else {
772 mDaylight = 0;
773 return false;
774 }
775 } else if ( mDaylight != 0 )
776 return true;
777 else
778 return false;
779}
780
781} // namespace KMime
class abstracting date formatting
Definition: kmime_util.h:194
void setFormat(FormatType t)
sets the currently used format
Definition: kmime_util.cpp:479
void reset()
resets the internal clock
Definition: kmime_util.cpp:728
TQCString rfc2822(time_t otime) const
returns rfc2822 formatted string
Definition: kmime_util.cpp:516
FormatType getFormat() const
returns the currently set format
Definition: kmime_util.cpp:473
TQString custom(time_t t) const
returns date formatted with the earlier given custom format
Definition: kmime_util.cpp:530
TQString dateString(time_t otime, const TQString &lang=TQString(), bool shortFormat=true, bool includeSecs=false) const
returns formatted date string in a currently set format.
Definition: kmime_util.cpp:485
static TQString formatCurrentDate(DateFormatter::FormatType t, const TQString &data=TQString(), bool shortFormat=true, bool includeSecs=false)
convenience function, same as formatDate but returns the current time formatted
Definition: kmime_util.cpp:745
TQCString zone(time_t otime) const
returns a string identifying the timezone (eg.
Definition: kmime_util.cpp:564
DateFormatter(FormatType fType=DateFormatter::Fancy)
constructor
Definition: kmime_util.cpp:463
static TQCString rfc2822FormatDate(time_t time)
convenience function, same as rfc2822
Definition: kmime_util.cpp:756
TQString isoDate(time_t otime) const
returns a string in the "%Y-%m-%d %H:%M:%S" format
Definition: kmime_util.cpp:719
static TQString formatDate(DateFormatter::FormatType t, time_t time, const TQString &data=TQString(), bool shortFormat=true, bool includeSecs=false)
convenience function dateString
Definition: kmime_util.cpp:734
void setCustomFormat(const TQString &format)
makes the class use the custom format for date to string conversions.
Definition: kmime_util.cpp:550
TQString fancy(time_t otime) const
returns fancy formatted date string
Definition: kmime_util.cpp:637
TQString cTime(time_t otime) const
returns string as formatted with ctime function
Definition: kmime_util.cpp:713
TQString localized(time_t otime, bool shortFormat=true, bool includeSecs=false, const TQString &localeLanguage=TQString()) const
returns localized formatted date string
Definition: kmime_util.cpp:689