~ubuntu-branches/ubuntu/wily/afnix/wily

« back to all changes in this revision

Viewing changes to src/lib/std/shl/obj/Date.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Anibal Monsalve Salazar
  • Date: 2011-03-16 21:31:18 UTC
  • mfrom: (1.1.2 upstream)
  • Revision ID: james.westby@ubuntu.com-20110316213118-gk4k3ez3e5d2huna
Tags: 2.0.0-1
* QA upload.
* New upstream release
* Debian source format is 3.0 (quilt)
* Fix debhelper-but-no-misc-depends
* Fix ancient-standards-version
* Fix package-contains-linda-override
* debhelper compatibility is 7
* Fix dh-clean-k-is-deprecated

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
// ---------------------------------------------------------------------------
2
 
// - Date.cpp                                                                -
3
 
// - standard object library - date class implementation                     -
4
 
// ---------------------------------------------------------------------------
5
 
// - This program is free software;  you can redistribute it  and/or  modify -
6
 
// - it provided that this copyright notice is kept intact.                  -
7
 
// -                                                                         -
8
 
// - This program  is  distributed in  the hope  that it will be useful, but -
9
 
// - without  any  warranty;  without  even   the   implied    warranty   of -
10
 
// - merchantability or fitness for a particular purpose.  In no event shall -
11
 
// - the copyright holder be liable for any  direct, indirect, incidental or -
12
 
// - special damages arising in any way out of the use of this software.     -
13
 
// ---------------------------------------------------------------------------
14
 
// - copyright (c) 1999-2007 amaury darsch                                   -
15
 
// ---------------------------------------------------------------------------
16
 
 
17
 
#include "Date.hpp"
18
 
#include "Regex.hpp"
19
 
#include "Vector.hpp"
20
 
#include "Integer.hpp"
21
 
#include "Utility.hpp"
22
 
#include "QuarkZone.hpp"
23
 
#include "Exception.hpp"
24
 
#include "cclk.hpp"
25
 
 
26
 
namespace afnix {
27
 
 
28
 
  // -------------------------------------------------------------------------
29
 
  // - private section                                                       -
30
 
  // -------------------------------------------------------------------------
31
 
 
32
 
  // week day string mapping in us/week reference
33
 
  static const long  ATC_MAX_WDAY               = 7;
34
 
  static const char* ATC_DAY_NAME[ATC_MAX_WDAY] = {
35
 
    "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"
36
 
  };
37
 
  // months string mapping
38
 
  static const long  ATC_MAX_YMON               = 12;
39
 
  static const char* ATC_MON_NAME[ATC_MAX_YMON] = {
40
 
    "Jan", "Feb", "Mar", "Apr", "May", "Jun",
41
 
    "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
42
 
  };
43
 
 
44
 
  // number of gregorian days per year  (normal and leap)
45
 
  static const long ATC_YDAY_NORM = 365;
46
 
  static const long ATC_YDAY_LEAP = 366;
47
 
  // number of gregorian days per month (normal and leap)
48
 
  static const long ATC_MDAY_NORM[12] = {
49
 
    31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
50
 
  };
51
 
  static const long ATC_MDAY_LEAP[12] = {
52
 
    31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
53
 
  };
54
 
 
55
 
  // format the day string
56
 
  static String atc_mapwday (const long wday) {
57
 
    if ((wday < 0) || (wday >= ATC_MAX_WDAY))
58
 
      throw Exception ("date-error", "day index is ot of range");
59
 
    return ATC_DAY_NAME[wday];
60
 
  }
61
 
 
62
 
  // format the month string
63
 
  static String atc_mapymon (const long ymon) {
64
 
    if ((ymon < 1) || (ymon > ATC_MAX_YMON))
65
 
      throw Exception ("time-error", "month index is out of range");
66
 
    return ATC_MON_NAME[ymon-1];
67
 
  }
68
 
 
69
 
  // return the absolute value
70
 
  static inline long abs (const long abs) {
71
 
    return (abs < 0) ? -abs : abs;
72
 
  }
73
 
  static inline t_long abs (const t_long abs) {
74
 
    return (abs < 0) ? -abs : abs;
75
 
  }
76
 
 
77
 
  // return true if the year is a leap year
78
 
  static inline bool atc_isleap (const long year) {
79
 
    if (year == 0) return true;
80
 
    // get absolute year
81
 
    long ywrk = abs (year);
82
 
    // 0 is a special case
83
 
    if ((ywrk % 400) == 0) return true;
84
 
    if ((ywrk % 100) == 0) return false;
85
 
    if ((ywrk % 4)   == 0) return true;
86
 
    return false;
87
 
  }
88
 
 
89
 
  // get the number of days in a year
90
 
  static inline t_long atc_yday_in_year (const long year) {
91
 
    t_long yday = atc_isleap (year) ? ATC_YDAY_LEAP : ATC_YDAY_NORM;
92
 
    return yday;
93
 
  }
94
 
 
95
 
  // get the number of seconds in a year
96
 
  static inline t_long atc_ysec_in_year (const long year) {
97
 
    t_long ysec = atc_yday_in_year (year) * (t_long) Time::DSEC;
98
 
    return ysec;
99
 
  }
100
 
 
101
 
  // get the number of days in a year month
102
 
  static inline t_long atc_mday_in_ymon (const long year, const long ymon) {
103
 
    if (atc_isleap (year) == true) return ATC_MDAY_LEAP[ymon];
104
 
    return ATC_MDAY_NORM[ymon];
105
 
  }
106
 
 
107
 
  // get the number of seconds in a year month
108
 
  static inline t_long atc_msec_in_ymon (const long year, const long ymon) {
109
 
    t_long msec = atc_mday_in_ymon (year, ymon) * (t_long) Time::DSEC;
110
 
    return msec;
111
 
  }
112
 
 
113
 
  // trim the day in a year month
114
 
  static inline long atc_trim_in_ymon (const long year, const long ymon,
115
 
                                       const long mday) {
116
 
    long maxd = (long) atc_mday_in_ymon (year, ymon);
117
 
    return (mday <= maxd) ? mday : maxd;
118
 
  }
119
 
 
120
 
  // get the number of days upto a year
121
 
  static t_long atc_yday_to_year (const long year) {
122
 
    // get absolute year
123
 
    long ywrk = abs (year);
124
 
    // iterate upto the year
125
 
    t_long yday = 0LL;
126
 
    for (long i = 0; i < ywrk; i++) {
127
 
      yday += atc_yday_in_year (i);
128
 
    }
129
 
    return yday;
130
 
  }
131
 
 
132
 
  // get the number of seconds upto a year
133
 
  static t_long atc_ysec_to_year (const long year) {
134
 
    t_long ysec = atc_yday_to_year (year) * (t_long) Time::DSEC;
135
 
    return ysec;
136
 
  }
137
 
 
138
 
  // get the number of days upto a month in a specific year
139
 
  static t_long atc_yday_to_ymon (const long year, const long ymon) {
140
 
    t_long yday = 0LL;
141
 
    if (atc_isleap (year) == true) {
142
 
      for (long i = 0; i < ymon; i++) yday += ATC_MDAY_LEAP[i];
143
 
    } else {
144
 
      for (long i = 0; i < ymon; i++) yday += ATC_MDAY_NORM[i];
145
 
    }
146
 
    return yday;
147
 
  }
148
 
 
149
 
  // get the number of seconds upto a month in a specific year
150
 
  static t_long atc_ysec_to_ymon (const long year, const long ymon) {
151
 
    t_long ysec = atc_yday_to_ymon (year, ymon) * (t_long) Time::DSEC;
152
 
    return ysec;
153
 
  }
154
 
 
155
 
  // number of day upto a date
156
 
  static t_long atc_yday_to_date (const long year, const long ymon, 
157
 
                                  const long mday) {
158
 
    t_long yday = 0LL;
159
 
    yday += atc_yday_to_year (year);
160
 
    yday += atc_yday_to_ymon (year, ymon);
161
 
    yday += mday;
162
 
    return yday;
163
 
  }
164
 
 
165
 
  // number of seconds upto a date
166
 
  static t_long atc_ysec_to_date (const long year, const long ymon, 
167
 
                                  const long mday) {
168
 
    t_long ysec = atc_yday_to_date (year, ymon, mday) * (t_long) Time::DSEC;
169
 
    return ysec;
170
 
  }
171
 
 
172
 
  // find the year from an atc clock
173
 
  static long atc_year_from_tclk (const t_long tclk) {
174
 
    // get the absolute clock
175
 
    t_long wclk = abs (tclk);
176
 
    // compute the year by iteration
177
 
    long   year = 0;
178
 
    long   ymax = Utility::maxlong ();
179
 
    t_long cclk = 0LL;
180
 
    while (year < ymax) {
181
 
      cclk += atc_ysec_in_year (year);
182
 
      if (cclk > wclk) break;
183
 
      year++;
184
 
    }
185
 
    return year;
186
 
  }
187
 
 
188
 
  // find the month in a year from an atc clock
189
 
  static long atc_ymon_from_tclk (const t_long tclk, const long year) {
190
 
    // get the absolute clock
191
 
    t_long wclk = abs (tclk);
192
 
    // compute the month by iteration
193
 
    long   ymon = 0;
194
 
    t_long cclk = 0LL;
195
 
    for (long i = 0; i < ATC_MAX_YMON; i++) {
196
 
      cclk += atc_msec_in_ymon (year, i);
197
 
      if (cclk > wclk) break;
198
 
      ymon++;
199
 
    }
200
 
    return ymon;
201
 
  }
202
 
 
203
 
  // the date sructure
204
 
  struct s_date {
205
 
    long d_year; // year
206
 
    long d_yday; // day in year
207
 
    long d_ymon; // month in year [0:11]
208
 
    long d_mday; // month in day  [0:30]
209
 
    long d_wday; // day in week   [0:6]
210
 
    // create a default date
211
 
    s_date (void) {
212
 
      d_year = 0;
213
 
      d_yday = 0;
214
 
      d_ymon = 0;
215
 
      d_mday = 0;
216
 
      d_wday = 6;
217
 
    }
218
 
    // create a specific date
219
 
    s_date (const t_long tclk) {
220
 
      // get the absolute clock
221
 
      t_long wclk = abs (tclk);
222
 
      // get the year
223
 
      d_year = atc_year_from_tclk (wclk);
224
 
      // update the remaining seconds
225
 
      t_long secs = wclk - atc_ysec_to_year (d_year);
226
 
      // get the year day
227
 
      d_yday = (long) (secs / (t_long) Time::DSEC);
228
 
      // get the year month
229
 
      d_ymon = atc_ymon_from_tclk (secs, d_year);
230
 
      // update the remaining seconds
231
 
      secs -= atc_ysec_to_ymon (d_year, d_ymon);
232
 
      // get the month day
233
 
      d_mday = (long) (secs / (t_long) Time::DSEC);
234
 
      if (tclk >= 0) {
235
 
        // get the week day (0000-00-00 is a saturday)
236
 
        d_wday = ((wclk / (t_long)Time::DSEC) + 6) % 7;
237
 
      } else {
238
 
        // update the sign
239
 
        d_year = -d_year;
240
 
        // get the week day (0000-00-00 is a saturday)
241
 
        d_wday = (13 - (atc_yday_in_year (d_year) - d_yday)) % 7;
242
 
      }
243
 
    }
244
 
  };
245
 
 
246
 
  // -------------------------------------------------------------------------
247
 
  // - class section                                                        -
248
 
  // -------------------------------------------------------------------------
249
 
 
250
 
  // create a current date
251
 
 
252
 
  Date::Date (void) {
253
 
    p_date = new s_date (d_tclk);
254
 
  }
255
 
 
256
 
  // create a specific date
257
 
 
258
 
  Date::Date (const t_long tclk) : Time (tclk) {
259
 
    p_date = new s_date (d_tclk);
260
 
  }
261
 
 
262
 
  // create a date by iso specification
263
 
 
264
 
  Date::Date (const String& date) {
265
 
    p_date = nilp;
266
 
    setdate (date);
267
 
  }
268
 
 
269
 
  // create a date by specific elements
270
 
  
271
 
  Date::Date (const long year, const long ymon, const long mday) : Time (0) {
272
 
    p_date = nilp;
273
 
    setdate (year, ymon, mday);
274
 
  }
275
 
 
276
 
  // create a date by specific elements
277
 
  
278
 
  Date::Date (const long year, const long ymon, const long mday,
279
 
              const long hour, const long mins, const long secs) : Time (0) {
280
 
    p_date = nilp;
281
 
    setdate (year, ymon, mday, hour, mins, secs);
282
 
  }
283
 
 
284
 
  // copy construct this date
285
 
 
286
 
  Date::Date (const Date& that) {
287
 
    that.rdlock ();
288
 
    p_date = nilp;
289
 
    settime (that.gettime ());
290
 
    that.unlock ();
291
 
  }
292
 
 
293
 
  // destroy this date
294
 
 
295
 
  Date::~Date (void) {
296
 
    delete p_date;
297
 
  }
298
 
 
299
 
  // return the class name
300
 
 
301
 
  String Date::repr (void) const {
302
 
    return "Date";
303
 
  }
304
 
 
305
 
  // return a clone of this object
306
 
 
307
 
  Object* Date::clone (void) const {
308
 
    return new Date (*this);
309
 
  }
310
 
 
311
 
  // set the date by specific time
312
 
 
313
 
  void Date::settime (const t_long tclk) {
314
 
    wrlock ();
315
 
    try {
316
 
      delete p_date;
317
 
      Time::settime (tclk);
318
 
      p_date = new s_date (d_tclk);
319
 
      unlock ();
320
 
    } catch (...) {
321
 
      unlock ();
322
 
      throw;
323
 
    }
324
 
  }
325
 
 
326
 
  // set a date by an iso specification
327
 
 
328
 
  void Date::setdate (const String& date) {
329
 
    wrlock ();
330
 
    try {
331
 
      // extract the date component
332
 
      Regex re ("[($d$d$d$d)-($d$d)-($d$d)T($d$d):($d$d):($d$d)Z]");
333
 
      if (re == date) {
334
 
        if (re.length () != 6) {
335
 
          throw Exception ("internal-error", "invalid parsed date", date);
336
 
        }
337
 
        // get the date data
338
 
        long year = re.getint (0);
339
 
        long ymon = re.getint (1);
340
 
        long mday = re.getint (2);
341
 
        long hour = re.getint (3);
342
 
        long mins = re.getint (4);
343
 
        long secs = re.getint (5);
344
 
        // set the date
345
 
        setdate (year, ymon, mday, hour, mins, secs);
346
 
      } else {
347
 
        throw Exception ("date-error", "invalid date format", date);
348
 
      }
349
 
      unlock ();
350
 
    } catch (...) {
351
 
      unlock ();
352
 
      throw;
353
 
    }
354
 
  }
355
 
 
356
 
  // set the date by specific elements
357
 
  
358
 
  void Date::setdate (const long year, const long ymon, const long mday) {
359
 
    wrlock ();
360
 
    try {
361
 
      t_long tclk = atc_ysec_to_date (year, ymon-1, mday-1);
362
 
      if (year >= 0) {
363
 
        settime (tclk);
364
 
      } else {
365
 
        settime (-tclk);
366
 
      }
367
 
      unlock ();
368
 
    } catch (...) {
369
 
      unlock ();
370
 
      throw;
371
 
    }
372
 
  }
373
 
 
374
 
  // set the date by specific elements
375
 
  
376
 
  void Date::setdate (const long year, const long ymon, const long mday,
377
 
                      const long hour, const long mins, const long secs) {
378
 
    wrlock ();
379
 
    try {
380
 
      // get the date clock
381
 
      t_long tclk = atc_ysec_to_date (year, ymon-1, mday-1);
382
 
      // add the time
383
 
      tclk += (t_long) (hour * HSEC + mins * MSEC + secs);
384
 
      // set the sign and time
385
 
      if (year >= 0) {
386
 
        settime (tclk);
387
 
      } else {
388
 
        settime (-tclk);
389
 
      }
390
 
      unlock ();
391
 
    } catch (...) {
392
 
      unlock ();
393
 
      throw;
394
 
    }
395
 
  }
396
 
 
397
 
  // add years to the current date
398
 
 
399
 
  void Date::addyear (const long num) {
400
 
    wrlock ();
401
 
    try {
402
 
      // get the current date
403
 
      long year = getyear ();
404
 
      long ymon = getymon ();
405
 
      long mday = getmday ();
406
 
      long hour = gethour (true);
407
 
      long mins = getmins (true);
408
 
      long secs = getsecs (true);
409
 
      // add the year
410
 
      year += num;
411
 
      // check if the day is valid
412
 
      mday = atc_trim_in_ymon (year, ymon, mday);
413
 
      // update the date
414
 
      setdate (year, ymon, mday, hour, mins, secs);
415
 
      unlock ();
416
 
    } catch (...) {
417
 
      unlock ();
418
 
      throw;
419
 
    }
420
 
  }
421
 
 
422
 
  // add months to the current date
423
 
 
424
 
  void Date::addymon (const long num) {
425
 
    wrlock ();
426
 
    try {
427
 
      // get the current date
428
 
      long year = getyear ();
429
 
      long ymon = getymon ();
430
 
      long mday = getmday ();
431
 
      long hour = gethour (true);
432
 
      long mins = getmins (true);
433
 
      long secs = getsecs (true);
434
 
      // compute number of year and remaining month
435
 
      long ynum = num / 12;
436
 
      long mnum = num % 12;
437
 
      // add the year and month
438
 
      year += ynum;
439
 
      ymon += mnum;
440
 
      // update year to add and month
441
 
      year += ymon / 12;
442
 
      ymon  = ymon % 12;
443
 
      // check if the day is valid
444
 
      mday = atc_trim_in_ymon (year, ymon, mday);
445
 
      // update the date
446
 
      setdate (year, ymon, mday, hour, mins, secs);
447
 
      unlock ();
448
 
    } catch (...) {
449
 
      unlock ();
450
 
      throw;
451
 
    }
452
 
  }
453
 
 
454
 
  // return the date year
455
 
 
456
 
  long Date::getyear (void) const {
457
 
    rdlock ();
458
 
    long result = p_date->d_year;
459
 
    unlock ();
460
 
    return result;
461
 
  }
462
 
 
463
 
  // return the day in the year 
464
 
 
465
 
  long Date::getyday (void) const {
466
 
    rdlock ();
467
 
    long result = p_date->d_yday + 1;
468
 
    unlock ();
469
 
    return result;
470
 
  }
471
 
 
472
 
  // return the month in the year 
473
 
 
474
 
  long Date::getymon (void) const {
475
 
    rdlock ();
476
 
    long result = p_date->d_ymon + 1;
477
 
    unlock ();
478
 
    return result;
479
 
  }
480
 
 
481
 
  // return the day in the month
482
 
 
483
 
  long Date::getmday (void) const {
484
 
    rdlock ();
485
 
    long result = p_date->d_mday + 1;
486
 
    unlock ();
487
 
    return result;
488
 
  }
489
 
 
490
 
  // return the day in the week
491
 
 
492
 
  long Date::getwday (void) const {
493
 
    rdlock ();
494
 
    long result = p_date->d_wday;
495
 
    unlock ();
496
 
    return result;
497
 
  }
498
 
 
499
 
  // return the base day reference time
500
 
 
501
 
  t_long Date::getbday (void) const {
502
 
    rdlock ();
503
 
    t_long result = (d_tclk / DSEC) * DSEC;
504
 
    unlock ();
505
 
    return result;
506
 
  }
507
 
 
508
 
  // return the week day name
509
 
 
510
 
  String Date::mapwday (void) const {
511
 
    rdlock ();
512
 
    try {
513
 
      long wday = getwday ();
514
 
      String result = atc_mapwday (wday);
515
 
      unlock ();
516
 
      return result;
517
 
    } catch (...) {
518
 
      unlock ();
519
 
      throw;
520
 
    }
521
 
  }
522
 
 
523
 
  // return the month name
524
 
 
525
 
  String Date::mapymon (void) const {
526
 
    rdlock ();
527
 
    try {
528
 
      long ymon = getymon ();
529
 
      String result = atc_mapymon (ymon);
530
 
      unlock ();
531
 
      return result;
532
 
    } catch (...) {
533
 
      unlock ();
534
 
      throw;
535
 
    }
536
 
  }
537
 
 
538
 
  // format the date
539
 
 
540
 
  String Date::todate (void) const {
541
 
    rdlock ();
542
 
    try {
543
 
      // check the year
544
 
      long year = getyear ();
545
 
      if (year < 0) {
546
 
        throw Exception ("date-error", 
547
 
                         "ISO-8601 does not define negative year");
548
 
      }
549
 
      if (year > 9999) {        
550
 
        throw Exception ("date-error", 
551
 
                         "ISO-8601 does not define year above 9999");
552
 
      }
553
 
      // format the year
554
 
      String result;
555
 
      if (year < 10) {
556
 
        result += "000";
557
 
      } else if (year < 100) {
558
 
        result += "00";
559
 
      } else if (year < 1000) {
560
 
        result += "0";
561
 
      }
562
 
      result += year;
563
 
      // format the month
564
 
      long ymon = getymon ();
565
 
      if (ymon < 10) {
566
 
        result += "-0";
567
 
      } else {
568
 
        result += "-";
569
 
      }
570
 
      result += ymon;
571
 
      // format the day
572
 
      long mday = getmday ();
573
 
      if (mday < 10) {
574
 
        result += "-0";
575
 
      } else {
576
 
        result += "-";
577
 
      }
578
 
      result += mday;
579
 
      unlock ();
580
 
      return result;
581
 
    } catch (...) {
582
 
      unlock ();
583
 
      throw;
584
 
    }
585
 
  }
586
 
 
587
 
  // format the time
588
 
 
589
 
  String Date::totime (const bool utc) const {
590
 
    rdlock ();
591
 
    try {
592
 
      String result = Time::format (utc);
593
 
      unlock ();
594
 
      return result;
595
 
    } catch (...) {
596
 
      unlock ();
597
 
      throw;
598
 
    }
599
 
  }
600
 
 
601
 
  // format the date in a general form
602
 
  
603
 
  String Date::format (const bool utc) const {
604
 
    rdlock ();
605
 
    try {
606
 
      // format the week day
607
 
      String result = mapwday ();
608
 
      // add the month
609
 
      result += ' ';
610
 
      result += mapymon ();
611
 
      // add the day
612
 
      result += ' ';
613
 
      result += getmday ();
614
 
      // format the time
615
 
      result += ' ';
616
 
      result += totime (utc);
617
 
      // add the year
618
 
      result += ' ';
619
 
      result += getyear ();
620
 
      unlock ();
621
 
      return result;
622
 
    } catch (...) {
623
 
      unlock ();
624
 
      throw;
625
 
    }
626
 
  }
627
 
 
628
 
  // format the date in the ISO-8601 form
629
 
  
630
 
  String Date::toiso (const bool utc) const {
631
 
    rdlock ();
632
 
    try {
633
 
      // format the date
634
 
      String result = todate ();
635
 
      // format the time
636
 
      result += 'T';
637
 
      result += Time::toiso (utc);
638
 
      unlock ();
639
 
      return result;
640
 
    } catch (...) {
641
 
      unlock ();
642
 
      throw;
643
 
    }
644
 
  }
645
 
 
646
 
  // format the date in the RFC-2822 form
647
 
 
648
 
  String Date::torfc (void) const {
649
 
    rdlock ();
650
 
    try {
651
 
      // ap the week day
652
 
      String result = mapwday ();
653
 
      // add the month day
654
 
      long mday = getmday ();
655
 
      if (mday < 10) {
656
 
        result += ", 0";
657
 
      } else {
658
 
        result += ", ";
659
 
      }
660
 
      result += mday;
661
 
      // add the month
662
 
      result += ' ';
663
 
      result += mapymon ();
664
 
      // add the year
665
 
      long year = getyear ();
666
 
      if (year < 10) {
667
 
        result += " 000";
668
 
      } else if (year < 100) {
669
 
        result += " 00";
670
 
      } else if (year < 1000) {
671
 
        result += " 0";
672
 
      } else {
673
 
        result += " ";
674
 
      }
675
 
      result += year;
676
 
      // add the time/zone
677
 
      result += ' ';
678
 
      result += Time::torfc ();
679
 
      unlock ();
680
 
      return result;
681
 
    } catch (...) {
682
 
      unlock ();
683
 
      throw;
684
 
    } 
685
 
  }
686
 
 
687
 
  // -------------------------------------------------------------------------
688
 
  // - object section                                                        -
689
 
  // -------------------------------------------------------------------------
690
 
 
691
 
  // the quark zone
692
 
  static const long QUARK_ZONE_LENGTH = 12;
693
 
  static QuarkZone  zone (QUARK_ZONE_LENGTH);
694
 
 
695
 
  // the object supported quarks
696
 
  static const long QUARK_TODATE  = zone.intern ("to-date");
697
 
  static const long QUARK_TOTIME  = zone.intern ("to-time");
698
 
  static const long QUARK_GETYEAR = zone.intern ("year");
699
 
  static const long QUARK_GETYDAY = zone.intern ("year-day");
700
 
  static const long QUARK_GETYMON = zone.intern ("month");
701
 
  static const long QUARK_GETMDAY = zone.intern ("day");
702
 
  static const long QUARK_ADDYEAR = zone.intern ("add-years");
703
 
  static const long QUARK_ADDYMON = zone.intern ("add-months");  
704
 
  static const long QUARK_GETWDAY = zone.intern ("week-day");
705
 
  static const long QUARK_MAPWDAY = zone.intern ("map-day");
706
 
  static const long QUARK_MAPYMON = zone.intern ("map-month");
707
 
  static const long QUARK_SETDATE = zone.intern ("set-date");
708
 
  static const long QUARK_GETBDAY = zone.intern ("get-base-day");
709
 
 
710
 
  // create a new object in a generic way
711
 
 
712
 
  Object* Date::mknew (Vector* argv) {
713
 
    long argc = (argv == nilp) ? 0 : argv->length ();
714
 
    // create a default time object
715
 
    if (argc == 0) return new Date;
716
 
    if (argc == 1) {
717
 
      Object* obj = argv->get (0);
718
 
      // check for an integer
719
 
      Integer* iobj = dynamic_cast <Integer*> (obj);
720
 
      if (iobj != nilp) return new Date (iobj->tointeger ());
721
 
      // check for a string
722
 
      String* sobj = dynamic_cast <String*> (obj);
723
 
      if (sobj != nilp) return new Date (*sobj);
724
 
      // invalid object
725
 
      throw Exception ("type-error", "invalid object for date",
726
 
                       Object::repr (obj));
727
 
    }
728
 
    // check for 3 arguments
729
 
    if (argc == 3) {
730
 
      long year = argv->getint (0);
731
 
      long ymon = argv->getint (1);
732
 
      long mday = argv->getint (2);
733
 
      return new Date (year, ymon, mday);
734
 
    }
735
 
    // check for 6 arguments
736
 
    if (argc == 6) {
737
 
      long year = argv->getint (0);
738
 
      long ymon = argv->getint (1);
739
 
      long mday = argv->getint (2);
740
 
      long hour = argv->getint (3);
741
 
      long mins = argv->getint (4);
742
 
      long secs = argv->getint (5);
743
 
      return new Date (year, ymon, mday, hour, mins, secs);
744
 
    }
745
 
    throw Exception ("argument-error",
746
 
                     "too many argument with date constructor");
747
 
  }
748
 
 
749
 
  // return true if the given quark is defined
750
 
 
751
 
  bool Date::isquark (const long quark, const bool hflg) const {
752
 
    rdlock ();
753
 
    if (zone.exists (quark) == true) {
754
 
      unlock ();
755
 
      return true;
756
 
    }
757
 
    bool result = hflg ? Time::isquark (quark, hflg) : false;
758
 
    unlock ();
759
 
    return result;
760
 
  }
761
 
 
762
 
  // apply this object with a set of arguments and a quark
763
 
  
764
 
  Object* Date::apply (Runnable* robj, Nameset* nset, const long quark,
765
 
                       Vector* argv) {
766
 
    // get the number of arguments
767
 
    long argc = (argv == nilp) ? 0 : argv->length ();
768
 
 
769
 
    // check for 0 arguments
770
 
    if (argc == 0) {
771
 
      if (quark == QUARK_TODATE)  return new String  (todate  ());
772
 
      if (quark == QUARK_TOTIME)  return new String  (totime  (false));
773
 
      if (quark == QUARK_GETYEAR) return new Integer (getyear ());
774
 
      if (quark == QUARK_GETYDAY) return new Integer (getyday ());
775
 
      if (quark == QUARK_GETYMON) return new Integer (getymon ());
776
 
      if (quark == QUARK_GETMDAY) return new Integer (getmday ());
777
 
      if (quark == QUARK_GETWDAY) return new Integer (getmday ());
778
 
      if (quark == QUARK_GETBDAY) return new Integer (getbday ());
779
 
      if (quark == QUARK_MAPWDAY) return new String  (mapwday ());
780
 
      if (quark == QUARK_MAPYMON) return new String  (mapymon ());
781
 
    }
782
 
    // check for 1 argument
783
 
    if (argc == 1) {
784
 
      if (quark == QUARK_TOTIME) {
785
 
        bool utc = argv->getbool (0);
786
 
        return new String (totime (utc));
787
 
      }
788
 
      if (quark == QUARK_ADDYEAR) {
789
 
        long num = argv->getint (0);
790
 
        addyear (num);
791
 
        return nilp;
792
 
      }
793
 
      if (quark == QUARK_ADDYMON) {
794
 
        long num = argv->getint (0);
795
 
        addymon (num);
796
 
        return nilp;
797
 
      }
798
 
      if (quark == QUARK_SETDATE) {
799
 
        String date = argv->getstring (0);
800
 
        setdate (date);
801
 
        return nilp;
802
 
      }
803
 
    }
804
 
    // check for 3 arguments
805
 
    if (argc == 3) {
806
 
      if (quark == QUARK_SETDATE) {
807
 
        long year = argv->getint (0);
808
 
        long ymon = argv->getint (1);
809
 
        long mday = argv->getint (2);
810
 
        setdate (year, ymon, mday);
811
 
        return nilp;
812
 
      }
813
 
    }
814
 
    // check for 6 arguments
815
 
    if (argc == 6) {
816
 
      if (quark == QUARK_SETDATE) {
817
 
        long year = argv->getint (0);
818
 
        long ymon = argv->getint (1);
819
 
        long mday = argv->getint (2);
820
 
        long hour = argv->getint (3);
821
 
        long mins = argv->getint (4);
822
 
        long secs = argv->getint (5);
823
 
        setdate (year, ymon, mday, hour, mins, secs);
824
 
        return nilp;
825
 
      }
826
 
    }
827
 
    // call the time method
828
 
    return Time::apply (robj, nset, quark, argv);
829
 
  }
830
 
}