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 
39 using namespace KMime;
40 
41 namespace KMime {
42 
43 TQStrIList c_harsetCache;
44 TQStrIList l_anguageCache;
45 
46 const 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 
57 const 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 
68 bool 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 // "(),.:;<>@[\]
79 const 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 // "(),:;<>@[\]/=?
87 const 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.
95 const 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.
103 const 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!*+-/
111 const 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 
122 TQString 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 
239 TQString decodeRFC2047String(const TQCString &src)
240 {
241  const char *usedCS;
242  return decodeRFC2047String(src, &usedCS, "utf-8", false);
243 }
244 
245 TQCString 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 
335 TQCString 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 
360 TQCString multiPartBoundary()
361 {
362  TQCString ret;
363  ret="nextPart"+uniqueString();
364  return ret;
365 }
366 
367 TQCString 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 
410 TQCString CRLFtoLF(const TQCString &s)
411 {
412  TQCString ret=s.copy();
413  ret.replace(TQRegExp("\\r\\n"), "\n");
414  return ret;
415 }
416 
417 
418 TQCString CRLFtoLF(const char *s)
419 {
420  TQCString ret=s;
421  ret.replace(TQRegExp("\\r\\n"), "\n");
422  return ret;
423 }
424 
425 
426 TQCString LFtoCRLF(const TQCString &s)
427 {
428  TQCString ret=s.copy();
429  ret.replace(TQRegExp("\\n"), "\r\n");
430  return ret;
431 }
432 
433 
434 void removeQuots(TQCString &str)
435 {
436  // Removes any quote or backslash caracter
437  str.replace(TQRegExp("[\\\"]"), "");
438 }
439 
440 
441 void removeQuots(TQString &str)
442 {
443  // Removes any quote or backslash caracter
444  str.replace(TQRegExp("[\\\"]"), "");
445 }
446 
447 
448 void 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 
459 int DateFormatter::mDaylight = -1;
461  : mFormat( fType ), mCurrentTime( 0 )
462 {
463 
464 }
465 
466 DateFormatter::~DateFormatter()
467 {/*empty*/}
468 
469 DateFormatter::FormatType
471 {
472  return mFormat;
473 }
474 
475 void
477 {
478  mFormat = t;
479 }
480 
481 TQString
482 DateFormatter::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 
505 TQString
506 DateFormatter::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 
512 TQCString
513 DateFormatter::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 
526 TQString
527 DateFormatter::custom(time_t t) const
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 
546 void
547 DateFormatter::setCustomFormat(const TQString& format)
548 {
549  mCustomFormat = format;
550  mFormat = Custom;
551 }
552 
553 TQString
554 DateFormatter::getCustomFormat() const
555 {
556  return mCustomFormat;
557 }
558 
559 
560 TQCString
561 DateFormatter::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 
619 time_t
620 DateFormatter::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 
633 TQString
634 DateFormatter::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 
681 TQString
682 DateFormatter::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 
705 TQString
706 DateFormatter::cTime(time_t otime) const
707 {
708  return TQString::fromLatin1( ctime( &otime ) ).stripWhiteSpace() ;
709 }
710 
711 TQString
712 DateFormatter::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 
720 void
722 {
723  mCurrentTime = 0;
724 }
725 
726 TQString
727 DateFormatter::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 
737 TQString
738 DateFormatter::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 
748 TQCString
750 {
751  DateFormatter f;
752  return f.rfc2822( t );
753 }
754 
755 bool
756 DateFormatter::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