kspread

kspread_functions_datetime.cc

00001 /* This file is part of the KDE project
00002    Copyright (C) 1998-2003 The KSpread Team
00003                            www.koffice.org/kspread
00004    Copyright (C) 2005 Tomas Mecir <mecirt@gmail.com>
00005 
00006    This library is free software; you can redistribute it and/or
00007    modify it under the terms of the GNU Library General Public
00008    License as published by the Free Software Foundation; either
00009    version 2 of the License.
00010 
00011    This library is distributed in the hope that it will be useful,
00012    but WITHOUT ANY WARRANTY; without even the implied warranty of
00013    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00014    Library General Public License for more details.
00015 
00016    You should have received a copy of the GNU Library General Public License
00017    along with this library; see the file COPYING.LIB.  If not, write to
00018    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
00019  * Boston, MA 02110-1301, USA.
00020 */
00021 
00022 // built-in date/time functions
00023 
00024 #include "functions.h"
00025 #include "kspread_functions_helper.h"
00026 #include "valuecalc.h"
00027 #include "valueconverter.h"
00028 
00029 #include <kcalendarsystem.h>
00030 #include <klocale.h>
00031 
00032 using namespace KSpread;
00033 
00034 // prototypes, sorted
00035 Value func_currentDate (valVector args, ValueCalc *calc, FuncExtra *);
00036 Value func_currentDateTime (valVector args, ValueCalc *calc, FuncExtra *);
00037 Value func_currentTime (valVector args, ValueCalc *calc, FuncExtra *);
00038 Value func_date (valVector args, ValueCalc *calc, FuncExtra *);
00039 Value func_datevalue (valVector args, ValueCalc *calc, FuncExtra *);
00040 Value func_day (valVector args, ValueCalc *calc, FuncExtra *);
00041 Value func_dayname (valVector args, ValueCalc *calc, FuncExtra *);
00042 Value func_dayOfYear (valVector args, ValueCalc *calc, FuncExtra *);
00043 Value func_days (valVector args, ValueCalc *calc, FuncExtra *);
00044 Value func_days360 (valVector args, ValueCalc *calc, FuncExtra *);
00045 Value func_daysInMonth (valVector args, ValueCalc *calc, FuncExtra *);
00046 Value func_daysInYear  (valVector args, ValueCalc *calc, FuncExtra *);
00047 Value func_easterSunday (valVector args, ValueCalc *calc, FuncExtra *);
00048 Value func_edate (valVector args, ValueCalc *calc, FuncExtra *);
00049 Value func_eomonth (valVector args, ValueCalc *calc, FuncExtra *);
00050 Value func_hour (valVector args, ValueCalc *calc, FuncExtra *);
00051 Value func_hours (valVector args, ValueCalc *calc, FuncExtra *);
00052 Value func_isLeapYear  (valVector args, ValueCalc *calc, FuncExtra *);
00053 Value func_isoWeekNum (valVector args, ValueCalc *calc, FuncExtra *);
00054 Value func_minute (valVector args, ValueCalc *calc, FuncExtra *);
00055 Value func_minutes (valVector args, ValueCalc *calc, FuncExtra *);
00056 Value func_month (valVector args, ValueCalc *calc, FuncExtra *);
00057 Value func_monthname (valVector args, ValueCalc *calc, FuncExtra *);
00058 Value func_months (valVector args, ValueCalc *calc, FuncExtra *);
00059 Value func_second (valVector args, ValueCalc *calc, FuncExtra *);
00060 Value func_seconds (valVector args, ValueCalc *calc, FuncExtra *);
00061 Value func_time (valVector args, ValueCalc *calc, FuncExtra *);
00062 Value func_timevalue (valVector args, ValueCalc *calc, FuncExtra *);
00063 Value func_today (valVector args, ValueCalc *calc, FuncExtra *);
00064 Value func_weekday (valVector args, ValueCalc *calc, FuncExtra *);
00065 Value func_weeks (valVector args, ValueCalc *calc, FuncExtra *);
00066 Value func_weeksInYear (valVector args, ValueCalc *calc, FuncExtra *);
00067 Value func_year (valVector args, ValueCalc *calc, FuncExtra *);
00068 Value func_years (valVector args, ValueCalc *calc, FuncExtra *);
00069 
00070 // registers all date/time functions
00071 // sadly, many of these functions aren't Excel compatible
00072 void RegisterDateTimeFunctions()
00073 {
00074   // missing: Excel:    WORKDAY, NETWORKDAYS, WEEKNUM, DATEDIF
00075   //          Gnumeric: UNIX2DATE, DATE2UNIX
00076   // TODO: do we really need DATEVALUE and TIMEVALUE ?
00077   FunctionRepository* repo = FunctionRepository::self();
00078   Function *f;
00079   
00080   f = new Function ("CURRENTDATE",  func_currentDate);
00081   f->setParamCount (0);
00082   repo->add (f);
00083   f = new Function ("CURRENTDATETIME",  func_currentDateTime);
00084   f->setParamCount (0);
00085   repo->add (f);
00086   f = new Function ("CURRENTTIME",  func_currentTime);
00087   f->setParamCount (0);
00088   repo->add (f);
00089   f = new Function ("DATE",  func_date);
00090   f->setParamCount (3);
00091   repo->add (f);
00092   f = new Function ("DATEVALUE",  func_datevalue);
00093   repo->add (f);
00094   f = new Function ("DAY",  func_day);
00095   repo->add (f);
00096   f = new Function ("DAYNAME",  func_dayname);
00097   repo->add (f);
00098   f = new Function ("DAYOFYEAR",  func_dayOfYear);
00099   f->setParamCount (3);
00100   repo->add (f);
00101   f = new Function ("DAYS",  func_days);
00102   f->setParamCount (2);
00103   repo->add (f);
00104   f = new Function ("DAYS360",  func_days360);
00105   f->setParamCount (2, 3);
00106   repo->add (f);
00107   f = new Function ("DAYSINMONTH",  func_daysInMonth);
00108   f->setParamCount (2);
00109   repo->add (f);
00110   f = new Function ("DAYSINYEAR",  func_daysInYear);
00111   repo->add (f);
00112   f = new Function ("EASTERSUNDAY",  func_easterSunday);
00113   repo->add (f);
00114   f = new Function ("EDATE",  func_edate);
00115   f->setParamCount (2);
00116   repo->add (f);
00117   f = new Function ("EOMONTH",  func_eomonth);
00118   f->setParamCount (2);
00119   repo->add (f);
00120   f = new Function ("HOUR",  func_hour);
00121   f->setParamCount (0, 1);
00122   repo->add (f);
00123   f = new Function ("HOURS",  func_hour);  // same as HOUR
00124   f->setParamCount (0, 1);
00125   repo->add (f);
00126   f = new Function ("ISLEAPYEAR",  func_isLeapYear);
00127   repo->add (f);
00128   f = new Function ("ISOWEEKNUM",  func_isoWeekNum);
00129   repo->add (f);
00130   f = new Function ("MINUTE",  func_minute);
00131   f->setParamCount (0, 1);
00132   repo->add (f);
00133   f = new Function ("MINUTES",  func_minute);  // same as MINUTE
00134   f->setParamCount (0, 1);
00135   repo->add (f);
00136   f = new Function ("MONTH",  func_month);
00137   repo->add (f);
00138   f = new Function ("MONTHNAME",  func_monthname);
00139   repo->add (f);
00140   f = new Function ("MONTHS",  func_months);
00141   f->setParamCount (3);
00142   repo->add (f);
00143   f = new Function ("NOW",  func_currentDateTime);
00144   f->setParamCount (0);
00145   repo->add (f);
00146   f = new Function ("SECOND",  func_second);
00147   f->setParamCount (0, 1);
00148   repo->add (f);
00149   f = new Function ("SECONDS",  func_second);  // same as SECOND
00150   f->setParamCount (0, 1);
00151   repo->add (f);
00152   f = new Function ("TIME",  func_time);
00153   f->setParamCount (3);
00154   repo->add (f);
00155   f = new Function ("TIMEVALUE",  func_timevalue);
00156   repo->add (f);
00157   f = new Function ("TODAY",  func_currentDate);
00158   f->setParamCount (0);
00159   repo->add (f);
00160   f = new Function ("WEEKDAY",  func_weekday);
00161   f->setParamCount (1, 2);
00162   repo->add (f);
00163   f = new Function ("WEEKS",  func_weeks);
00164   f->setParamCount (3);
00165   repo->add (f);
00166   f = new Function ("WEEKSINYEAR",  func_weeksInYear);
00167   repo->add (f);
00168   f = new Function ("YEAR",   func_year);
00169   repo->add (f);
00170   f = new Function ("YEARS",  func_years);
00171   f->setParamCount (3);
00172   repo->add (f);
00173 }
00174 
00175 // Function: EDATE
00176 Value func_edate (valVector args, ValueCalc *calc, FuncExtra *)
00177 {
00178   QDate date = calc->conv()->asDate (args[0]).asDate();
00179   int months = calc->conv()->asInteger (args[1]).asInteger();
00180   
00181   date = calc->conv()->locale()->calendar()->addMonths (date, months);
00182 
00183   if (!date.isValid())
00184     return Value::errorVALUE();
00185 
00186   return Value (date);
00187 }
00188 
00189 // Function: EOMONTH
00190 Value func_eomonth (valVector args, ValueCalc *calc, FuncExtra *)
00191 {
00192   // add months to date using EDATE
00193   Value modDate = func_edate (args, calc, 0);
00194   if (modDate.isError()) return modDate;
00195   
00196   // modDate is currently in Date format
00197   QDate date = modDate.asDate();
00198   date.setYMD (date.year(), date.month(), date.daysInMonth());
00199 
00200   return Value (date);
00201 }
00202 
00203 // Function: DAYS360
00204 // algorithm adapted from gnumeric
00205 Value func_days360 (valVector args, ValueCalc *calc, FuncExtra *)
00206 {
00207   QDate date1 = calc->conv()->asDate (args[0]).asDate();
00208   QDate date2 = calc->conv()->asDate (args[1]).asDate();
00209   bool european = false;
00210   if (args.count() == 3)
00211     european = calc->conv()->asBoolean (args[2]).asBoolean();
00212 
00213   int day1, day2;
00214   int month1, month2;
00215   int year1, year2;
00216   bool negative = false;
00217 
00218   if (date1.daysTo( date2 ) < 0)
00219   {
00220     QDate tmp( date1 );
00221     date1 = date2;
00222     date2 = tmp;
00223     negative = true;
00224   }
00225 
00226   day1   = date1.day();
00227   day2   = date2.day();
00228   month1 = date1.month();
00229   month2 = date2.month();
00230   year1  = date1.year();
00231   year2  = date2.year();
00232 
00233   if ( european )
00234   {
00235     if ( day1 == 31 )
00236       day1 = 30;
00237     if ( day2 == 31 )
00238       day2 = 30;
00239   }
00240   else
00241   {
00242     // thanks to the Gnumeric developers for this...
00243     if ( month1 == 2 && month2 == 2
00244          && date1.daysInMonth() == day1
00245          && date2.daysInMonth() == day2 )
00246       day2 = 30;
00247 
00248     if ( month1 == 2 && date1.daysInMonth() == day1 )
00249       day1 = 30;
00250 
00251     if ( day2 == 31 && day1 >= 30 )
00252       day2 = 30;
00253 
00254     if ( day1 == 31 )
00255       day1 = 30;
00256   }
00257 
00258   int result = ( ( year2 - year1 ) * 12 + ( month2 - month1 ) ) * 30
00259     + ( day2 - day1 );
00260 
00261   return Value (result);
00262 }
00263 
00264 // Function: YEAR
00265 Value func_year (valVector args, ValueCalc *calc, FuncExtra *)
00266 {
00267   Value v = calc->conv()->asDate (args[0]);
00268   if (v.isError()) return v;
00269   QDate date = v.asDate();
00270   return Value (date.year ());
00271 }
00272 
00273 // Function: MONTH
00274 Value func_month (valVector args, ValueCalc *calc, FuncExtra *)
00275 {
00276   Value v = calc->conv()->asDate (args[0]);
00277   if (v.isError()) return v;
00278   QDate date = v.asDate();
00279   return Value (date.month ());
00280 }
00281 
00282 // Function: DAY
00283 Value func_day (valVector args, ValueCalc *calc, FuncExtra *)
00284 {
00285   Value v = calc->conv()->asDate (args[0]);
00286   if (v.isError()) return v;
00287   QDate date = v.asDate();
00288   return Value (date.day ());
00289 }
00290 
00291 // Function: HOUR
00292 Value func_hour (valVector args, ValueCalc *calc, FuncExtra *)
00293 {
00294   QTime time;
00295   if (args.count() == 1)
00296   {
00297     Value v = calc->conv()->asTime (args[0]);
00298     if (v.isError()) return v;
00299     time = v.asTime();
00300   }
00301   else
00302     time = QTime::currentTime ();
00303   return Value (time.hour ());
00304 }
00305 
00306 // Function: MINUTE
00307 Value func_minute (valVector args, ValueCalc *calc, FuncExtra *)
00308 {
00309   QTime time;
00310   if (args.count() == 1)
00311   {
00312     Value v = calc->conv()->asTime (args[0]);
00313     if (v.isError()) return v;
00314     time = v.asTime();
00315   }
00316   else
00317     time = QTime::currentTime ();
00318   return Value (time.minute ());
00319 }
00320 
00321 // Function: SECOND
00322 Value func_second (valVector args, ValueCalc *calc, FuncExtra *)
00323 {
00324   QTime time;
00325   if (args.count() == 1)
00326   {
00327     Value v = calc->conv()->asTime (args[0]);
00328     if (v.isError()) return v;
00329     time = v.asTime();
00330   }
00331   else
00332     time = QTime::currentTime ();
00333   return Value (time.second ());
00334 }
00335 
00336 // Function: weekday
00337 Value func_weekday (valVector args, ValueCalc *calc, FuncExtra *)
00338 {
00339   Value v = calc->conv()->asDate (args[0]).asDate();
00340   if (v.isError()) return v;
00341   QDate date = v.asDate();
00342   int method = 1;
00343   if (args.count() == 2)
00344     method = calc->conv()->asInteger (args[1]).asInteger();
00345   
00346   if ( method < 1 || method > 3 )
00347     return Value::errorVALUE();
00348 
00349   int result = date.dayOfWeek();
00350 
00351   if (method == 3)
00352     --result;
00353   else if (method == 1)
00354   {
00355     ++result;
00356     result = result % 7;
00357   }
00358 
00359   return Value (result);
00360 }
00361 
00362 // Function: datevalue
00363 // same result would be obtained by applying number format on a date value
00364 Value func_datevalue (valVector args, ValueCalc *calc, FuncExtra *)
00365 {
00366   return calc->conv()->asFloat (calc->conv()->asDate (args[0]));
00367 }
00368 
00369 // Function: timevalue
00370 // same result would be obtained by applying number format on a time value
00371 Value func_timevalue (valVector args, ValueCalc *calc, FuncExtra *)
00372 {
00373   return calc->conv()->asFloat (calc->conv()->asTime (args[0]));
00374 }
00375 
00376 // Function: years
00377 Value func_years (valVector args, ValueCalc *calc, FuncExtra *)
00378 {
00379   QDate date1 = calc->conv()->asDate (args[0]).asDate();
00380   QDate date2 = calc->conv()->asDate (args[1]).asDate();
00381   if (!date1.isValid() || !date2.isValid())
00382     return Value::errorVALUE();
00383 
00384   int type = calc->conv()->asInteger (args[2]).asInteger();
00385   if (type == 0)
00386   {
00387     // max. possible years between both dates
00388     int years = date2.year() - date1.year();
00389 
00390     if (date2.month() < date1.month())
00391       --years;
00392     else if ( (date2.month() == date1.month()) && (date2.day() < date1.day()) )
00393       --years;
00394 
00395     return Value (years);
00396   }
00397     
00398   // type is non-zero now
00399   // the number of full years in between, starting on 1/1/XXXX
00400   if ( date1.year() == date2.year() )
00401     return Value (0);
00402 
00403   if ( (date1.month() != 1) || (date1.day() != 1) )
00404     date1.setYMD(date1.year() + 1, 1, 1);
00405   date2.setYMD(date2.year(), 1, 1);
00406 
00407   return Value (date2.year() - date1.year());
00408 }
00409 
00410 // Function: months
00411 Value func_months (valVector args, ValueCalc *calc, FuncExtra *)
00412 {
00413   QDate date1 = calc->conv()->asDate (args[0]).asDate();
00414   QDate date2 = calc->conv()->asDate (args[1]).asDate();
00415   if (!date1.isValid() || !date2.isValid())
00416     return Value::errorVALUE();
00417 
00418   int type = calc->conv()->asInteger (args[2]).asInteger();
00419   if (type == 0)
00420   {
00421     int months  = (date2.year() - date1.year()) * 12;
00422     months += date2.month() - date1.month();
00423 
00424     if (date2.day() < date1.day())
00425       if (date2.day() != date2.daysInMonth())
00426         --months;
00427 
00428     return Value (months);
00429   }
00430   
00431   // type is now non-zero
00432   // the number of full months in between, starting on 1/XX/XXXX
00433   if (date1.month() == 12)
00434     date1.setYMD(date1.year() + 1, 1, 1);
00435   else
00436     date1.setYMD(date1.year(), date1.month() + 1, 1);
00437   date2.setYMD(date2.year(), date2.month(), 1);
00438 
00439   int months = (date2.year() - date1.year()) * 12;
00440   months += date2.month() - date1.month();
00441 
00442   return Value (months);
00443 }
00444 
00445 // Function: weeks
00446 Value func_weeks (valVector args, ValueCalc *calc, FuncExtra *)
00447 {
00448   QDate date1 = calc->conv()->asDate (args[0]).asDate();
00449   QDate date2 = calc->conv()->asDate (args[1]).asDate();
00450   if (!date1.isValid() || !date2.isValid())
00451     return Value::errorVALUE();
00452 
00453   int type = calc->conv()->asInteger (args[2]).asInteger();
00454   int days = date1.daysTo (date2);
00455   if (type == 0)
00456     // just the number of full weeks between
00457     return Value ((int) (days / 7));
00458     
00459   // the number of full weeks between starting on mondays
00460   int weekStartDay = calc->conv()->locale()->weekStartDay();
00461   
00462   int dow1 = date1.dayOfWeek();
00463   int dow2 = date2.dayOfWeek();
00464 
00465   days -= (7 + (weekStartDay % 7) - dow1);
00466   days -= ((dow2 - weekStartDay) % 7);
00467 
00468   return Value ((int) (days / 7));
00469 }
00470 
00471 // Function: days
00472 Value func_days (valVector args, ValueCalc *calc, FuncExtra *)
00473 {
00474   QDate date1 = calc->conv()->asDate (args[0]).asDate();
00475   QDate date2 = calc->conv()->asDate (args[1]).asDate();
00476   if (!date1.isValid() || !date2.isValid())
00477     return Value::errorVALUE();
00478 
00479   return Value (date1.daysTo (date2));
00480 }
00481 
00482 // Function: date
00483 Value func_date (valVector args, ValueCalc *calc, FuncExtra *)
00484 {
00485   int y = calc->conv()->asInteger (args[0]).asInteger();
00486   int m = calc->conv()->asInteger (args[1]).asInteger();
00487   int d = calc->conv()->asInteger (args[2]).asInteger();
00488   
00489   QDate _date;
00490   if( _date.setYMD (y, m, d))
00491     return Value (_date);
00492   return Value::errorVALUE();
00493 }
00494 
00495 // Function: day
00496 Value func_dayname (valVector args, ValueCalc *calc, FuncExtra *)
00497 {
00498   int number = calc->conv()->asInteger (args[0]).asInteger();
00499 
00500   QString weekName = calc->conv()->locale()->calendar()->weekDayName (number);
00501   if (weekName.isNull())
00502     return Value::errorVALUE();
00503   return Value (weekName);
00504 }
00505 
00506 // Function: monthname
00507 Value func_monthname (valVector args, ValueCalc *calc, FuncExtra *)
00508 {
00509   int number = calc->conv()->asInteger (args[0]).asInteger();
00510 
00511   QString monthName = calc->conv()->locale()->calendar()->monthName (number,
00512       QDate::currentDate().year());
00513   if (monthName.isNull())
00514     return Value::errorVALUE();
00515   return Value (monthName);
00516 }
00517 
00518 // Function: time
00519 Value func_time (valVector args, ValueCalc *calc, FuncExtra *)
00520 {
00521   int h = calc->conv()->asInteger (args[0]).asInteger();
00522   int m = calc->conv()->asInteger (args[1]).asInteger();
00523   int s = calc->conv()->asInteger (args[2]).asInteger();
00524   
00525   /* normalize the data */
00526   m += s / 60;
00527   s = s % 60;
00528   h += m / 60;
00529   m = m % 60;
00530   // we'll lose hours data that carries over into days
00531   h = h % 24;
00532 
00533   // now carry down hours/minutes for negative minutes/seconds
00534   if (s < 0) {
00535     s += 60;
00536     m -= 1;
00537   }
00538   if (m < 0) {
00539     m += 60;
00540     h -= 1;
00541   }
00542   if (h < 0)
00543     h += 24;
00544 
00545   return Value (QTime (h, m, s));
00546 }
00547 
00548 // Function: currentDate
00549 Value func_currentDate (valVector, ValueCalc *, FuncExtra *)
00550 {
00551   return Value (QDate::currentDate ());
00552 }
00553 
00554 // Function: currentTime
00555 Value func_currentTime (valVector, ValueCalc *, FuncExtra *)
00556 {
00557   return Value (QTime::currentTime ());
00558 }
00559 
00560 // Function: currentDateTime
00561 Value func_currentDateTime (valVector, ValueCalc *, FuncExtra *)
00562 {
00563   return Value (QDateTime::currentDateTime ());
00564 }
00565 
00566 // Function: dayOfYear
00567 Value func_dayOfYear (valVector args, ValueCalc *calc, FuncExtra *)
00568 {
00569   Value date = func_date (args, calc, 0);
00570   if (date.isError()) return date;
00571   return Value (date.asDate().dayOfYear());
00572 }
00573 
00574 // Function: daysInMonth
00575 Value func_daysInMonth (valVector args, ValueCalc *calc, FuncExtra *)
00576 {
00577   int y = calc->conv()->asInteger (args[0]).asInteger();
00578   int m = calc->conv()->asInteger (args[1]).asInteger();
00579   QDate date (y, m, 1);
00580   return Value (date.daysInMonth());
00581 }
00582 
00583 // Function: isLeapYear
00584 Value func_isLeapYear  (valVector args, ValueCalc *calc, FuncExtra *)
00585 {
00586   int y = calc->conv()->asInteger (args[0]).asInteger();
00587   return Value (QDate::leapYear (y));
00588 }
00589 
00590 // Function: daysInYear
00591 Value func_daysInYear  (valVector args, ValueCalc *calc, FuncExtra *)
00592 {
00593   int y = calc->conv()->asInteger (args[0]).asInteger();
00594   return Value (QDate::leapYear (y) ? 366 : 365);
00595 }
00596 
00597 // Function: weeksInYear
00598 Value func_weeksInYear (valVector args, ValueCalc *calc, FuncExtra *)
00599 {
00600   int y = calc->conv()->asInteger (args[0]).asInteger();
00601   QDate date (y, 12, 31);  // last day of the year
00602   return Value (date.weekNumber ());
00603 }
00604 
00605 // Function: easterSunday
00606 Value func_easterSunday (valVector args, ValueCalc *calc, FuncExtra *)
00607 {
00608   int nDay, nMonth;
00609   int nYear = calc->conv()->asInteger (args[0]).asInteger();
00610 
00611   // (Tomas) the person who wrote this should be hanged :>
00612   int B,C,D,E,F,G,H,I,K,L,M,N,O;
00613   N = nYear % 19;
00614   B = int(nYear / 100);
00615   C = nYear % 100;
00616   D = int(B / 4);
00617   E = B % 4;
00618   F = int((B + 8) / 25);
00619   G = int((B - F + 1) / 3);
00620   H = (19 * N + B - D - G + 15) % 30;
00621   I = int(C / 4);
00622   K = C % 4;
00623   L = (32 + 2 * E + 2 * I - H - K) % 7;
00624   M = int((N + 11 * H + 22 * L) / 451);
00625   O = H + L - 7 * M + 114;
00626   nDay = O % 31 + 1;
00627   nMonth = int(O / 31);
00628 
00629   return Value (QDate (nYear, nMonth, nDay));
00630 }
00631 
00632 // Function: isoWeekNum
00633 Value func_isoWeekNum (valVector args, ValueCalc *calc, FuncExtra *)
00634 {
00635   QDate date = calc->conv()->asDate (args[0]).asDate();
00636   if (!date.isValid())
00637       return Value::errorVALUE();
00638 
00639   return Value (date.weekNumber());
00640 }
KDE Home | KDE Accessibility Home | Description of Access Keys