~ubuntu-branches/ubuntu/gutsy/kde4libs/gutsy

« back to all changes in this revision

Viewing changes to kdecore/kcalendarsystemhebrew.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Jonathan Riddell
  • Date: 2007-02-21 11:00:12 UTC
  • mfrom: (1.1.1 upstream)
  • Revision ID: james.westby@ubuntu.com-20070221110012-6kw8khr9knv6lmg1
Tags: 3.80.3-0ubuntu1
New upstream unstable release

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*
2
 
   Copyright (c) 2003 Hans Petter Bieker <bieker@kde.org>
3
 
       Calendar conversion routines based on Hdate v6, by Amos
4
 
       Shapir 1978 (rev. 1985, 1992)
5
 
 
6
 
   This library is free software; you can redistribute it and/or
7
 
   modify it under the terms of the GNU Library General Public
8
 
   License as published by the Free Software Foundation; either
9
 
   version 2 of the License, or (at your option) any later version.
10
 
 
11
 
   This library is distributed in the hope that it will be useful,
12
 
   but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14
 
   Library General Public License for more details.
15
 
 
16
 
   You should have received a copy of the GNU Library General Public License
17
 
   along with this library; see the file COPYING.LIB.  If not, write to
18
 
   the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
19
 
   Boston, MA 02110-1301, USA.
20
 
*/
21
 
 
22
 
// Derived hebrew kde calendar class
23
 
 
24
 
#include "kcalendarsystemhebrew.h"
25
 
 
26
 
#include "kdebug.h"
27
 
#include "klocale.h"
28
 
 
29
 
#include <qdatetime.h>
30
 
#include <qstring.h>
31
 
 
32
 
static int hebrewDaysElapsed(int y);
33
 
static QString num2heb(int num, bool includeMillenium);
34
 
 
35
 
class h_date
36
 
{
37
 
public:
38
 
  int hd_day;
39
 
  int hd_mon;
40
 
  int hd_year;
41
 
  int hd_dw;
42
 
  int hd_flg;
43
 
};
44
 
 
45
 
/*
46
 
 * compute general date structure from hebrew date
47
 
 */
48
 
static class h_date * hebrewToGregorian(int y, int m, int d)
49
 
{
50
 
  static class h_date h;
51
 
  int s;
52
 
 
53
 
  y -= 3744;
54
 
  s = hebrewDaysElapsed(y);
55
 
  d += s;
56
 
  s = hebrewDaysElapsed(y + 1) - s;    /* length of year */
57
 
 
58
 
  if (s > 365 && m > 6 )
59
 
  {
60
 
    --m;
61
 
    d += 30;
62
 
  }
63
 
  d += (59 * (m - 1) + 1) / 2;  /* regular months */
64
 
  /* special cases */
65
 
  if (s % 10 > 4 && m > 2)  /* long Heshvan */
66
 
    d++;
67
 
  if (s % 10 < 4 && m > 3)  /* short Kislev */
68
 
    d--;
69
 
  // ### HPB: Broken in leap years
70
 
  //if (s > 365 && m > 6)  /* leap year */
71
 
  //  d += 30;
72
 
  d -= 6002;
73
 
 
74
 
  y = (d + 36525) * 4 / 146097 - 1;
75
 
  d -= y / 4 * 146097 + (y % 4) * 36524;
76
 
  y *= 100;
77
 
 
78
 
  /* compute year */
79
 
  s = (d + 366)*4/1461-1;
80
 
  d -= s/4*1461 + (s % 4)*365;
81
 
  y += s;
82
 
  /* compute month */
83
 
  m = (d + 245)*12/367-7;
84
 
  d -= m*367/12-30;
85
 
  if (++m >= 12) {
86
 
    m -= 12;
87
 
    y++;
88
 
  }
89
 
  h.hd_day = d;
90
 
  h.hd_mon = m;
91
 
  h.hd_year = y;
92
 
  return(&h);
93
 
}
94
 
 
95
 
/*
96
 
 * compute date structure from no. of days since 1 Tishrei 3744
97
 
 */
98
 
static class h_date * gregorianToHebrew(int y, int m, int d)
99
 
{
100
 
  static class h_date h;
101
 
  int s;
102
 
 
103
 
  if ((m -= 2) <= 0) {
104
 
    m += 12;
105
 
    y--;
106
 
  }
107
 
  /* no. of days, Julian calendar */
108
 
  d += 365*y + y/4 + 367*m/12 + 5968;
109
 
  /* Gregorian calendar */
110
 
  d -= y/100-y/400-2;
111
 
  h.hd_dw = (d + 1) % 7;
112
 
 
113
 
  /* compute the year */
114
 
  y += 16;
115
 
  s = hebrewDaysElapsed(y);
116
 
  m = hebrewDaysElapsed(y + 1);
117
 
  while(d >= m) {  /* computed year was underestimated */
118
 
    s = m;
119
 
    y++;
120
 
    m = hebrewDaysElapsed(y + 1);
121
 
  }
122
 
  d -= s;
123
 
  s = m-s;  /* size of current year */
124
 
  y += 3744;
125
 
 
126
 
  h.hd_flg = s % 10-4;
127
 
 
128
 
  /* compute day and month */
129
 
  if (d >= s-236) {  /* last 8 months are regular */
130
 
    d -= s-236;
131
 
    m = d*2/59;
132
 
    d -= (m*59 + 1)/2;
133
 
    m += 4;
134
 
    if (s > 365 && m <= 5)  /* Adar of Meuberet */
135
 
      m += 8;
136
 
  } else {
137
 
    /* first 4 months have 117-119 days */
138
 
    s = 114 + s % 10;
139
 
    m = d * 4 / s;
140
 
    d -= (m * s + 3) / 4;
141
 
  }
142
 
 
143
 
  h.hd_day = d;
144
 
  h.hd_mon = m;
145
 
  h.hd_year = y;
146
 
  return(&h);
147
 
}
148
 
 
149
 
static QString num2heb(int num, bool includeMillenium)
150
 
{
151
 
  const QChar decade[] = {0x05D8, 0x05D9, 0x05DB, 0x05DC, 0x05DE,
152
 
                          0x05E0, 0x05E1, 0x05E2, 0x05E4, 0x05E6};
153
 
  QString result;
154
 
 
155
 
  if (num < 1 || num > 9999)
156
 
    return QString::number(num);
157
 
 
158
 
  if (num >= 1000) {
159
 
    if (includeMillenium || num % 1000 == 0)
160
 
      result += QChar(0x05D0 - 1 + num / 1000);
161
 
    num %= 1000;
162
 
  }
163
 
  if (num >= 100) {
164
 
    while (num >= 500) {
165
 
      result += QChar(0x05EA);
166
 
      num -= 400;
167
 
    }
168
 
    result += QChar(0x05E7 - 1 + num / 100);
169
 
    num %= 100;
170
 
  }
171
 
  if (num >= 10) {
172
 
    if (num == 15 || num == 16)
173
 
      num -= 9;
174
 
    result += decade[num / 10];
175
 
    num %= 10;
176
 
  }
177
 
  if (num > 0)
178
 
    result += QChar(0x05D0 - 1 + num);
179
 
 
180
 
  if (result.length() == 1)
181
 
    result += '\'';
182
 
  else
183
 
    result.insert(result.length() - 1, '\"');
184
 
 
185
 
  return result;
186
 
}
187
 
 
188
 
/* constants, in 1/18th of minute */
189
 
static const int HOUR = 1080;
190
 
static const int DAY = 24*HOUR;
191
 
static const int WEEK = 7*DAY;
192
 
#define M(h,p) ((h)*HOUR+p)
193
 
#define MONTH (DAY+M(12,793))
194
 
 
195
 
/**
196
 
 * @internal
197
 
 * no. of days in y years
198
 
 */
199
 
static int hebrewDaysElapsed(int y)
200
 
{
201
 
  int m, nm, dw, s, l;
202
 
 
203
 
  l = y * 7 + 1;  // no. of leap months
204
 
  m = y*12+l/19;  // total no. of months
205
 
  l %= 19;
206
 
  nm = m*MONTH+M(1+6,779); // molad new year 3744 (16BC) + 6 hours
207
 
  s = m*28+nm/DAY-2;
208
 
 
209
 
  nm %= WEEK;
210
 
  dw = nm/DAY;
211
 
  nm %= DAY;
212
 
 
213
 
  // special cases of Molad Zaken
214
 
  if (l < 12 && dw == 3 && nm >= M(9 + 6,204) ||
215
 
   l < 7 && dw == 2 && nm>=M(15+6,589))
216
 
    s++,dw++;
217
 
  /* ADU */
218
 
  if (dw == 1 || dw == 4 || dw == 6)
219
 
    s++;
220
 
  return s;
221
 
}
222
 
 
223
 
/**
224
 
 * @internal
225
 
 * true if long Cheshvan
226
 
 */
227
 
static int long_cheshvan(int year)
228
 
{
229
 
  QDate first, last;
230
 
  class h_date *gd;
231
 
 
232
 
  gd = hebrewToGregorian(year, 1, 1);
233
 
  first.setYMD(gd->hd_year, gd->hd_mon + 1, gd->hd_day + 1);
234
 
 
235
 
  gd = hebrewToGregorian(year + 1, 1, 1);
236
 
  last.setYMD(gd->hd_year, gd->hd_mon + 1, gd->hd_day + 1);
237
 
 
238
 
  return (first.daysTo(last) % 10 == 5);
239
 
}
240
 
 
241
 
/**
242
 
 * @internal
243
 
 * true if short Kislev
244
 
 */
245
 
static int short_kislev(int year)
246
 
{
247
 
  QDate first, last;
248
 
  class h_date * gd;
249
 
 
250
 
  gd = hebrewToGregorian(year, 1, 1);
251
 
  first.setYMD(gd->hd_year, gd->hd_mon + 1, gd->hd_day + 1);
252
 
 
253
 
  gd = hebrewToGregorian(year + 1, 1, 1);
254
 
  last.setYMD(gd->hd_year, gd->hd_mon + 1, gd->hd_day + 1);
255
 
 
256
 
  return (first.daysTo(last) % 10 == 3);
257
 
}
258
 
 
259
 
static bool is_leap_year(int year)
260
 
{
261
 
  return ((((7 * year) + 1) % 19) < 7);
262
 
}
263
 
 
264
 
// Ok
265
 
KCalendarSystemHebrew::KCalendarSystemHebrew(const KLocale * locale)
266
 
  : KCalendarSystem(locale)
267
 
{
268
 
}
269
 
 
270
 
// Ok
271
 
KCalendarSystemHebrew::~KCalendarSystemHebrew()
272
 
{
273
 
}
274
 
 
275
 
// Ok
276
 
static class h_date * toHebrew(const QDate & date)
277
 
{
278
 
  class h_date *sd;
279
 
  sd = gregorianToHebrew(date.year(), date.month(), date.day());
280
 
  ++sd->hd_mon;
281
 
  ++sd->hd_day;
282
 
  return sd;
283
 
}
284
 
 
285
 
// Ok
286
 
int KCalendarSystemHebrew::year(const QDate& date) const
287
 
{
288
 
  class h_date *sd = toHebrew(date);
289
 
  return sd->hd_year;
290
 
}
291
 
 
292
 
// Ok
293
 
int KCalendarSystemHebrew::monthsInYear( const QDate & date ) const
294
 
{
295
 
  if ( is_leap_year( year(date) ) )
296
 
    return 13;
297
 
  else
298
 
    return 12;
299
 
}
300
 
 
301
 
// Ok
302
 
int KCalendarSystemHebrew::weeksInYear(int year) const
303
 
{
304
 
  QDate temp;
305
 
  setYMD(temp, year, 1, 1);  // don't pass an uninitialized QDate to
306
 
                             // monthsInYear in the next call
307
 
  setYMD(temp, year, monthsInYear(temp), hndays(monthsInYear(temp), year) );
308
 
 
309
 
  int nWeekNumber = weekNumber(temp);
310
 
  if(nWeekNumber == 1)  // last week belongs to next year
311
 
  {
312
 
    temp = temp.addDays(-7);
313
 
    nWeekNumber = weekNumber(temp);
314
 
  }
315
 
 
316
 
  return nWeekNumber;
317
 
}
318
 
 
319
 
int KCalendarSystemHebrew::weekNumber(const QDate& date, int * yearNum) const
320
 
{
321
 
  QDate firstDayWeek1, lastDayOfYear;
322
 
  int y = year(date);
323
 
  int week;
324
 
  int weekDay1, dayOfWeek1InYear;
325
 
 
326
 
  // let's guess 1st day of 1st week
327
 
  setYMD(firstDayWeek1, y, 1, 1);
328
 
  weekDay1 = dayOfWeek(firstDayWeek1);
329
 
 
330
 
  // iso 8601: week 1  is the first containing thursday and week starts on
331
 
  // monday
332
 
  if (weekDay1 > 4 /*Thursday*/)
333
 
    firstDayWeek1 = addDays(firstDayWeek1 , 7 - weekDay1 + 1); // next monday
334
 
 
335
 
  dayOfWeek1InYear = dayOfYear(firstDayWeek1);
336
 
 
337
 
  if ( dayOfYear(date) < dayOfWeek1InYear ) // our date in prev year's week
338
 
  {
339
 
    if ( yearNum )
340
 
      *yearNum = y - 1;
341
 
    return weeksInYear(y - 1);
342
 
  }
343
 
 
344
 
  // let's check if its last week belongs to next year
345
 
  setYMD(lastDayOfYear, y + 1, 1, 1);
346
 
  lastDayOfYear = addDays(lastDayOfYear, -1);
347
 
  if ( (dayOfYear(date) >= daysInYear(date) - dayOfWeek(lastDayOfYear) + 1)
348
 
       // our date is in last week
349
 
       && dayOfWeek(lastDayOfYear) < 4) // 1st week in next year has thursday
350
 
    {
351
 
      if ( yearNum )
352
 
        *yearNum = y + 1;
353
 
      week = 1;
354
 
    }
355
 
  else
356
 
  {
357
 
   if( weekDay1 < 5 ) // To calculate properly the number of weeks
358
 
                     //  from day a to x let's make a day 1 of week
359
 
      firstDayWeek1 = addDays( firstDayWeek1, -( weekDay1 - 1));
360
 
 
361
 
   week = firstDayWeek1.daysTo(date) / 7 + 1;
362
 
  }
363
 
 
364
 
  return week;
365
 
}
366
 
 
367
 
// Ok
368
 
QString KCalendarSystemHebrew::monthName(const QDate& date,
369
 
                                        bool shortName) const
370
 
{
371
 
  return monthName(month(date), year(date), shortName);
372
 
}
373
 
 
374
 
// Ok
375
 
QString KCalendarSystemHebrew::monthNamePossessive(const QDate& date,
376
 
                                                  bool shortName) const
377
 
{
378
 
  return monthNamePossessive(month(date), year(date), shortName);
379
 
}
380
 
 
381
 
// ### Fixme
382
 
QString KCalendarSystemHebrew::monthName(int month, int year, bool /*shortName*/) const
383
 
{
384
 
  if ( month < 1 )
385
 
    return QString();
386
 
  if ( is_leap_year(year) )
387
 
  {
388
 
    if ( month > 13 )
389
 
      return QString();
390
 
  }
391
 
  else if ( month > 12 )
392
 
      return QString();
393
 
 
394
 
  // We must map conversion algorithm month index to real index
395
 
  if( month == 6 && is_leap_year(year) )
396
 
    month = 13; /*Adar I*/
397
 
  else if ( month == 7 && is_leap_year(year) )
398
 
    month = 14; /*Adar II*/
399
 
  else if ( month > 7 && is_leap_year(year) )
400
 
    month--; //Because of Adar II
401
 
 
402
 
  switch(month)
403
 
  {
404
 
  case 1:
405
 
    return ki18n("Tishrey").toString(locale());
406
 
  case 2:
407
 
    return ki18n("Heshvan").toString(locale());
408
 
  case 3:
409
 
    return ki18n("Kislev").toString(locale());
410
 
  case 4:
411
 
    return ki18n("Tevet").toString(locale());
412
 
  case 5:
413
 
    return ki18n("Shvat").toString(locale());
414
 
  case 6:
415
 
    return ki18n("Adar").toString(locale());
416
 
  case 7:
417
 
    return ki18n("Nisan").toString(locale());
418
 
  case 8:
419
 
    return ki18n("Iyar").toString(locale());
420
 
  case 9:
421
 
    return ki18n("Sivan").toString(locale());
422
 
  case 10:
423
 
    return ki18n("Tamuz").toString(locale());
424
 
  case 11:
425
 
    return ki18n("Av").toString(locale());
426
 
  case 12:
427
 
    return ki18n("Elul").toString(locale());
428
 
  case 13:
429
 
    return ki18n("Adar I").toString(locale());
430
 
  case 14:
431
 
    return ki18n("Adar II").toString(locale());
432
 
  default:
433
 
    break;
434
 
  }
435
 
 
436
 
  return QString();
437
 
}
438
 
 
439
 
// ### Fixme
440
 
QString KCalendarSystemHebrew::monthNamePossessive(int month, int year,
441
 
                                                  bool shortName) const
442
 
{
443
 
  return "of " + monthName(month, year, shortName);
444
 
}
445
 
 
446
 
bool KCalendarSystemHebrew::setYMD(QDate & date, int y, int m, int d) const
447
 
{
448
 
  if( y < minValidYear() || y > maxValidYear() )
449
 
    return false;
450
 
  if( m < 1 || m > (is_leap_year(y) ? 13 : 12) )
451
 
    return false;
452
 
  if( d < 1 || d > hndays(m,y) )
453
 
    return false;
454
 
 
455
 
  class h_date * gd = hebrewToGregorian( y, m, d );
456
 
 
457
 
  return date.setYMD(gd->hd_year, gd->hd_mon + 1, gd->hd_day + 1);
458
 
}
459
 
 
460
 
QString KCalendarSystemHebrew::weekDayName(int day, bool shortName) const
461
 
{
462
 
  return KCalendarSystem::weekDayName(day, shortName);
463
 
}
464
 
 
465
 
// Ok
466
 
QString KCalendarSystemHebrew::weekDayName(const QDate& date,
467
 
                                          bool shortName) const
468
 
{
469
 
  return weekDayName(dayOfWeek(date), shortName);
470
 
}
471
 
 
472
 
// Ok
473
 
int KCalendarSystemHebrew::dayOfWeek(const QDate& date) const
474
 
{
475
 
  class h_date *sd = toHebrew(date);
476
 
  if ( sd->hd_dw == 0 )
477
 
    return 7;
478
 
  else
479
 
    return (sd->hd_dw);
480
 
}
481
 
 
482
 
// Ok
483
 
int KCalendarSystemHebrew::dayOfYear(const QDate & date) const
484
 
{
485
 
  QDate first;
486
 
  setYMD(first, year(date), 1, 1);
487
 
 
488
 
  return first.daysTo(date) + 1;
489
 
}
490
 
 
491
 
int KCalendarSystemHebrew::daysInMonth(const QDate& date) const
492
 
{
493
 
  return hndays(month(date), year(date));
494
 
}
495
 
 
496
 
int KCalendarSystemHebrew::hndays(int mon, int year) const
497
 
{
498
 
  if ( mon == 6 && is_leap_year(year) )
499
 
    mon = 13; /*Adar I*/
500
 
  else if ( mon == 7 && is_leap_year(year) )
501
 
    mon = 14; /*Adar II*/
502
 
  else if ( mon > 7 && is_leap_year(year) )
503
 
    mon--; //Because of Adar II
504
 
 
505
 
  if( mon == 8 /*IYYAR*/ || mon == 10 /*TAMUZ*/ ||
506
 
    mon == 12 /*ELUL*/ || mon == 4 /*TEVET*/ ||
507
 
    mon == 14 /*ADAR 2*/||
508
 
    ( mon == 6 /*ADAR*/ && !is_leap_year(year)) ||
509
 
    (mon ==  2 /*CHESHVAN*/ && !long_cheshvan(year)) ||
510
 
    (mon == 3 /*KISLEV*/ && short_kislev(year)))
511
 
    return 29;
512
 
  else
513
 
    return 30;
514
 
}
515
 
 
516
 
// Ok
517
 
// Min valid year that may be converted to QDate
518
 
int KCalendarSystemHebrew::minValidYear() const
519
 
{
520
 
  QDate date(1753, 1, 1);
521
 
 
522
 
  return year(date);
523
 
}
524
 
 
525
 
// Ok
526
 
// Max valid year that may be converted to QDate
527
 
int KCalendarSystemHebrew::maxValidYear() const
528
 
{
529
 
  QDate date(8000, 1, 1);
530
 
 
531
 
  return year(date);
532
 
}
533
 
 
534
 
// Ok
535
 
int KCalendarSystemHebrew::day(const QDate& date) const
536
 
{
537
 
  class h_date *sd = toHebrew(date);
538
 
 
539
 
  return sd->hd_day;
540
 
}
541
 
 
542
 
// Ok
543
 
int KCalendarSystemHebrew::month(const QDate& date) const
544
 
{
545
 
  class h_date *sd = toHebrew(date);
546
 
 
547
 
  int month = sd->hd_mon;
548
 
  if ( is_leap_year( sd->hd_year ) )
549
 
  {
550
 
    if( month == 13 /*AdarI*/ )
551
 
       month = 6;
552
 
    else if( month == 14 /*AdarII*/ )
553
 
       month = 7;
554
 
    else if ( month > 6 && month < 13 )
555
 
      ++month;
556
 
  }
557
 
 
558
 
  return month;
559
 
}
560
 
 
561
 
// Ok
562
 
int KCalendarSystemHebrew::daysInYear(const QDate & date) const
563
 
{
564
 
  QDate first, last;
565
 
  setYMD(first, year(date), 1, 1); // 1 Tishrey
566
 
  setYMD(last, year(date) + 1, 1, 1); // 1 Tishrey the year later
567
 
 
568
 
  return first.daysTo(last);
569
 
}
570
 
 
571
 
// Ok
572
 
int KCalendarSystemHebrew::weekDayOfPray() const
573
 
{
574
 
  return 6; // saturday
575
 
}
576
 
 
577
 
// Ok
578
 
QDate KCalendarSystemHebrew::addDays( const QDate & date, int ndays ) const
579
 
{
580
 
  return date.addDays( ndays );
581
 
}
582
 
 
583
 
// Ok
584
 
QDate KCalendarSystemHebrew::addMonths( const QDate & date, int nmonths ) const
585
 
{
586
 
  QDate result = date;
587
 
 
588
 
  while ( nmonths > 0 )
589
 
  {
590
 
    result = addDays(result, daysInMonth(result));
591
 
    --nmonths;
592
 
  }
593
 
 
594
 
  while ( nmonths < 0 )
595
 
  {
596
 
    // get the number of days in the previous month to be consistent with
597
 
    // addMonths where nmonths > 0
598
 
    int nDaysInMonth = daysInMonth(addDays(result, -day(result)));
599
 
    result = addDays(result, -nDaysInMonth);
600
 
    ++nmonths;
601
 
  }
602
 
 
603
 
  return result;
604
 
}
605
 
 
606
 
// Ok
607
 
QDate KCalendarSystemHebrew::addYears( const QDate & date, int nyears ) const
608
 
{
609
 
  QDate result = date;
610
 
  int y = year(date) + nyears;
611
 
 
612
 
  setYMD( result, y, month(date), day(date) );
613
 
 
614
 
  return result;
615
 
}
616
 
 
617
 
// Ok
618
 
QString KCalendarSystemHebrew::calendarName() const
619
 
{
620
 
  return QLatin1String("hebrew");
621
 
}
622
 
 
623
 
// Ok
624
 
bool KCalendarSystemHebrew::isLunar() const
625
 
{
626
 
  return false;
627
 
}
628
 
 
629
 
// Ok
630
 
bool KCalendarSystemHebrew::isLunisolar() const
631
 
{
632
 
  return true;
633
 
}
634
 
 
635
 
// Ok
636
 
bool KCalendarSystemHebrew::isSolar() const
637
 
{
638
 
  return false;
639
 
}
640
 
 
641
 
QString KCalendarSystemHebrew::dayString(const QDate & pDate, bool bShort) const
642
 
{
643
 
  QString sResult;
644
 
 
645
 
  // Only use hebrew numbers if the hebrew setting is selected
646
 
  if (locale()->language() == QLatin1String("he"))
647
 
    sResult = num2heb(day(pDate), false);
648
 
  else
649
 
    sResult = KCalendarSystem::dayString(pDate, bShort);
650
 
 
651
 
  return sResult;
652
 
}
653
 
 
654
 
QString KCalendarSystemHebrew::yearString(const QDate & pDate, bool bShort) const
655
 
{
656
 
  QString sResult;
657
 
 
658
 
  // Only use hebrew numbers if the hebrew setting is selected
659
 
  if (locale()->language() == QLatin1String("he"))
660
 
    sResult = num2heb(year(pDate), !bShort);
661
 
  else
662
 
    sResult = KCalendarSystem::yearString(pDate, bShort);
663
 
 
664
 
  return sResult;
665
 
}
666
 
 
667
 
static int heb2num(const QString& str, int & iLength) {
668
 
  QChar c;
669
 
  QString s = str;
670
 
  int result = 0;
671
 
  iLength = 0;
672
 
  int decadeValues[14] = {10, 20, 20, 30, 40, 40, 50,
673
 
                          50, 60, 70, 80, 80, 90, 90};
674
 
 
675
 
  int pos;
676
 
  for (pos = 0 ; pos < s.length() ; pos++)
677
 
  {
678
 
    c = s[pos];
679
 
    if (s.length() > pos && (s[pos + 1] == QChar('\'') ||
680
 
                             s[pos + 1] == QChar('\"')))
681
 
    {
682
 
      iLength++;
683
 
      s.remove(pos + 1, 1);
684
 
    }
685
 
 
686
 
    if (c >= QChar(0x05D0) && c <= QChar(0x05D7))
687
 
    {
688
 
      if (s.length() > pos && s[pos + 1] >= QChar(0x05D0) &&
689
 
          s[pos + 1] <= QChar(0x05EA))
690
 
        result += (c.unicode() - 0x05D0 + 1) * 1000;
691
 
      else
692
 
        result += c.unicode() - 0x05D0 + 1;
693
 
    }
694
 
    else if (c == QChar(0x05D8))
695
 
    {
696
 
      if (s.length() > pos && s[pos + 1] >= QChar(0x05D0) &&
697
 
          s[pos + 1] <= QChar(0x05EA) && s[pos + 1] != QChar(0x05D5) &&
698
 
          s[pos + 1] != QChar(0x05D6))
699
 
        result += 9000;
700
 
      else
701
 
        result += 9;
702
 
    }
703
 
    else if (c >= QChar(0x05D9) && c <= QChar(0x05E6))
704
 
    {
705
 
      if (s.length() > pos && s[pos + 1] >= QChar(0x05D9))
706
 
        return -1;
707
 
      else
708
 
        result += decadeValues[c.unicode() - 0x05D9];
709
 
    }
710
 
    else if (c >= QChar(0x05E7) && c <= QChar(0x05EA))
711
 
    {
712
 
      result += (c.unicode() - 0x05E7 + 1) * 100;
713
 
    }
714
 
    else
715
 
    {
716
 
      break;
717
 
    }
718
 
  }
719
 
 
720
 
  iLength += pos;
721
 
 
722
 
  return result;
723
 
}
724
 
 
725
 
int KCalendarSystemHebrew::dayStringToInteger(const QString & sNum, int & iLength) const
726
 
{
727
 
  int iResult;
728
 
  if (locale()->language() == "he")
729
 
    iResult= heb2num(sNum, iLength);
730
 
  else
731
 
    iResult = KCalendarSystem::yearStringToInteger(sNum, iLength);
732
 
 
733
 
  return iResult;
734
 
}
735
 
 
736
 
int KCalendarSystemHebrew::yearStringToInteger(const QString & sNum, int & iLength) const
737
 
{
738
 
  int iResult;
739
 
  if (locale()->language() == "he")
740
 
    iResult = heb2num(sNum, iLength);
741
 
  else
742
 
    iResult = KCalendarSystem::yearStringToInteger(sNum, iLength);
743
 
 
744
 
  if (iResult < 1000)
745
 
    iResult += 5000; // assume we're in the 6th millenium (y6k bug)
746
 
 
747
 
  return iResult;
748
 
}
749