/********************************************************************** ** Copyright (C) 2000-2006 Trolltech AS. All rights reserved. ** ** This file is part of the Qtopia Environment. ** ** This program is free software; you can redistribute it and/or modify it ** under the terms of the GNU General Public License as published by the ** Free Software Foundation; either version 2 of the License, or (at your ** option) any later version. ** ** A copy of the GNU GPL license version 2 is included in this package as ** LICENSE.GPL. ** ** This program is distributed in the hope that it will be useful, but ** WITHOUT ANY WARRANTY; without even the implied warranty of ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. ** See the GNU General Public License for more details. ** ** In addition, as a special exception Trolltech gives permission to link ** the code of this program with Qtopia applications copyrighted, developed ** and distributed by Trolltech under the terms of the Qtopia Personal Use ** License Agreement. You must comply with the GNU General Public License ** in all respects for all of the code used other than the applications ** licensed under the Qtopia Personal Use License Agreement. If you modify ** this file, you may extend this exception to your version of the file, ** but you are not obligated to do so. If you do not wish to do so, delete ** this exception statement from your version. ** ** See http://www.trolltech.com/gpl/ for GPL licensing information. ** ** Contact info@trolltech.com if any conditions of this licensing are ** not clear to you. ** **********************************************************************/ #include "timestring.h" #include #include #include #include "config.h" #include class TimeStringFormat : public QObject { Q_OBJECT public: static DateFormat currentFormat() { if ( !self ) self = new TimeStringFormat; return self->format; } private slots: void formatChanged( DateFormat f ) { format = f; } private: static TimeStringFormat *self; DateFormat format; TimeStringFormat() : QObject( qApp ) { Config config("qpe"); config.setGroup( "Date" ); format = ::DateFormat(QChar(config.readEntry("Separator", "/")[0]), (::DateFormat::Order)config.readNumEntry("ShortOrder", ::DateFormat::DayMonthYear), (::DateFormat::Order)config.readNumEntry("LongOrder", ::DateFormat::DayMonthYear)); connect( qApp, SIGNAL( dateFormatChanged(DateFormat) ), this, SLOT( formatChanged(DateFormat) ) ); } }; TimeStringFormat *TimeStringFormat::self = 0; QString DateFormat::toNumberString() const { QString buf = ""; // for each part of the order for (int i = 0; i < 3; i++) { // switch on the relavent 3 bits. switch((_shortOrder >> (i * 3)) & 0x0007) { case 0x0001: buf += TimeStringFormat::tr( "D", "first letter of the word 'Day'" ); break; case 0x0002: buf += TimeStringFormat::tr( "M" , "first letter of the word 'Month'" ); break; case 0x0004: buf += TimeStringFormat::tr( "Y" , "first letter of the word 'Year'" ); break; } if (i < 2) buf += _shortSeparator; } return buf; } QString DateFormat::toWordString() const { QString buf = ""; // for each part of the order for (int i = 0; i < 3; i++) { // switch on the relavent 3 bits. switch((_longOrder >> (i * 3)) & 0x0007) { case 0x0001: buf += TimeStringFormat::tr( "day", "in month" ); if (i < 2) { if ((_shortOrder << ((i+1) * 3)) & 0x0007) buf += ", "; else buf += " "; } break; case 0x0002: buf += TimeStringFormat::tr( "month" ); if (i < 2) buf += " "; break; case 0x0004: buf += TimeStringFormat::tr( "year" ); if (i < 2) buf += ", "; break; } } return buf; } QString DateFormat::numberDate(const QDate &d, int v) const { QString buf = ""; int pad = 2; // for each part of the order for (int i = 0; i < 3; i++) { // switch on the relavent 3 bits. switch((_shortOrder >> (i * 3)) & 0x0007) { case 0x0001: if (pad==2) buf += QString().sprintf("%02d",d.day()); else buf += QString().sprintf("%d",d.day()); break; case 0x0002: if (i==0) { // no padding with only MM/DD/YY format pad=0; } if (pad==2) buf += QString().sprintf("%02d",d.month()); else buf += QString().sprintf("%d",d.month()); break; case 0x0004: { int year = d.year(); if (!(v & longNumber)) year = year % 100; buf += QString().sprintf("%02d",year); } break; } if (i < 2) buf += _shortSeparator; } return buf; } static const char* unTranslatedFullMonthNames[] = { QT_TRANSLATE_NOOP( "QDate", "January" ), QT_TRANSLATE_NOOP( "QDate", "February" ), QT_TRANSLATE_NOOP( "QDate", "March" ), QT_TRANSLATE_NOOP( "QDate", "April" ), QT_TRANSLATE_NOOP( "QDate", "May" ), QT_TRANSLATE_NOOP( "QDate", "June" ), QT_TRANSLATE_NOOP( "QDate", "July" ), QT_TRANSLATE_NOOP( "QDate", "August" ), QT_TRANSLATE_NOOP( "QDate", "September" ), QT_TRANSLATE_NOOP( "QDate", "October" ), QT_TRANSLATE_NOOP( "QDate", "November" ), QT_TRANSLATE_NOOP( "QDate", "December" ) }; static const char* unTranslatedFullDayNames[] = { QT_TRANSLATE_NOOP( "QDate", "Monday" ), QT_TRANSLATE_NOOP( "QDate", "Tuesday" ), QT_TRANSLATE_NOOP( "QDate", "Wednesday" ), QT_TRANSLATE_NOOP( "QDate", "Thursday" ), QT_TRANSLATE_NOOP( "QDate", "Friday" ), QT_TRANSLATE_NOOP( "QDate", "Saturday" ), QT_TRANSLATE_NOOP( "QDate", "Sunday" ) }; #ifdef QTOPIA_DESKTOP //translations in qt.qm static const char* unTranslatedMediumDayNames[] = { "Mon" , "Tue", "Wed", "Thu", "Fri", "Sat", "Sun" }; static const char* unTranslatedMediumMonthNames[] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" }; #endif static QString dayname(const QDate& d, bool lng) { if (lng && qApp) return qApp->translate("QDate", unTranslatedFullDayNames[d.dayOfWeek()-1]); else { #ifdef QTOPIA_DESKTOP if (qApp) return qApp->translate("QDate", unTranslatedMediumDayNames[ d.dayOfWeek()-1]); #endif return d.dayName(d.dayOfWeek()); } } QString DateFormat::wordDate(const QDate &d, int v) const { // for each part of the order QString weekDay; if (v & showWeekDay) weekDay = ::dayname(d,(v & longWord)); QString date=""; QString sep=""; for (int i = 0; i < 3; i++) { // switch on the relavent 3 bits. int field = (_longOrder >> (i * 3)) & 0x0007; if ( field && !date.isEmpty() ) date += sep; switch (field) { case 0x0001: // Day { QString daysuffix = TimeStringFormat::tr("@day", "day suffix - applies to some asian languages (e.g. Japanese and Trad. Chinese). If it doesn't apply to your language it has to be translated to an '@day' " ); if (i==1) { date += QString().sprintf("%02d",d.day()); if (daysuffix != "@day") date+=daysuffix; sep = TimeStringFormat::tr(",","day-date separator") + " "; } else { date += QString().sprintf("%2d",d.day()); if (daysuffix == "@day") { if (separator()=='.') // 2002/1/11 sep = ". "; else sep = " "; } else { date += daysuffix+" "; sep = " "; } } } break; case 0x0002: // Month { QString monthName; if (v & longWord) monthName = qApp->translate("QDate", unTranslatedFullMonthNames[d.month()-1] ); else { #ifdef QTOPIA_DESKTOP monthName = qApp->translate("QDate", unTranslatedMediumMonthNames[d.month()-1] ); #else monthName = d.monthName( d.month() ); #endif } date += monthName; } sep = " ";//TimeStringFormat::tr(" ","month-date separator"); break; case 0x0004: // Year { int year = d.year(); if (!(v & longNumber)) year = year % 100; if (year < 10) date += "0"; date += QString::number(year); QString yearsuffix = TimeStringFormat::tr("@year", "year suffix - applies to some asian languages (e.g. Japanese and Trad. Chinese). If it doesn't apply to your language it has to be translated to an '@year' " ); if (yearsuffix != "@year") date += yearsuffix; } sep = TimeStringFormat::tr(",","year-date seperator") + " "; break; } } QString r = ""; if ( weekDay.isEmpty() ) r = date; else if ((_longOrder & 0x0007) == 0x0002) r = TimeStringFormat::tr("%1 %2","1=Monday 2=January 12").arg(weekDay).arg(date); else if ( _longOrder ) r = TimeStringFormat::tr("%1, %2","1=Monday 2=12 January").arg(weekDay).arg(date); else r = weekDay; return r; } #ifndef QT_NO_DATASTREAM void DateFormat::save(QDataStream &d) const { d << _shortSeparator.unicode(); uint v= _shortOrder; d << v; v = _longOrder; d << v; } void DateFormat::load(QDataStream &d) { ushort value; d >> value; _shortSeparator = QChar(value); uint v = 0; d >> v; _shortOrder = (Order)v; v = 0; d >> v; _longOrder = (Order)v; } QDataStream &operator<<(QDataStream &s, const DateFormat&df) { df.save(s); return s; } QDataStream &operator>>(QDataStream &s, DateFormat&df) { df.load(s); return s; } #endif QString TimeString::shortDate( const QDate &d, DateFormat dtf ) { return dtf.wordDate(d); } QString TimeString::dateString( const QDate &d, DateFormat dtf ) { return dtf.wordDate(d, DateFormat::longNumber); } QString TimeString::longDateString( const QDate &d, DateFormat dtf ) { return dtf.wordDate(d, DateFormat::showWeekDay | DateFormat::longNumber | DateFormat::longWord); } DateFormat TimeString::currentDateFormat() { return TimeStringFormat::currentFormat(); } QString TimeString::dateString( const QDateTime &dt, bool ampm, bool seconds, DateFormat dtf ) { const QDate& d = dt.date(); const QTime& t = dt.time(); // based on QDateTime::toString() QString buf = timeString(t,ampm,seconds); buf += " "; buf += longDateString( d, dtf ); return buf; } QString TimeString::timeString( const QTime &t, bool ampm, bool seconds ) { if ( !ampm ) { if ( seconds ) return t.toString(); QString r = QString::number(t.hour()); if ( t.hour() < 10 ) r.prepend( "0" ); r.append( ":" ); if ( t.minute() < 10 ) r.append( "0" ); r.append(QString::number(t.minute())); return r; } // ### else the hard case that should disappear in Qt 3.0 QString argString = seconds ? "%4:%5:%6 %7" : "%4:%5 %7"; int hour = t.hour(); QString strMin = QString::number( t.minute() ); QString strSec = QString::number( t.second() ); if ( hour > 12 ) argString = argString.arg( hour - 12, 2 ); else { if ( hour == 0 ) argString = argString.arg( 12 ); else argString = argString.arg( hour, 2 ); } if ( t.minute() < 10 ) strMin.prepend( "0" ); if ( t.second() < 10 ) strSec.prepend( "0" ); argString = argString.arg( strMin ); if ( seconds ) argString = argString.arg( strSec ); if ( hour >= 12 ) argString = argString.arg( TimeStringFormat::tr("PM") ); else argString = argString.arg( TimeStringFormat::tr("AM") ); return argString; } QString TimeString::shortTime( bool ampm, bool seconds ) { // just create a shorter time String QDateTime dtTmp = QDateTime::currentDateTime(); QString strTime = TimeStringFormat::tr( "%1 %2", "1=Monday 2=12:45" ) .arg(::dayname(dtTmp.date(),FALSE)) .arg(timeString( dtTmp.time(), ampm, seconds )); return strTime; } QString TimeString::dateString( const QDateTime &t, bool ampm ) { return dateString(t,ampm,FALSE); } QString TimeString::timeString( const QTime &t, bool ampm) { return timeString(t,ampm,FALSE); } QString TimeString::shortTime( bool ampm ) { return shortTime(ampm,FALSE); } QString TimeString::numberDateString( const QDate &d, DateFormat dtf ) { return dtf.numberDate(d); } QString TimeString::longNumberDateString( const QDate &d, DateFormat dtf ) { return dtf.numberDate(d,DateFormat::longNumber); } /*! Returns date/time \a dt as a string, showing year, month, date, hours, minutes, and seconds. \a len determines the length of the resulting string. The format, including order depends on the user's settings. First availability: Qtopia 1.6 */ //QString TimeString::localYMDHMS( const QDateTime &dt, Length len ) //{ // const QDate& d = dt.date(); // const QTime& t = dt.time(); // return LocalTimeFormat::tr("%1 %2","date,time").arg(localYMD(d,len)).arg(localHMS(t)); //} #include "timestring.moc"