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