home_run 0.9.0-x86-mswin32
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/CHANGELOG +3 -0
- data/LICENSE +19 -0
- data/README.rdoc +314 -0
- data/Rakefile +135 -0
- data/bench/cpu_bench.rb +279 -0
- data/bench/dt_garbage_bench.rb +11 -0
- data/bench/dt_mem_bench.rb +14 -0
- data/bench/garbage_bench.rb +11 -0
- data/bench/mem_bench.rb +14 -0
- data/bin/home_run +91 -0
- data/default.mspec +12 -0
- data/ext/1.8/date_ext.so +0 -0
- data/ext/1.9/date_ext.so +0 -0
- data/ext/date.rb +7 -0
- data/ext/date/format.rb +842 -0
- data/ext/date_ext.c +4548 -0
- data/ext/date_parser.c +367 -0
- data/ext/date_parser.rl +134 -0
- data/ext/datetime.c +2804 -0
- data/ext/extconf.rb +6 -0
- data/spec/date/accessor_spec.rb +176 -0
- data/spec/date/add_month_spec.rb +26 -0
- data/spec/date/add_spec.rb +23 -0
- data/spec/date/boat_spec.rb +38 -0
- data/spec/date/civil_spec.rb +147 -0
- data/spec/date/commercial_spec.rb +153 -0
- data/spec/date/constants_spec.rb +44 -0
- data/spec/date/conversions_spec.rb +246 -0
- data/spec/date/day_spec.rb +73 -0
- data/spec/date/downto_spec.rb +17 -0
- data/spec/date/eql_spec.rb +16 -0
- data/spec/date/format_spec.rb +52 -0
- data/spec/date/gregorian_spec.rb +52 -0
- data/spec/date/hash_spec.rb +11 -0
- data/spec/date/julian_spec.rb +129 -0
- data/spec/date/leap_spec.rb +19 -0
- data/spec/date/minus_month_spec.rb +25 -0
- data/spec/date/minus_spec.rb +51 -0
- data/spec/date/next_prev_spec.rb +108 -0
- data/spec/date/ordinal_spec.rb +83 -0
- data/spec/date/parse_spec.rb +442 -0
- data/spec/date/parsing_spec.rb +77 -0
- data/spec/date/relationship_spec.rb +28 -0
- data/spec/date/step_spec.rb +109 -0
- data/spec/date/strftime_spec.rb +223 -0
- data/spec/date/strptime_spec.rb +201 -0
- data/spec/date/succ_spec.rb +20 -0
- data/spec/date/today_spec.rb +15 -0
- data/spec/date/upto_spec.rb +17 -0
- data/spec/datetime/accessor_spec.rb +218 -0
- data/spec/datetime/add_month_spec.rb +26 -0
- data/spec/datetime/add_spec.rb +36 -0
- data/spec/datetime/boat_spec.rb +43 -0
- data/spec/datetime/constructor_spec.rb +142 -0
- data/spec/datetime/conversions_spec.rb +54 -0
- data/spec/datetime/day_spec.rb +73 -0
- data/spec/datetime/downto_spec.rb +39 -0
- data/spec/datetime/eql_spec.rb +17 -0
- data/spec/datetime/format_spec.rb +59 -0
- data/spec/datetime/hash_spec.rb +11 -0
- data/spec/datetime/leap_spec.rb +19 -0
- data/spec/datetime/minus_month_spec.rb +25 -0
- data/spec/datetime/minus_spec.rb +77 -0
- data/spec/datetime/next_prev_spec.rb +138 -0
- data/spec/datetime/now_spec.rb +18 -0
- data/spec/datetime/parse_spec.rb +390 -0
- data/spec/datetime/parsing_spec.rb +77 -0
- data/spec/datetime/relationship_spec.rb +28 -0
- data/spec/datetime/step_spec.rb +155 -0
- data/spec/datetime/strftime_spec.rb +118 -0
- data/spec/datetime/strptime_spec.rb +117 -0
- data/spec/datetime/succ_spec.rb +24 -0
- data/spec/datetime/upto_spec.rb +39 -0
- data/spec/spec_helper.rb +59 -0
- metadata +154 -0
    
        data/ext/datetime.c
    ADDED
    
    | @@ -0,0 +1,2804 @@ | |
| 1 | 
            +
             | 
| 2 | 
            +
            /* Helper methods */
         | 
| 3 | 
            +
             | 
| 4 | 
            +
            /* Identical for rhrd__valid_civil, but for rhrdt_t.  Not very
         | 
| 5 | 
            +
             * DRY, but the arguments get modified by the method and then
         | 
| 6 | 
            +
             * used to populate the rhrdt_t. Because the rhrd_t field structure
         | 
| 7 | 
            +
             * has a different layout from the rhrdt_t field structure, you
         | 
| 8 | 
            +
             * need separate functions (no duck typing in C). */
         | 
| 9 | 
            +
            int rhrdt__valid_civil(rhrdt_t *dt, long year, long month, long day) {
         | 
| 10 | 
            +
              if (month < 0 && month >= -12) {
         | 
| 11 | 
            +
                month += 13;
         | 
| 12 | 
            +
              }
         | 
| 13 | 
            +
              if (month < 1 || month > 12) {
         | 
| 14 | 
            +
                return 0;
         | 
| 15 | 
            +
              }
         | 
| 16 | 
            +
             | 
| 17 | 
            +
              if (day < 0) {
         | 
| 18 | 
            +
                if (month == 2) {
         | 
| 19 | 
            +
                  day += rhrd__leap_year(year) ? 30 : 29;
         | 
| 20 | 
            +
                } else {
         | 
| 21 | 
            +
                  day += rhrd_days_in_month[month] + 1;
         | 
| 22 | 
            +
                }
         | 
| 23 | 
            +
              }
         | 
| 24 | 
            +
              if (day < 1 || day > 28) {
         | 
| 25 | 
            +
                if (day > 31 || day <= 0) {
         | 
| 26 | 
            +
                  return 0;
         | 
| 27 | 
            +
                } else if (month == 2) {
         | 
| 28 | 
            +
                  if (rhrd__leap_year(year)) {
         | 
| 29 | 
            +
                    if (day > 29) {
         | 
| 30 | 
            +
                      return 0;
         | 
| 31 | 
            +
                    }
         | 
| 32 | 
            +
                  } else if (day > 28) {
         | 
| 33 | 
            +
                    return 0;
         | 
| 34 | 
            +
                  }
         | 
| 35 | 
            +
                } else if (day > rhrd_days_in_month[month]) {
         | 
| 36 | 
            +
                  return 0;
         | 
| 37 | 
            +
                }
         | 
| 38 | 
            +
              }
         | 
| 39 | 
            +
             | 
| 40 | 
            +
              if(!rhrd__valid_civil_limits(year, month, day)) {
         | 
| 41 | 
            +
                return 0;
         | 
| 42 | 
            +
              } 
         | 
| 43 | 
            +
             | 
| 44 | 
            +
              dt->year = year;
         | 
| 45 | 
            +
              dt->month = (unsigned char)month;
         | 
| 46 | 
            +
              dt->day = (unsigned char)day;
         | 
| 47 | 
            +
              dt->flags |= RHR_HAVE_CIVIL;
         | 
| 48 | 
            +
              return 1;
         | 
| 49 | 
            +
            }
         | 
| 50 | 
            +
             | 
| 51 | 
            +
            /* Check if the given offset is valid.  If so, set the offset field
         | 
| 52 | 
            +
             * in the rhrdt_t and return 1.  Otherwise, return 0. */
         | 
| 53 | 
            +
            int rhrdt__valid_offset(rhrdt_t *dt, double offset) {
         | 
| 54 | 
            +
              if (offset < RHR_MIN_OFFSET_FRACT || offset > RHR_MAX_OFFSET_FRACT) {
         | 
| 55 | 
            +
                return 0;
         | 
| 56 | 
            +
              }
         | 
| 57 | 
            +
             | 
| 58 | 
            +
              dt->offset = lround(offset * 1440);
         | 
| 59 | 
            +
              return 1;
         | 
| 60 | 
            +
            }
         | 
| 61 | 
            +
             | 
| 62 | 
            +
            /* Check if the time information consistutes a valid time.  If not, return
         | 
| 63 | 
            +
             * 0.  If so, fill in the fields in the rhrdt_t and return 1.  This handles
         | 
| 64 | 
            +
             * wrap around for negative hour, minute, and second arguments, and handles
         | 
| 65 | 
            +
             * an hour of 24 with no minute or second value as the 0th hour of the next
         | 
| 66 | 
            +
             * day, so either the julian day or civil day fields in the rhrdt_t should
         | 
| 67 | 
            +
             * be filled out before calling this method. */
         | 
| 68 | 
            +
            int rhrdt__valid_time(rhrdt_t *dt, long h, long m, long s, double offset) {
         | 
| 69 | 
            +
              if (h < 0) {
         | 
| 70 | 
            +
                h += 24;
         | 
| 71 | 
            +
              }
         | 
| 72 | 
            +
              if (m < 0) {
         | 
| 73 | 
            +
                m += 60;
         | 
| 74 | 
            +
              }
         | 
| 75 | 
            +
              if (s < 0) {
         | 
| 76 | 
            +
                s += 60;
         | 
| 77 | 
            +
              }
         | 
| 78 | 
            +
             | 
| 79 | 
            +
              if (h == 24 && m == 0 && s == 0) {
         | 
| 80 | 
            +
                RHRDT_FILL_JD(dt)
         | 
| 81 | 
            +
                dt->jd++;
         | 
| 82 | 
            +
                dt->flags &= ~RHR_HAVE_CIVIL;
         | 
| 83 | 
            +
                h = 0;
         | 
| 84 | 
            +
              } else if (h < 0 || m < 0 || s < 0 || h > 23 || m > 59 || s > 59) {
         | 
| 85 | 
            +
                return 0;
         | 
| 86 | 
            +
              }
         | 
| 87 | 
            +
              if(!rhrdt__valid_offset(dt, offset)) {
         | 
| 88 | 
            +
                return 0;
         | 
| 89 | 
            +
              }
         | 
| 90 | 
            +
             | 
| 91 | 
            +
              dt->hour = h;
         | 
| 92 | 
            +
              dt->minute = m;
         | 
| 93 | 
            +
              dt->second = s;
         | 
| 94 | 
            +
              dt->flags |= RHR_HAVE_HMS;
         | 
| 95 | 
            +
              return 1;
         | 
| 96 | 
            +
            }
         | 
| 97 | 
            +
             | 
| 98 | 
            +
            /* Same as rhrd__civil_to_jd for rhrdt_t. */
         | 
| 99 | 
            +
            void rhrdt__civil_to_jd(rhrdt_t *d) {
         | 
| 100 | 
            +
              d->jd = rhrd__ymd_to_jd(d->year, d->month, d->day);
         | 
| 101 | 
            +
              d->flags |= RHR_HAVE_JD;
         | 
| 102 | 
            +
            }
         | 
| 103 | 
            +
             | 
| 104 | 
            +
            /* Same as rhrd__jd_to_civil for rhrdt_t. */
         | 
| 105 | 
            +
            void rhrdt__jd_to_civil(rhrdt_t *date) {
         | 
| 106 | 
            +
              long x, a, b, c, d, e;
         | 
| 107 | 
            +
              x = (long)floor((date->jd - 1867216.25) / 36524.25);
         | 
| 108 | 
            +
              a = date->jd + 1 + x - (long)floor(x / 4.0);
         | 
| 109 | 
            +
              b = a + 1524;
         | 
| 110 | 
            +
              c = (long)floor((b - 122.1) / 365.25);
         | 
| 111 | 
            +
              d = (long)floor(365.25 * c);
         | 
| 112 | 
            +
              e = (long)floor((b - d) / 30.6001);
         | 
| 113 | 
            +
              date->day = b - d - (long)floor(30.6001 * e);
         | 
| 114 | 
            +
              if (e <= 13) {
         | 
| 115 | 
            +
                date->month = e - 1;
         | 
| 116 | 
            +
                date->year = c - 4716;
         | 
| 117 | 
            +
              } else {
         | 
| 118 | 
            +
                date->month = e - 13;
         | 
| 119 | 
            +
                date->year = c - 4715;
         | 
| 120 | 
            +
              }
         | 
| 121 | 
            +
              date->flags |= RHR_HAVE_CIVIL;
         | 
| 122 | 
            +
            }
         | 
| 123 | 
            +
             | 
| 124 | 
            +
            /* Using the stored nanos field, fill in the hour, minute,
         | 
| 125 | 
            +
             * and second fields for the rhrdt_t.  This assumes the
         | 
| 126 | 
            +
             * nanos field has already been filled in. */
         | 
| 127 | 
            +
            void rhrdt__nanos_to_hms(rhrdt_t *d) {
         | 
| 128 | 
            +
              unsigned int seconds;
         | 
| 129 | 
            +
              seconds = d->nanos/RHR_NANOS_PER_SECOND;
         | 
| 130 | 
            +
              d->hour = seconds/RHR_SECONDS_PER_HOUR;
         | 
| 131 | 
            +
              d->minute = (seconds % RHR_SECONDS_PER_HOUR)/60;
         | 
| 132 | 
            +
              d->second = seconds % 60;
         | 
| 133 | 
            +
              d->flags |= RHR_HAVE_HMS;
         | 
| 134 | 
            +
            }
         | 
| 135 | 
            +
             | 
| 136 | 
            +
            /* Using the stored hour, minute, and second fields, fill in
         | 
| 137 | 
            +
             * the nanos field for th rhrdt_t. This assumes the hour, minute
         | 
| 138 | 
            +
             * and second fields have already been filled in. */
         | 
| 139 | 
            +
            void rhrdt__hms_to_nanos(rhrdt_t *d) {
         | 
| 140 | 
            +
              d->nanos = (d->hour*RHR_SECONDS_PER_HOUR + d->minute*60 + d->second)*RHR_NANOS_PER_SECOND;
         | 
| 141 | 
            +
              d->flags |= RHR_HAVE_NANOS;
         | 
| 142 | 
            +
            }
         | 
| 143 | 
            +
             | 
| 144 | 
            +
            /* Same as rhrd__valid_commercial, for rhrdt_t. */
         | 
| 145 | 
            +
            int rhrdt__valid_commercial(rhrdt_t *d, long cwyear, long cweek, long cwday) {
         | 
| 146 | 
            +
              rhrd_t n;
         | 
| 147 | 
            +
              memset(&n, 0, sizeof(rhrd_t));
         | 
| 148 | 
            +
             | 
| 149 | 
            +
              if (cwday < 0) {
         | 
| 150 | 
            +
                if (cwday < -8) {
         | 
| 151 | 
            +
                  return 0;
         | 
| 152 | 
            +
                }
         | 
| 153 | 
            +
                cwday += 8;
         | 
| 154 | 
            +
              }
         | 
| 155 | 
            +
              if (cweek < 0) {
         | 
| 156 | 
            +
                if (cweek < -53) {
         | 
| 157 | 
            +
                  return 0;
         | 
| 158 | 
            +
                }
         | 
| 159 | 
            +
                n.jd = rhrd__commercial_to_jd(cwyear + 1, 1, 1) + cweek * 7;
         | 
| 160 | 
            +
                rhrd__fill_commercial(&n);
         | 
| 161 | 
            +
                if (n.year != cwyear) {
         | 
| 162 | 
            +
                  return 0;
         | 
| 163 | 
            +
                }
         | 
| 164 | 
            +
                cweek = n.month;
         | 
| 165 | 
            +
                memset(&n, 0, sizeof(rhrd_t));
         | 
| 166 | 
            +
              }
         | 
| 167 | 
            +
             | 
| 168 | 
            +
              n.jd = rhrd__commercial_to_jd(cwyear, cweek, cwday);
         | 
| 169 | 
            +
              rhrd__fill_commercial(&n);
         | 
| 170 | 
            +
              if(cwyear != n.year || cweek != n.month || cwday != n.day) {
         | 
| 171 | 
            +
                return 0;
         | 
| 172 | 
            +
              }
         | 
| 173 | 
            +
             | 
| 174 | 
            +
              if ((n.jd > RHR_JD_MAX) || (n.jd < RHR_JD_MIN)) {
         | 
| 175 | 
            +
                return 0;
         | 
| 176 | 
            +
              }
         | 
| 177 | 
            +
             | 
| 178 | 
            +
              d->jd = n.jd;
         | 
| 179 | 
            +
              d->flags = RHR_HAVE_JD;
         | 
| 180 | 
            +
              return 1;
         | 
| 181 | 
            +
            }
         | 
| 182 | 
            +
             | 
| 183 | 
            +
            /* Same as rhrd__valid_ordinal, for rhrdt_t. */
         | 
| 184 | 
            +
            int rhrdt__valid_ordinal(rhrdt_t *d, long year, long yday) {
         | 
| 185 | 
            +
              int leap;
         | 
| 186 | 
            +
              long month, day;
         | 
| 187 | 
            +
             | 
| 188 | 
            +
              leap = rhrd__leap_year(year);
         | 
| 189 | 
            +
              if (yday < 0) {
         | 
| 190 | 
            +
                if (leap) {
         | 
| 191 | 
            +
                  yday += 367;
         | 
| 192 | 
            +
                } else {
         | 
| 193 | 
            +
                  yday += 366;
         | 
| 194 | 
            +
                }
         | 
| 195 | 
            +
              }
         | 
| 196 | 
            +
              if (yday < 1 || yday > (leap ? 366 : 365)) {
         | 
| 197 | 
            +
                return 0;
         | 
| 198 | 
            +
              }
         | 
| 199 | 
            +
              if (leap) {
         | 
| 200 | 
            +
                month = rhrd_leap_yday_to_month[yday];
         | 
| 201 | 
            +
                if (yday > 60) {
         | 
| 202 | 
            +
                  day = yday - rhrd_cumulative_days_in_month[month] - 1;
         | 
| 203 | 
            +
                } else {
         | 
| 204 | 
            +
                  day = yday - rhrd_cumulative_days_in_month[month];
         | 
| 205 | 
            +
                }
         | 
| 206 | 
            +
              } else {
         | 
| 207 | 
            +
                month = rhrd_yday_to_month[yday];
         | 
| 208 | 
            +
                day = yday - rhrd_cumulative_days_in_month[month];
         | 
| 209 | 
            +
              }
         | 
| 210 | 
            +
             | 
| 211 | 
            +
              if(!rhrd__valid_civil_limits(year, month, day)) {
         | 
| 212 | 
            +
                return 0;
         | 
| 213 | 
            +
              } 
         | 
| 214 | 
            +
             | 
| 215 | 
            +
              d->year = year;
         | 
| 216 | 
            +
              d->month = (unsigned char)month;
         | 
| 217 | 
            +
              d->day = (unsigned char)day;
         | 
| 218 | 
            +
              d->flags |= RHR_HAVE_CIVIL;
         | 
| 219 | 
            +
              return 1;
         | 
| 220 | 
            +
            }
         | 
| 221 | 
            +
             | 
| 222 | 
            +
            /* Fill the rhrdt_t with the current time information. On
         | 
| 223 | 
            +
             * ruby 1.9, this is accurate to nanoseconds if the platform
         | 
| 224 | 
            +
             * supports it, while on ruby 1.8 is is accurate to microseconds.
         | 
| 225 | 
            +
             * On Windows, it's only accurate to within about 15 milliseconds. */
         | 
| 226 | 
            +
            void rhrdt__now(rhrdt_t * dt) {
         | 
| 227 | 
            +
              long t;
         | 
| 228 | 
            +
              long offset;
         | 
| 229 | 
            +
              VALUE rt; 
         | 
| 230 | 
            +
              rt = rb_funcall(rb_cTime, rhrd_id_now, 0);
         | 
| 231 | 
            +
              offset = NUM2LONG(rb_funcall(rt, rhrd_id_utc_offset, 0));
         | 
| 232 | 
            +
              t = NUM2LONG(rb_funcall(rt, rhrd_id_to_i, 0)) + offset;
         | 
| 233 | 
            +
              dt->jd = rhrd__unix_to_jd(t);
         | 
| 234 | 
            +
            #ifdef RUBY19
         | 
| 235 | 
            +
              dt->nanos = rhrd__mod(t, RHR_SECONDS_PER_DAY) * RHR_NANOS_PER_SECOND + NUM2LONG(rb_funcall(rt, rhrd_id_nsec, 0));
         | 
| 236 | 
            +
            #else
         | 
| 237 | 
            +
              dt->nanos = rhrd__mod(t, RHR_SECONDS_PER_DAY) * RHR_NANOS_PER_SECOND + NUM2LONG(rb_funcall(rt, rhrd_id_usec, 0)) * 1000;
         | 
| 238 | 
            +
            #endif
         | 
| 239 | 
            +
              dt->offset = offset/60;
         | 
| 240 | 
            +
              dt->flags |= RHR_HAVE_JD | RHR_HAVE_NANOS;
         | 
| 241 | 
            +
              RHR_CHECK_JD(dt);
         | 
| 242 | 
            +
            }
         | 
| 243 | 
            +
             | 
| 244 | 
            +
            /* Return a new ruby DateTime object using the given jd, nanos,
         | 
| 245 | 
            +
             * and offset.  The offset should already be in minutes-from-UTC
         | 
| 246 | 
            +
             * format. This handles negative nanos or nanos greater than
         | 
| 247 | 
            +
             * the number per day by subtracting from or adding to the jd.
         | 
| 248 | 
            +
             * It should ensure that the stored nanos value is in the range
         | 
| 249 | 
            +
             * [0, RHR_NANOS_PER_DAY). */
         | 
| 250 | 
            +
            VALUE rhrdt__from_jd_nanos(long jd, long long nanos, short offset) {
         | 
| 251 | 
            +
              long t;
         | 
| 252 | 
            +
              rhrdt_t *dt;
         | 
| 253 | 
            +
              VALUE new;
         | 
| 254 | 
            +
              new = Data_Make_Struct(rhrdt_class, rhrdt_t, NULL, free, dt);
         | 
| 255 | 
            +
              
         | 
| 256 | 
            +
              if (nanos < 0) {
         | 
| 257 | 
            +
                t = nanos/RHR_NANOS_PER_DAY - 1;
         | 
| 258 | 
            +
                nanos -= t * RHR_NANOS_PER_DAY;
         | 
| 259 | 
            +
                jd += t;
         | 
| 260 | 
            +
              } else if (nanos >= RHR_NANOS_PER_DAY) {
         | 
| 261 | 
            +
                t = nanos/RHR_NANOS_PER_DAY;
         | 
| 262 | 
            +
                nanos -= t * RHR_NANOS_PER_DAY;
         | 
| 263 | 
            +
                jd += t;
         | 
| 264 | 
            +
              }
         | 
| 265 | 
            +
              dt->jd = jd;
         | 
| 266 | 
            +
              dt->nanos = nanos;
         | 
| 267 | 
            +
              dt->offset = offset;
         | 
| 268 | 
            +
              dt->flags = RHR_HAVE_JD | RHR_HAVE_NANOS;
         | 
| 269 | 
            +
              return new;
         | 
| 270 | 
            +
            }
         | 
| 271 | 
            +
             | 
| 272 | 
            +
            /* Similar to rhrd__spaceship.  Unlike that, we
         | 
| 273 | 
            +
             * don't try to speed up by checking which fields
         | 
| 274 | 
            +
             * are already stored, we just fill the jd and
         | 
| 275 | 
            +
             * nanos fields for both and compare them.*/
         | 
| 276 | 
            +
            long rhrdt__spaceship(rhrdt_t *dt, rhrdt_t *odt) {
         | 
| 277 | 
            +
              RHRDT_FILL_JD(dt)
         | 
| 278 | 
            +
              RHRDT_FILL_JD(odt)
         | 
| 279 | 
            +
              RHRDT_FILL_NANOS(dt)
         | 
| 280 | 
            +
              RHRDT_FILL_NANOS(odt)
         | 
| 281 | 
            +
              if (dt->jd == odt->jd) { 
         | 
| 282 | 
            +
                if (dt->nanos == odt->nanos) {
         | 
| 283 | 
            +
                  return 0;
         | 
| 284 | 
            +
                } else if (dt->nanos < odt->nanos) {
         | 
| 285 | 
            +
                  return -1;
         | 
| 286 | 
            +
                } 
         | 
| 287 | 
            +
                return 1;
         | 
| 288 | 
            +
              } else if (dt->jd < odt->jd) {
         | 
| 289 | 
            +
                return -1;
         | 
| 290 | 
            +
              } 
         | 
| 291 | 
            +
              return 1;
         | 
| 292 | 
            +
            }
         | 
| 293 | 
            +
             | 
| 294 | 
            +
            /* Similar to rhrd__add_days, but n is a double in
         | 
| 295 | 
            +
             * order to handle fractional days. */
         | 
| 296 | 
            +
            VALUE rhrdt__add_days(VALUE self, double n) {
         | 
| 297 | 
            +
              long l;
         | 
| 298 | 
            +
              long long nanos;
         | 
| 299 | 
            +
              rhrdt_t *dt;
         | 
| 300 | 
            +
              Data_Get_Struct(self, rhrdt_t, dt);
         | 
| 301 | 
            +
              RHRDT_FILL_JD(dt)
         | 
| 302 | 
            +
              RHRDT_FILL_NANOS(dt)
         | 
| 303 | 
            +
              l = floor(n);
         | 
| 304 | 
            +
              nanos = llround((n - l) * RHR_NANOS_PER_DAY);
         | 
| 305 | 
            +
              return rhrdt__from_jd_nanos(rhrd__safe_add_long(dt->jd, l), dt->nanos + nanos, dt->offset);
         | 
| 306 | 
            +
            }
         | 
| 307 | 
            +
             | 
| 308 | 
            +
            /* Similar to rhrd__add_months, but for ruby DateTime
         | 
| 309 | 
            +
             * values. */
         | 
| 310 | 
            +
            VALUE rhrdt__add_months(VALUE self, long n) {
         | 
| 311 | 
            +
              rhrdt_t *d;
         | 
| 312 | 
            +
              rhrdt_t *newd;
         | 
| 313 | 
            +
              VALUE new;
         | 
| 314 | 
            +
              long x;
         | 
| 315 | 
            +
              Data_Get_Struct(self, rhrdt_t, d);
         | 
| 316 | 
            +
             | 
| 317 | 
            +
              new = Data_Make_Struct(rhrdt_class, rhrdt_t, NULL, free, newd);
         | 
| 318 | 
            +
              RHRDT_FILL_CIVIL(d)
         | 
| 319 | 
            +
              memcpy(newd, d, sizeof(rhrdt_t));
         | 
| 320 | 
            +
             | 
| 321 | 
            +
              n = rhrd__safe_add_long(n, (long)(d->month));
         | 
| 322 | 
            +
              if(n > 1 && n <= 12) {
         | 
| 323 | 
            +
                newd->year = d->year;
         | 
| 324 | 
            +
                newd->month = n;
         | 
| 325 | 
            +
              } else {
         | 
| 326 | 
            +
                x = n / 12;
         | 
| 327 | 
            +
                n = n % 12;
         | 
| 328 | 
            +
                if (n <= 0) {
         | 
| 329 | 
            +
                  newd->year = d->year + x - 1;
         | 
| 330 | 
            +
                  newd->month = n + 12;
         | 
| 331 | 
            +
                } else {
         | 
| 332 | 
            +
                  newd->year = d->year + x;
         | 
| 333 | 
            +
                  newd->month = (unsigned char)n;
         | 
| 334 | 
            +
                }
         | 
| 335 | 
            +
              }
         | 
| 336 | 
            +
              x = rhrd__days_in_month(newd->year, newd->month);
         | 
| 337 | 
            +
              newd->day = (unsigned char)(d->day > x ? x : d->day);
         | 
| 338 | 
            +
              RHR_CHECK_CIVIL(newd)
         | 
| 339 | 
            +
              newd->flags &= ~RHR_HAVE_JD;
         | 
| 340 | 
            +
              return new;
         | 
| 341 | 
            +
            }
         | 
| 342 | 
            +
             | 
| 343 | 
            +
            /* Similar to rhrd__fill_from_hash for rhrdt_t, except instead of
         | 
| 344 | 
            +
             * returning 1 or 0, this raises ruby ArgumentErrors. */
         | 
| 345 | 
            +
            void rhrdt__fill_from_hash(rhrdt_t *dt, VALUE hash) {
         | 
| 346 | 
            +
              rhrd_t d;
         | 
| 347 | 
            +
              long hour = 0;
         | 
| 348 | 
            +
              long minute = 0;
         | 
| 349 | 
            +
              long second = 0;
         | 
| 350 | 
            +
              long offset = 0;
         | 
| 351 | 
            +
              long long nanos = 0;
         | 
| 352 | 
            +
              long long time_set = 0;
         | 
| 353 | 
            +
              int r;
         | 
| 354 | 
            +
              VALUE rhour, rmin, rsec, runix, roffset, rsecf;
         | 
| 355 | 
            +
             | 
| 356 | 
            +
              if (!RTEST(hash)) {
         | 
| 357 | 
            +
                rb_raise(rb_eArgError, "invalid date");
         | 
| 358 | 
            +
              }
         | 
| 359 | 
            +
             | 
| 360 | 
            +
              roffset = rb_hash_aref(hash, rhrd_sym_offset);
         | 
| 361 | 
            +
              if (RTEST(roffset)) {
         | 
| 362 | 
            +
                offset = NUM2LONG(roffset);
         | 
| 363 | 
            +
              }
         | 
| 364 | 
            +
             | 
| 365 | 
            +
              rsecf = rb_hash_aref(hash, rhrd_sym_sec_fraction);
         | 
| 366 | 
            +
              if (RTEST(rsecf)) {
         | 
| 367 | 
            +
                nanos = llround(NUM2DBL(rsecf) * RHR_NANOS_PER_SECOND);
         | 
| 368 | 
            +
              }
         | 
| 369 | 
            +
             | 
| 370 | 
            +
              runix = rb_hash_aref(hash, rhrd_sym_seconds);
         | 
| 371 | 
            +
              if (RTEST(runix)) {
         | 
| 372 | 
            +
                time_set = NUM2LL(runix);
         | 
| 373 | 
            +
                dt->jd = rhrd__unix_to_jd(time_set);
         | 
| 374 | 
            +
                time_set = rhrd__modll(time_set, RHR_SECONDS_PER_DAY);
         | 
| 375 | 
            +
                dt->nanos = time_set*RHR_NANOS_PER_SECOND + nanos;
         | 
| 376 | 
            +
                dt->hour = time_set/RHR_SECONDS_PER_HOUR;
         | 
| 377 | 
            +
                dt->minute = (time_set - dt->hour * RHR_SECONDS_PER_HOUR)/60;
         | 
| 378 | 
            +
                dt->second = rhrd__mod(time_set, 60);
         | 
| 379 | 
            +
                offset /= 60;
         | 
| 380 | 
            +
                if (offset > RHR_MAX_OFFSET_MINUTES || offset < RHR_MIN_OFFSET_MINUTES) {
         | 
| 381 | 
            +
                  rb_raise(rb_eArgError, "invalid offset: %ld minutes", offset);
         | 
| 382 | 
            +
                }
         | 
| 383 | 
            +
                RHR_CHECK_JD(dt);
         | 
| 384 | 
            +
                dt->flags = RHR_HAVE_JD | RHR_HAVE_NANOS | RHR_HAVE_HMS;
         | 
| 385 | 
            +
                return;
         | 
| 386 | 
            +
              } else {
         | 
| 387 | 
            +
                rhour = rb_hash_aref(hash, rhrd_sym_hour);
         | 
| 388 | 
            +
                rmin = rb_hash_aref(hash, rhrd_sym_min);
         | 
| 389 | 
            +
                rsec = rb_hash_aref(hash, rhrd_sym_sec);
         | 
| 390 | 
            +
                
         | 
| 391 | 
            +
                if (RTEST(rhour)) {
         | 
| 392 | 
            +
                  time_set = 1;
         | 
| 393 | 
            +
                  hour = NUM2LONG(rhour);
         | 
| 394 | 
            +
                }
         | 
| 395 | 
            +
                if (RTEST(rmin)) {
         | 
| 396 | 
            +
                  time_set = 1;
         | 
| 397 | 
            +
                  minute = NUM2LONG(rmin);
         | 
| 398 | 
            +
                }
         | 
| 399 | 
            +
                if (RTEST(rsec)) {
         | 
| 400 | 
            +
                  time_set = 1;
         | 
| 401 | 
            +
                  second = NUM2LONG(rsec);
         | 
| 402 | 
            +
                }
         | 
| 403 | 
            +
              }
         | 
| 404 | 
            +
             | 
| 405 | 
            +
              memset(&d, 0, sizeof(rhrd_t));
         | 
| 406 | 
            +
              r = rhrd__fill_from_hash(&d, hash);
         | 
| 407 | 
            +
              if(r > 0) {
         | 
| 408 | 
            +
                /* bad date info */
         | 
| 409 | 
            +
                rb_raise(rb_eArgError, "invalid date");
         | 
| 410 | 
            +
              } else if (r < 0) {
         | 
| 411 | 
            +
                if (time_set) {
         | 
| 412 | 
            +
                  /* time info but no date info, assume current date */
         | 
| 413 | 
            +
                  rhrd__today(&d);
         | 
| 414 | 
            +
                } else {
         | 
| 415 | 
            +
                  /* no time or date info */
         | 
| 416 | 
            +
                  rb_raise(rb_eArgError, "invalid date");
         | 
| 417 | 
            +
                }
         | 
| 418 | 
            +
              } 
         | 
| 419 | 
            +
             | 
| 420 | 
            +
              if(RHR_HAS_JD(&d)) {
         | 
| 421 | 
            +
                dt->jd = d.jd;
         | 
| 422 | 
            +
                dt->flags |= RHR_HAVE_JD;
         | 
| 423 | 
            +
              }
         | 
| 424 | 
            +
              if(RHR_HAS_CIVIL(&d)) {
         | 
| 425 | 
            +
                dt->year = d.year;
         | 
| 426 | 
            +
                dt->month = d.month;
         | 
| 427 | 
            +
                dt->day = d.day;
         | 
| 428 | 
            +
                dt->flags |= RHR_HAVE_CIVIL;
         | 
| 429 | 
            +
              }
         | 
| 430 | 
            +
              if(time_set) {
         | 
| 431 | 
            +
                rhrdt__valid_time(dt, hour, minute, second, offset/RHR_SECONDS_PER_DAYD);
         | 
| 432 | 
            +
                if(nanos) {
         | 
| 433 | 
            +
                  RHRDT_FILL_NANOS(dt)
         | 
| 434 | 
            +
                  dt->nanos += nanos;
         | 
| 435 | 
            +
                }
         | 
| 436 | 
            +
              } else if (offset) {
         | 
| 437 | 
            +
                if(!rhrdt__valid_offset(dt, offset/RHR_SECONDS_PER_DAYD)){
         | 
| 438 | 
            +
                  rb_raise(rb_eArgError, "invalid date");
         | 
| 439 | 
            +
                } 
         | 
| 440 | 
            +
              }
         | 
| 441 | 
            +
            }
         | 
| 442 | 
            +
             | 
| 443 | 
            +
            /* Return a new ruby DateTime object with the same
         | 
| 444 | 
            +
             * absolute time as the given one, but with a different
         | 
| 445 | 
            +
             * offset. */
         | 
| 446 | 
            +
            VALUE rhrdt__new_offset(VALUE self, double offset) {
         | 
| 447 | 
            +
              rhrdt_t *dt;
         | 
| 448 | 
            +
              long offset_min;
         | 
| 449 | 
            +
             | 
| 450 | 
            +
              if(offset < RHR_MIN_OFFSET_FRACT || offset > RHR_MAX_OFFSET_FRACT) {
         | 
| 451 | 
            +
                rb_raise(rb_eArgError, "invalid offset (%f)", offset);
         | 
| 452 | 
            +
              } 
         | 
| 453 | 
            +
              offset_min = lround(offset * 1440.0);
         | 
| 454 | 
            +
              Data_Get_Struct(self, rhrdt_t, dt);
         | 
| 455 | 
            +
              RHRDT_FILL_JD(dt)
         | 
| 456 | 
            +
              RHRDT_FILL_NANOS(dt)
         | 
| 457 | 
            +
              return rhrdt__from_jd_nanos(dt->jd, dt->nanos - (dt->offset - offset_min)*RHR_NANOS_PER_MINUTE, offset_min);
         | 
| 458 | 
            +
            }
         | 
| 459 | 
            +
             | 
| 460 | 
            +
            /* Class methods */
         | 
| 461 | 
            +
             | 
| 462 | 
            +
            /* call-seq:
         | 
| 463 | 
            +
             *   _load(string) -> DateTime
         | 
| 464 | 
            +
             *
         | 
| 465 | 
            +
             * Unmarshal a dumped +DateTime+ object. Not generally called directly,
         | 
| 466 | 
            +
             * usually called by <tt>Marshal.load</tt>.
         | 
| 467 | 
            +
             *
         | 
| 468 | 
            +
             * Note that this does not handle the marshalling format used by
         | 
| 469 | 
            +
             * the stdlib's +DateTime+, it only handles marshalled versions of
         | 
| 470 | 
            +
             * this library's +DateTime+ objects.
         | 
| 471 | 
            +
             */
         | 
| 472 | 
            +
            static VALUE rhrdt_s__load(VALUE klass, VALUE string) {
         | 
| 473 | 
            +
              rhrdt_t * d;
         | 
| 474 | 
            +
              long x;
         | 
| 475 | 
            +
              VALUE ary, rd;
         | 
| 476 | 
            +
              rd = Data_Make_Struct(klass, rhrdt_t, NULL, free, d);
         | 
| 477 | 
            +
             | 
| 478 | 
            +
              ary = rb_marshal_load(string);
         | 
| 479 | 
            +
              if (!RTEST(rb_obj_is_kind_of(ary, rb_cArray)) || RARRAY_LEN(ary) != 3) {
         | 
| 480 | 
            +
                rb_raise(rb_eTypeError, "incompatible marshal file format");
         | 
| 481 | 
            +
              }
         | 
| 482 | 
            +
             | 
| 483 | 
            +
              d->jd = NUM2LONG(rb_ary_entry(ary, 0));
         | 
| 484 | 
            +
              RHR_CHECK_JD(d)
         | 
| 485 | 
            +
             | 
| 486 | 
            +
              d->nanos = NUM2LL(rb_ary_entry(ary, 1));
         | 
| 487 | 
            +
              if (d->nanos < 0 || d->nanos >= RHR_NANOS_PER_DAY) {
         | 
| 488 | 
            +
                rb_raise(rb_eArgError, "invalid nanos: %lld", d->nanos);
         | 
| 489 | 
            +
              }
         | 
| 490 | 
            +
             | 
| 491 | 
            +
              x = NUM2LONG(rb_ary_entry(ary, 2));
         | 
| 492 | 
            +
              if (x > RHR_MAX_OFFSET_MINUTES || x < RHR_MIN_OFFSET_MINUTES) {
         | 
| 493 | 
            +
                rb_raise(rb_eArgError, "invalid offset: %ld minutes", x);
         | 
| 494 | 
            +
              }
         | 
| 495 | 
            +
              d->offset = x;
         | 
| 496 | 
            +
              
         | 
| 497 | 
            +
              d->flags = RHR_HAVE_JD | RHR_HAVE_NANOS;
         | 
| 498 | 
            +
              return rd;
         | 
| 499 | 
            +
            }
         | 
| 500 | 
            +
             | 
| 501 | 
            +
            /* call-seq:
         | 
| 502 | 
            +
             *   _strptime(string, format='%FT%T%z') -> Hash or nil
         | 
| 503 | 
            +
             *
         | 
| 504 | 
            +
             * Attemps to parse the string using the given format, returning
         | 
| 505 | 
            +
             * a hash if there is a match (or +nil+ if no match).
         | 
| 506 | 
            +
             *
         | 
| 507 | 
            +
             * +_strptime+ supports the same formats that <tt>DateTime#strftime</tt> does.
         | 
| 508 | 
            +
             */
         | 
| 509 | 
            +
            static VALUE rhrdt_s__strptime(int argc, VALUE *argv, VALUE klass) {
         | 
| 510 | 
            +
              const char * fmt_str = "%FT%T%z";
         | 
| 511 | 
            +
              long fmt_len = 7;
         | 
| 512 | 
            +
              VALUE r;
         | 
| 513 | 
            +
             | 
| 514 | 
            +
              switch(argc) {
         | 
| 515 | 
            +
                case 2:
         | 
| 516 | 
            +
                  r = rb_str_to_str(argv[1]);
         | 
| 517 | 
            +
                  fmt_str = RSTRING_PTR(r);
         | 
| 518 | 
            +
                  fmt_len = RSTRING_LEN(r);
         | 
| 519 | 
            +
                case 1:
         | 
| 520 | 
            +
                  break;
         | 
| 521 | 
            +
                default:
         | 
| 522 | 
            +
                  rb_raise(rb_eArgError, "wrong number of arguments (%i for 2)", argc);
         | 
| 523 | 
            +
                  break;
         | 
| 524 | 
            +
              }
         | 
| 525 | 
            +
             | 
| 526 | 
            +
              return rhrd__strptime(argv[0], fmt_str, fmt_len);
         | 
| 527 | 
            +
            }
         | 
| 528 | 
            +
             | 
| 529 | 
            +
            /* call-seq:
         | 
| 530 | 
            +
             *   civil() -> DateTime <br />
         | 
| 531 | 
            +
             *   civil(year, month=1, day=1, hour=0, minute=0, second=0, offset=0, sg=nil) -> DateTime
         | 
| 532 | 
            +
             *
         | 
| 533 | 
            +
             * If no arguments are given, returns a +DateTime+ for julian day 0.
         | 
| 534 | 
            +
             * Otherwise, returns a +DateTime+ for the year, month, day, hour, minute, second
         | 
| 535 | 
            +
             * and offset given.
         | 
| 536 | 
            +
             * Raises an +ArgumentError+ for invalid dates or times.
         | 
| 537 | 
            +
             * Ignores the 8th argument.
         | 
| 538 | 
            +
             */
         | 
| 539 | 
            +
            static VALUE rhrdt_s_civil(int argc, VALUE *argv, VALUE klass) {
         | 
| 540 | 
            +
              rhrdt_t *dt;
         | 
| 541 | 
            +
              long year;
         | 
| 542 | 
            +
              long month = 1;
         | 
| 543 | 
            +
              long day = 1;
         | 
| 544 | 
            +
              long hour = 0;
         | 
| 545 | 
            +
              long minute = 0;
         | 
| 546 | 
            +
              long second = 0;
         | 
| 547 | 
            +
              double offset = 0.0;
         | 
| 548 | 
            +
              VALUE rdt = Data_Make_Struct(klass, rhrdt_t, NULL, free, dt);
         | 
| 549 | 
            +
             | 
| 550 | 
            +
              switch(argc) {
         | 
| 551 | 
            +
                case 0:
         | 
| 552 | 
            +
                  dt->flags = RHR_HAVE_JD | RHR_HAVE_NANOS | RHR_HAVE_HMS;
         | 
| 553 | 
            +
                  return rdt;
         | 
| 554 | 
            +
                case 8:
         | 
| 555 | 
            +
                case 7:
         | 
| 556 | 
            +
                  offset = NUM2DBL(argv[6]);
         | 
| 557 | 
            +
                case 6:
         | 
| 558 | 
            +
                  second = NUM2LONG(argv[5]);
         | 
| 559 | 
            +
                case 5:
         | 
| 560 | 
            +
                  minute = NUM2LONG(argv[4]);
         | 
| 561 | 
            +
                case 4:
         | 
| 562 | 
            +
                  hour = NUM2LONG(argv[3]);
         | 
| 563 | 
            +
                case 3:
         | 
| 564 | 
            +
                  day = NUM2LONG(argv[2]);
         | 
| 565 | 
            +
                case 2:
         | 
| 566 | 
            +
                  month = NUM2LONG(argv[1]);
         | 
| 567 | 
            +
                case 1:
         | 
| 568 | 
            +
                  year = NUM2LONG(argv[0]);
         | 
| 569 | 
            +
                  break;
         | 
| 570 | 
            +
                default:
         | 
| 571 | 
            +
                  rb_raise(rb_eArgError, "wrong number of arguments: %i for 8", argc);
         | 
| 572 | 
            +
                  break;
         | 
| 573 | 
            +
              }
         | 
| 574 | 
            +
             | 
| 575 | 
            +
              if (!rhrdt__valid_civil(dt, year, month, day)) {
         | 
| 576 | 
            +
                RHR_CHECK_CIVIL(dt)
         | 
| 577 | 
            +
                rb_raise(rb_eArgError, "invalid date (year: %li, month: %li, day: %li)", year, month, day);
         | 
| 578 | 
            +
              }
         | 
| 579 | 
            +
              if (!rhrdt__valid_time(dt, hour, minute, second, offset)) {
         | 
| 580 | 
            +
                rb_raise(rb_eArgError, "invalid time (hour: %li, minute: %li, second: %li, offset: %f)", hour, minute, second, offset);
         | 
| 581 | 
            +
              }
         | 
| 582 | 
            +
             | 
| 583 | 
            +
              return rdt;
         | 
| 584 | 
            +
            }
         | 
| 585 | 
            +
             | 
| 586 | 
            +
            /* call-seq:
         | 
| 587 | 
            +
             *   commercial() -> DateTime <br />
         | 
| 588 | 
            +
             *   commercial(cwyear, cweek=41, cwday=5, hour=0, minute=0, second=0, offset=0, sg=nil) -> DateTime [ruby 1-8] <br />
         | 
| 589 | 
            +
             *   commercial(cwyear, cweek=1, cwday=1, hour=0, minute=0, second=0, offset=0, sg=nil) -> DateTime [ruby 1-9]
         | 
| 590 | 
            +
             *
         | 
| 591 | 
            +
             * If no arguments are given:
         | 
| 592 | 
            +
             * * ruby 1.8: returns a +DateTime+ for 1582-10-15 (the Day of Calendar Reform in Italy)
         | 
| 593 | 
            +
             * * ruby 1.9: returns a +DateTime+ for julian day 0
         | 
| 594 | 
            +
             *
         | 
| 595 | 
            +
             * Otherwise, returns a +DateTime+ for the commercial week year, commercial week, 
         | 
| 596 | 
            +
             * commercial week day, hour, minute, second, and offset given.
         | 
| 597 | 
            +
             * Raises an +ArgumentError+ for invalid dates or times.
         | 
| 598 | 
            +
             * Ignores the 8th argument.
         | 
| 599 | 
            +
             */
         | 
| 600 | 
            +
            static VALUE rhrdt_s_commercial(int argc, VALUE *argv, VALUE klass) {
         | 
| 601 | 
            +
              rhrdt_t *dt;
         | 
| 602 | 
            +
              long cwyear = RHR_DEFAULT_CWYEAR;
         | 
| 603 | 
            +
              long cweek = RHR_DEFAULT_CWEEK;
         | 
| 604 | 
            +
              long cwday = RHR_DEFAULT_CWDAY;
         | 
| 605 | 
            +
              long hour = 0;
         | 
| 606 | 
            +
              long minute = 0;
         | 
| 607 | 
            +
              long second = 0;
         | 
| 608 | 
            +
              double offset = 0.0;
         | 
| 609 | 
            +
              VALUE rdt = Data_Make_Struct(klass, rhrdt_t, NULL, free, dt);
         | 
| 610 | 
            +
             | 
| 611 | 
            +
              switch(argc) {
         | 
| 612 | 
            +
                case 8:
         | 
| 613 | 
            +
                case 7:
         | 
| 614 | 
            +
                  offset = NUM2DBL(argv[6]);
         | 
| 615 | 
            +
                case 6:
         | 
| 616 | 
            +
                  second = NUM2LONG(argv[5]);
         | 
| 617 | 
            +
                case 5:
         | 
| 618 | 
            +
                  minute = NUM2LONG(argv[4]);
         | 
| 619 | 
            +
                case 4:
         | 
| 620 | 
            +
                  hour = NUM2LONG(argv[3]);
         | 
| 621 | 
            +
                case 3:
         | 
| 622 | 
            +
                  cwday = NUM2LONG(argv[2]);
         | 
| 623 | 
            +
                case 2:
         | 
| 624 | 
            +
                  cweek = NUM2LONG(argv[1]);
         | 
| 625 | 
            +
                case 1:
         | 
| 626 | 
            +
                  cwyear = NUM2LONG(argv[0]);
         | 
| 627 | 
            +
            #ifdef RUBY19
         | 
| 628 | 
            +
                  break;
         | 
| 629 | 
            +
                case 0:
         | 
| 630 | 
            +
                  dt->flags = RHR_HAVE_JD | RHR_HAVE_NANOS | RHR_HAVE_HMS;
         | 
| 631 | 
            +
                  return rdt;
         | 
| 632 | 
            +
            #else
         | 
| 633 | 
            +
                case 0:
         | 
| 634 | 
            +
                  break;
         | 
| 635 | 
            +
            #endif
         | 
| 636 | 
            +
                default:
         | 
| 637 | 
            +
                  rb_raise(rb_eArgError, "wrong number of arguments: %i for 8", argc);
         | 
| 638 | 
            +
                  break;
         | 
| 639 | 
            +
              }
         | 
| 640 | 
            +
              if(!rhrdt__valid_commercial(dt, cwyear, cweek, cwday)) {
         | 
| 641 | 
            +
                RHR_CHECK_JD(dt)
         | 
| 642 | 
            +
                rb_raise(rb_eArgError, "invalid date (cwyear: %li, cweek: %li, cwday: %li)", cwyear, cweek, cwday);
         | 
| 643 | 
            +
              }
         | 
| 644 | 
            +
              if (!rhrdt__valid_time(dt, hour, minute, second, offset)) {
         | 
| 645 | 
            +
                rb_raise(rb_eArgError, "invalid time (hour: %li, minute: %li, second: %li, offset: %f)", hour, minute, second, offset);
         | 
| 646 | 
            +
              }
         | 
| 647 | 
            +
             | 
| 648 | 
            +
              return rdt;
         | 
| 649 | 
            +
            }
         | 
| 650 | 
            +
             | 
| 651 | 
            +
            /* call-seq:
         | 
| 652 | 
            +
             *   jd(jd=0, hour=0, minute=0, second=0, offset=0, sg=nil) -> DateTime
         | 
| 653 | 
            +
             *
         | 
| 654 | 
            +
             * Returns a +DateTime+ for the julian day number,
         | 
| 655 | 
            +
             * hour, minute, second, and offset given.
         | 
| 656 | 
            +
             * Raises +ArgumentError+ for invalid times.
         | 
| 657 | 
            +
             * Ignores the 6th argument.
         | 
| 658 | 
            +
             */
         | 
| 659 | 
            +
            static VALUE rhrdt_s_jd(int argc, VALUE *argv, VALUE klass) {
         | 
| 660 | 
            +
              rhrdt_t *dt;
         | 
| 661 | 
            +
              long hour = 0;
         | 
| 662 | 
            +
              long minute = 0;
         | 
| 663 | 
            +
              long second = 0;
         | 
| 664 | 
            +
              double offset = 0.0;
         | 
| 665 | 
            +
              VALUE rdt = Data_Make_Struct(klass, rhrdt_t, NULL, free, dt);
         | 
| 666 | 
            +
             | 
| 667 | 
            +
              switch(argc) {
         | 
| 668 | 
            +
                case 0:
         | 
| 669 | 
            +
                  dt->flags = RHR_HAVE_JD | RHR_HAVE_NANOS | RHR_HAVE_HMS;
         | 
| 670 | 
            +
                  return rdt;
         | 
| 671 | 
            +
                case 6:
         | 
| 672 | 
            +
                case 5:
         | 
| 673 | 
            +
                  offset = NUM2DBL(argv[4]);
         | 
| 674 | 
            +
                case 4:
         | 
| 675 | 
            +
                  second = NUM2LONG(argv[3]);
         | 
| 676 | 
            +
                case 3:
         | 
| 677 | 
            +
                  minute = NUM2LONG(argv[2]);
         | 
| 678 | 
            +
                case 2:
         | 
| 679 | 
            +
                  hour = NUM2LONG(argv[1]);
         | 
| 680 | 
            +
                case 1:
         | 
| 681 | 
            +
                  dt->jd = NUM2LONG(argv[0]);
         | 
| 682 | 
            +
                  break;
         | 
| 683 | 
            +
                default:
         | 
| 684 | 
            +
                  rb_raise(rb_eArgError, "wrong number of arguments: %i for 6", argc);
         | 
| 685 | 
            +
                  break;
         | 
| 686 | 
            +
              }
         | 
| 687 | 
            +
             | 
| 688 | 
            +
              RHR_CHECK_JD(dt)
         | 
| 689 | 
            +
              dt->flags = RHR_HAVE_JD;
         | 
| 690 | 
            +
              if (!rhrdt__valid_time(dt, hour, minute, second, offset)) {
         | 
| 691 | 
            +
                rb_raise(rb_eArgError, "invalid time (hour: %li, minute: %li, second: %li, offset: %f)", hour, minute, second, offset);
         | 
| 692 | 
            +
              }
         | 
| 693 | 
            +
             | 
| 694 | 
            +
              return rdt;
         | 
| 695 | 
            +
            }
         | 
| 696 | 
            +
             | 
| 697 | 
            +
            /* call-seq:
         | 
| 698 | 
            +
             *   new!(ajd=0, offset=0, sg=nil) -> DateTime
         | 
| 699 | 
            +
             *
         | 
| 700 | 
            +
             * Returns a +DateTime+ for the astronomical julian day number and offset given.
         | 
| 701 | 
            +
             * To include a fractional day, +ajd+ can be a +Float+. The date is assumed
         | 
| 702 | 
            +
             * to be based at noon UTC, so if +ajd+ is an +Integer+ and +offset+ is 0,
         | 
| 703 | 
            +
             * the hour will be 12.
         | 
| 704 | 
            +
             * Ignores the 3rd argument. Example:
         | 
| 705 | 
            +
             *
         | 
| 706 | 
            +
             *   DateTime.new!(2422222).to_s
         | 
| 707 | 
            +
             *   # => "1919-09-20T12:00:00+00:00"
         | 
| 708 | 
            +
             *   DateTime.new!(2422222.5).to_s
         | 
| 709 | 
            +
             *   # => "1919-09-21T00:00:00+00:00"
         | 
| 710 | 
            +
             *   DateTime.new!(2422222, 0.5).to_s
         | 
| 711 | 
            +
             *   # => "1919-09-21T00:00:00+12:00"
         | 
| 712 | 
            +
             *   DateTime.new!(2422222.5, 0.5).to_s
         | 
| 713 | 
            +
             *   # => "1919-09-21T12:00:00+12:00"
         | 
| 714 | 
            +
             */
         | 
| 715 | 
            +
            static VALUE rhrdt_s_new_b(int argc, VALUE *argv, VALUE klass) {
         | 
| 716 | 
            +
              double offset = 0;
         | 
| 717 | 
            +
              rhrdt_t *dt;
         | 
| 718 | 
            +
              VALUE rdt = Data_Make_Struct(klass, rhrdt_t, NULL, free, dt);
         | 
| 719 | 
            +
             | 
| 720 | 
            +
              switch(argc) {
         | 
| 721 | 
            +
                case 0:
         | 
| 722 | 
            +
                  dt->flags = RHR_HAVE_JD | RHR_HAVE_NANOS | RHR_HAVE_HMS;
         | 
| 723 | 
            +
                  return rdt; 
         | 
| 724 | 
            +
                case 2:
         | 
| 725 | 
            +
                case 3:
         | 
| 726 | 
            +
                  offset = NUM2DBL(argv[1]);
         | 
| 727 | 
            +
                  if (!rhrdt__valid_offset(dt, offset)) {
         | 
| 728 | 
            +
                    rb_raise(rb_eArgError, "invalid offset (%f)", offset);
         | 
| 729 | 
            +
                  }
         | 
| 730 | 
            +
                case 1:
         | 
| 731 | 
            +
                  offset += NUM2DBL(argv[0]) + 0.5;
         | 
| 732 | 
            +
                  dt->jd = offset;
         | 
| 733 | 
            +
                  dt->nanos = (offset - dt->jd)*RHR_NANOS_PER_DAY;
         | 
| 734 | 
            +
                  dt->flags = RHR_HAVE_JD | RHR_HAVE_NANOS;
         | 
| 735 | 
            +
                  break;
         | 
| 736 | 
            +
                default:
         | 
| 737 | 
            +
                  rb_raise(rb_eArgError, "wrong number of arguments: %i for 3", argc);
         | 
| 738 | 
            +
                  break;
         | 
| 739 | 
            +
              }
         | 
| 740 | 
            +
             | 
| 741 | 
            +
              RHR_CHECK_JD(dt)
         | 
| 742 | 
            +
              return rdt;
         | 
| 743 | 
            +
            }
         | 
| 744 | 
            +
             | 
| 745 | 
            +
            /* call-seq:
         | 
| 746 | 
            +
             *   now(sg=nil) -> DateTime
         | 
| 747 | 
            +
             *
         | 
| 748 | 
            +
             * Returns a +DateTime+ representing the current local date
         | 
| 749 | 
            +
             * and time.
         | 
| 750 | 
            +
             * Ignores an argument if given.
         | 
| 751 | 
            +
             */
         | 
| 752 | 
            +
            static VALUE rhrdt_s_now(int argc, VALUE *argv, VALUE klass) {
         | 
| 753 | 
            +
              rhrdt_t *dt;
         | 
| 754 | 
            +
              VALUE rdt = Data_Make_Struct(klass, rhrdt_t, NULL, free, dt);
         | 
| 755 | 
            +
             | 
| 756 | 
            +
              switch(argc) {
         | 
| 757 | 
            +
                case 0:
         | 
| 758 | 
            +
                case 1:
         | 
| 759 | 
            +
                  break;
         | 
| 760 | 
            +
                default:
         | 
| 761 | 
            +
                  rb_raise(rb_eArgError, "wrong number of arguments: %i for 1", argc);
         | 
| 762 | 
            +
                  break;
         | 
| 763 | 
            +
              }
         | 
| 764 | 
            +
             | 
| 765 | 
            +
              rhrdt__now(dt);
         | 
| 766 | 
            +
              return rdt;
         | 
| 767 | 
            +
            }
         | 
| 768 | 
            +
             | 
| 769 | 
            +
            /* call-seq:
         | 
| 770 | 
            +
             *   ordinal() -> DateTime <br />
         | 
| 771 | 
            +
             *   ordinal(year, yday=1, hour=0, minute=0, second=0, offset=0, sg=nil) -> DateTime
         | 
| 772 | 
            +
             *
         | 
| 773 | 
            +
             * If no arguments are given, returns a +DateTime+ for julian day 0.
         | 
| 774 | 
            +
             * Otherwise, returns a +DateTime+ for the year, day of year,
         | 
| 775 | 
            +
             * hour, minute, second, and offset given.
         | 
| 776 | 
            +
             * Raises an +ArgumentError+ for invalid dates.
         | 
| 777 | 
            +
             * Ignores the 7th argument.
         | 
| 778 | 
            +
             */
         | 
| 779 | 
            +
            static VALUE rhrdt_s_ordinal(int argc, VALUE *argv, VALUE klass) {
         | 
| 780 | 
            +
              long year;
         | 
| 781 | 
            +
              long day = 1;
         | 
| 782 | 
            +
              long hour = 0;
         | 
| 783 | 
            +
              long minute = 0;
         | 
| 784 | 
            +
              long second = 0;
         | 
| 785 | 
            +
              double offset = 0.0;
         | 
| 786 | 
            +
              rhrdt_t *dt;
         | 
| 787 | 
            +
              VALUE rdt = Data_Make_Struct(klass, rhrdt_t, NULL, free, dt);
         | 
| 788 | 
            +
             | 
| 789 | 
            +
              switch(argc) {
         | 
| 790 | 
            +
                case 7:
         | 
| 791 | 
            +
                case 6:
         | 
| 792 | 
            +
                  offset = NUM2DBL(argv[5]);
         | 
| 793 | 
            +
                case 5:
         | 
| 794 | 
            +
                  second = NUM2LONG(argv[4]);
         | 
| 795 | 
            +
                case 4:
         | 
| 796 | 
            +
                  minute = NUM2LONG(argv[3]);
         | 
| 797 | 
            +
                case 3:
         | 
| 798 | 
            +
                  hour = NUM2LONG(argv[2]);
         | 
| 799 | 
            +
                case 2:
         | 
| 800 | 
            +
                  day = NUM2LONG(argv[1]);
         | 
| 801 | 
            +
                case 1:
         | 
| 802 | 
            +
                  year = NUM2LONG(argv[0]);
         | 
| 803 | 
            +
                  break;
         | 
| 804 | 
            +
                case 0:
         | 
| 805 | 
            +
                  dt->flags = RHR_HAVE_JD | RHR_HAVE_NANOS | RHR_HAVE_HMS;
         | 
| 806 | 
            +
                  return rdt;
         | 
| 807 | 
            +
                default:
         | 
| 808 | 
            +
                  rb_raise(rb_eArgError, "wrong number of arguments: %i for 7", argc);
         | 
| 809 | 
            +
                  break;
         | 
| 810 | 
            +
              }
         | 
| 811 | 
            +
             | 
| 812 | 
            +
              if(!rhrdt__valid_ordinal(dt, year, day)) {
         | 
| 813 | 
            +
                RHR_CHECK_JD(dt)
         | 
| 814 | 
            +
                rb_raise(rb_eArgError, "invalid date (year: %li, yday: %li)", year, day);
         | 
| 815 | 
            +
              }
         | 
| 816 | 
            +
              if (!rhrdt__valid_time(dt, hour, minute, second, offset)) {
         | 
| 817 | 
            +
                rb_raise(rb_eArgError, "invalid time (hour: %li, minute: %li, second: %li, offset: %f)", hour, minute, second, offset);
         | 
| 818 | 
            +
              }
         | 
| 819 | 
            +
              return rdt;
         | 
| 820 | 
            +
            }
         | 
| 821 | 
            +
             | 
| 822 | 
            +
            /* call-seq:
         | 
| 823 | 
            +
             *   parse() -> DateTime <br />
         | 
| 824 | 
            +
             *   parse(string, comp=true, sg=nil) -> DateTime
         | 
| 825 | 
            +
             *
         | 
| 826 | 
            +
             * If no arguments are given, returns a +DateTime+ for julian day 0.
         | 
| 827 | 
            +
             * Otherwise returns a +DateTime+ for the date represented by the given
         | 
| 828 | 
            +
             * +string+.  Raises an +ArgumentError+ if the string was not in
         | 
| 829 | 
            +
             * a recognized format, or if the recognized format represents
         | 
| 830 | 
            +
             * an invalid date or time.
         | 
| 831 | 
            +
             * If +comp+ is true, expands 2-digit years to 4-digits years.
         | 
| 832 | 
            +
             * Ignores the 3rd argument.
         | 
| 833 | 
            +
             */
         | 
| 834 | 
            +
            static VALUE rhrdt_s_parse(int argc, VALUE *argv, VALUE klass) {
         | 
| 835 | 
            +
              rhrdt_t *dt;
         | 
| 836 | 
            +
              VALUE rdt = Data_Make_Struct(klass, rhrdt_t, NULL, free, dt);
         | 
| 837 | 
            +
             | 
| 838 | 
            +
              switch(argc) {
         | 
| 839 | 
            +
                case 0:
         | 
| 840 | 
            +
                  dt->flags = RHR_HAVE_JD | RHR_HAVE_NANOS | RHR_HAVE_HMS;
         | 
| 841 | 
            +
                  return rdt;
         | 
| 842 | 
            +
                case 1:
         | 
| 843 | 
            +
                  rhrdt__fill_from_hash(dt, rb_funcall(klass, rhrd_id__parse, 1, argv[0]));
         | 
| 844 | 
            +
                  break;
         | 
| 845 | 
            +
                case 2:
         | 
| 846 | 
            +
                case 3:
         | 
| 847 | 
            +
                  rhrdt__fill_from_hash(dt, rb_funcall(klass, rhrd_id__parse, 2, argv[0], argv[1]));
         | 
| 848 | 
            +
                  break;
         | 
| 849 | 
            +
                default:
         | 
| 850 | 
            +
                  rb_raise(rb_eArgError, "wrong number of arguments (%i for 3)", argc);
         | 
| 851 | 
            +
                  break;
         | 
| 852 | 
            +
              }
         | 
| 853 | 
            +
             | 
| 854 | 
            +
              return rdt;
         | 
| 855 | 
            +
            }
         | 
| 856 | 
            +
             | 
| 857 | 
            +
            /* call-seq:
         | 
| 858 | 
            +
             *   strptime() -> DateTime <br />
         | 
| 859 | 
            +
             *   strptime(string, format="%FT%T%z", sg=nil) -> DateTime
         | 
| 860 | 
            +
             *
         | 
| 861 | 
            +
             * If no arguments are given, returns a +DateTime+ for julian day 0.
         | 
| 862 | 
            +
             * Other returns a +DateTime+ for the date and time represented by the given
         | 
| 863 | 
            +
             * +string+, parsed using the given +format+.
         | 
| 864 | 
            +
             * Raises an +ArgumentError+ if the string did not match the format
         | 
| 865 | 
            +
             * given, or if it did match and it represented an invalid date or time.
         | 
| 866 | 
            +
             * Ignores the 3rd argument.
         | 
| 867 | 
            +
             */
         | 
| 868 | 
            +
            static VALUE rhrdt_s_strptime(int argc, VALUE *argv, VALUE klass) {
         | 
| 869 | 
            +
              rhrdt_t *dt;
         | 
| 870 | 
            +
              VALUE rdt = Data_Make_Struct(klass, rhrdt_t, NULL, free, dt);
         | 
| 871 | 
            +
             | 
| 872 | 
            +
              switch(argc) {
         | 
| 873 | 
            +
                case 0:
         | 
| 874 | 
            +
                  dt->flags = RHR_HAVE_JD | RHR_HAVE_NANOS | RHR_HAVE_HMS;
         | 
| 875 | 
            +
                  return rdt;
         | 
| 876 | 
            +
                case 3:
         | 
| 877 | 
            +
                  argc = 2;
         | 
| 878 | 
            +
                case 1:
         | 
| 879 | 
            +
                case 2:
         | 
| 880 | 
            +
                  break;
         | 
| 881 | 
            +
                default:
         | 
| 882 | 
            +
                  rb_raise(rb_eArgError, "wrong number of arguments (%i for 3)", argc);
         | 
| 883 | 
            +
                  break;
         | 
| 884 | 
            +
              }
         | 
| 885 | 
            +
             | 
| 886 | 
            +
              rhrdt__fill_from_hash(dt, rhrdt_s__strptime(argc, argv, klass));
         | 
| 887 | 
            +
              return rdt;
         | 
| 888 | 
            +
            }
         | 
| 889 | 
            +
             | 
| 890 | 
            +
            /* Instance methods */
         | 
| 891 | 
            +
             | 
| 892 | 
            +
            /* call-seq:
         | 
| 893 | 
            +
             *   _dump(limit) -> String
         | 
| 894 | 
            +
             *
         | 
| 895 | 
            +
             * Returns a marshalled representation of the receiver as a +String+.
         | 
| 896 | 
            +
             * Generally not called directly, usually called by <tt>Marshal.dump</tt>.
         | 
| 897 | 
            +
             */
         | 
| 898 | 
            +
            static VALUE rhrdt__dump(VALUE self, VALUE limit) {
         | 
| 899 | 
            +
              rhrdt_t *d;
         | 
| 900 | 
            +
              Data_Get_Struct(self, rhrdt_t, d);
         | 
| 901 | 
            +
              RHRDT_FILL_JD(d)
         | 
| 902 | 
            +
              RHRDT_FILL_NANOS(d)
         | 
| 903 | 
            +
              return rb_marshal_dump(rb_ary_new3(3, LONG2NUM(d->jd), LL2NUM(d->nanos), LONG2NUM(d->offset)), LONG2NUM(NUM2LONG(limit) - 1));
         | 
| 904 | 
            +
            }
         | 
| 905 | 
            +
             | 
| 906 | 
            +
            /* call-seq:
         | 
| 907 | 
            +
             *   ajd() -> Float
         | 
| 908 | 
            +
             *
         | 
| 909 | 
            +
             * Returns the date and time represented by the receiver as a
         | 
| 910 | 
            +
             * astronomical julian day +Float+.
         | 
| 911 | 
            +
             */
         | 
| 912 | 
            +
            static VALUE rhrdt_ajd(VALUE self) {
         | 
| 913 | 
            +
              rhrdt_t *d;
         | 
| 914 | 
            +
              Data_Get_Struct(self, rhrdt_t, d);
         | 
| 915 | 
            +
              RHRDT_FILL_JD(d)
         | 
| 916 | 
            +
              RHRDT_FILL_NANOS(d)
         | 
| 917 | 
            +
              return rb_float_new(d->jd + d->nanos/RHR_NANOS_PER_DAYD - d->offset/1440.0 - 0.5);
         | 
| 918 | 
            +
            }
         | 
| 919 | 
            +
             | 
| 920 | 
            +
            /* call-seq:
         | 
| 921 | 
            +
             *   amjd() -> Float
         | 
| 922 | 
            +
             *
         | 
| 923 | 
            +
             * Returns the date and time represented by the receiver as a
         | 
| 924 | 
            +
             * astronomical modified julian day +Float+.
         | 
| 925 | 
            +
             */
         | 
| 926 | 
            +
            static VALUE rhrdt_amjd(VALUE self) {
         | 
| 927 | 
            +
              rhrdt_t *d;
         | 
| 928 | 
            +
              Data_Get_Struct(self, rhrdt_t, d);
         | 
| 929 | 
            +
              RHRDT_FILL_JD(d)
         | 
| 930 | 
            +
              RHRDT_FILL_NANOS(d)
         | 
| 931 | 
            +
              return rb_float_new(d->jd + d->nanos/RHR_NANOS_PER_DAYD - d->offset/1440.0 - RHR_JD_MJD);
         | 
| 932 | 
            +
            }
         | 
| 933 | 
            +
             | 
| 934 | 
            +
            /* call-seq:
         | 
| 935 | 
            +
             *   asctime() -> String
         | 
| 936 | 
            +
             *
         | 
| 937 | 
            +
             * Returns a string representation of the receiver.  Example:
         | 
| 938 | 
            +
             * 
         | 
| 939 | 
            +
             *   DateTime.civil(2009, 1, 2, 3, 4, 5).asctime
         | 
| 940 | 
            +
             *   # => "Fri Jan  2 03:04:05 2009"
         | 
| 941 | 
            +
             */
         | 
| 942 | 
            +
            static VALUE rhrdt_asctime(VALUE self) {
         | 
| 943 | 
            +
              VALUE s;
         | 
| 944 | 
            +
              rhrdt_t *d;
         | 
| 945 | 
            +
              int len;
         | 
| 946 | 
            +
              Data_Get_Struct(self, rhrdt_t, d);
         | 
| 947 | 
            +
              RHRDT_FILL_CIVIL(d)
         | 
| 948 | 
            +
              RHRDT_FILL_JD(d)
         | 
| 949 | 
            +
              RHRDT_FILL_HMS(d)
         | 
| 950 | 
            +
             | 
| 951 | 
            +
              s = rb_str_buf_new(128);
         | 
| 952 | 
            +
              len = snprintf(RSTRING_PTR(s), 128, "%s %s %2hhi %02hhi:%02hhi:%02hhi %04li", 
         | 
| 953 | 
            +
                    rhrd__abbr_day_names[rhrd__jd_to_wday(d->jd)],
         | 
| 954 | 
            +
                    rhrd__abbr_month_names[d->month],
         | 
| 955 | 
            +
                    d->day, d->hour, d->minute, d->second,
         | 
| 956 | 
            +
                    d->year);
         | 
| 957 | 
            +
              if (len == -1 || len > 127) {
         | 
| 958 | 
            +
                rb_raise(rb_eNoMemError, "in DateTime#asctime (in snprintf)");
         | 
| 959 | 
            +
              }
         | 
| 960 | 
            +
             | 
| 961 | 
            +
              RHR_RETURN_RESIZED_STR(s, len)
         | 
| 962 | 
            +
            }
         | 
| 963 | 
            +
             | 
| 964 | 
            +
            /* call-seq:
         | 
| 965 | 
            +
             *   cwday() -> Integer
         | 
| 966 | 
            +
             *
         | 
| 967 | 
            +
             * Returns the commercial week day as an +Integer+. Example:
         | 
| 968 | 
            +
             * 
         | 
| 969 | 
            +
             *   DateTime.civil(2009, 1, 2).cwday
         | 
| 970 | 
            +
             *   # => 5
         | 
| 971 | 
            +
             *   DateTime.civil(2010, 1, 2).cwday
         | 
| 972 | 
            +
             *   # => 6
         | 
| 973 | 
            +
             */
         | 
| 974 | 
            +
            static VALUE rhrdt_cwday(VALUE self) {
         | 
| 975 | 
            +
              rhrdt_t *d;
         | 
| 976 | 
            +
              rhrd_t n;
         | 
| 977 | 
            +
              RHR_CACHED_IV(self, rhrd_id_cwday)
         | 
| 978 | 
            +
              memset(&n, 0, sizeof(rhrd_t));
         | 
| 979 | 
            +
              Data_Get_Struct(self, rhrdt_t, d);
         | 
| 980 | 
            +
              RHRDT_FILL_JD(d)
         | 
| 981 | 
            +
              n.jd = d->jd;
         | 
| 982 | 
            +
              rhrd__fill_commercial(&n);
         | 
| 983 | 
            +
              rhrd__set_cw_ivs(self, &n);
         | 
| 984 | 
            +
              return LONG2NUM(n.day);
         | 
| 985 | 
            +
            }
         | 
| 986 | 
            +
             | 
| 987 | 
            +
            /* call-seq:
         | 
| 988 | 
            +
             *   cweek() -> Integer
         | 
| 989 | 
            +
             *
         | 
| 990 | 
            +
             * Returns the commercial week as an +Integer+. Example:
         | 
| 991 | 
            +
             * 
         | 
| 992 | 
            +
             *   DateTime.civil(2009, 1, 2).cweek
         | 
| 993 | 
            +
             *   # => 1
         | 
| 994 | 
            +
             *   DateTime.civil(2010, 1, 2).cweek
         | 
| 995 | 
            +
             *   # => 53
         | 
| 996 | 
            +
             */
         | 
| 997 | 
            +
            static VALUE rhrdt_cweek(VALUE self) {
         | 
| 998 | 
            +
              rhrdt_t *d;
         | 
| 999 | 
            +
              rhrd_t n;
         | 
| 1000 | 
            +
              RHR_CACHED_IV(self, rhrd_id_cweek)
         | 
| 1001 | 
            +
              memset(&n, 0, sizeof(rhrd_t));
         | 
| 1002 | 
            +
              Data_Get_Struct(self, rhrdt_t, d);
         | 
| 1003 | 
            +
              RHRDT_FILL_JD(d)
         | 
| 1004 | 
            +
              n.jd = d->jd;
         | 
| 1005 | 
            +
              rhrd__fill_commercial(&n);
         | 
| 1006 | 
            +
              rhrd__set_cw_ivs(self, &n);
         | 
| 1007 | 
            +
              return LONG2NUM(n.month);
         | 
| 1008 | 
            +
            }
         | 
| 1009 | 
            +
             | 
| 1010 | 
            +
            /* call-seq:
         | 
| 1011 | 
            +
             *   cwyear() -> Integer
         | 
| 1012 | 
            +
             *
         | 
| 1013 | 
            +
             * Returns the commercial week year as an +Integer+. Example:
         | 
| 1014 | 
            +
             * 
         | 
| 1015 | 
            +
             *   DateTime.civil(2009, 1, 2).cwyear
         | 
| 1016 | 
            +
             *   # => 2009
         | 
| 1017 | 
            +
             *   DateTime.civil(2010, 1, 2).cwyear
         | 
| 1018 | 
            +
             *   # => 2009
         | 
| 1019 | 
            +
             */
         | 
| 1020 | 
            +
            static VALUE rhrdt_cwyear(VALUE self) {
         | 
| 1021 | 
            +
              rhrdt_t *d;
         | 
| 1022 | 
            +
              rhrd_t n;
         | 
| 1023 | 
            +
              RHR_CACHED_IV(self, rhrd_id_cwyear)
         | 
| 1024 | 
            +
              memset(&n, 0, sizeof(rhrd_t));
         | 
| 1025 | 
            +
              Data_Get_Struct(self, rhrdt_t, d);
         | 
| 1026 | 
            +
              RHRDT_FILL_JD(d)
         | 
| 1027 | 
            +
              n.jd = d->jd;
         | 
| 1028 | 
            +
              rhrd__fill_commercial(&n);
         | 
| 1029 | 
            +
              rhrd__set_cw_ivs(self, &n);
         | 
| 1030 | 
            +
              return LONG2NUM(n.year);
         | 
| 1031 | 
            +
            }
         | 
| 1032 | 
            +
             | 
| 1033 | 
            +
            /* call-seq:
         | 
| 1034 | 
            +
             *   day() -> Integer
         | 
| 1035 | 
            +
             *
         | 
| 1036 | 
            +
             * Returns the day of the month as an +Integer+. Example:
         | 
| 1037 | 
            +
             * 
         | 
| 1038 | 
            +
             *   DateTime.civil(2009, 1, 2).day
         | 
| 1039 | 
            +
             *   # => 2
         | 
| 1040 | 
            +
             */
         | 
| 1041 | 
            +
            static VALUE rhrdt_day(VALUE self) {
         | 
| 1042 | 
            +
              rhrdt_t *dt;
         | 
| 1043 | 
            +
              Data_Get_Struct(self, rhrdt_t, dt);
         | 
| 1044 | 
            +
              RHRDT_FILL_CIVIL(dt)
         | 
| 1045 | 
            +
              return LONG2NUM(dt->day);
         | 
| 1046 | 
            +
            }
         | 
| 1047 | 
            +
             | 
| 1048 | 
            +
            /* call-seq:
         | 
| 1049 | 
            +
             *   day_fraction() -> Float
         | 
| 1050 | 
            +
             *
         | 
| 1051 | 
            +
             * Returns the fraction of the day as a +Float+.  Example:
         | 
| 1052 | 
            +
             * 
         | 
| 1053 | 
            +
             *   DateTime.civil(2009, 1, 2).day_fraction
         | 
| 1054 | 
            +
             *   # => 0.0
         | 
| 1055 | 
            +
             *   DateTime.civil(2009, 1, 2, 12).day_fraction
         | 
| 1056 | 
            +
             *   # => 0.5
         | 
| 1057 | 
            +
             *   DateTime.civil(2009, 1, 2, 6).day_fraction
         | 
| 1058 | 
            +
             *   # => 0.25
         | 
| 1059 | 
            +
             */
         | 
| 1060 | 
            +
            static VALUE rhrdt_day_fraction(VALUE self) {
         | 
| 1061 | 
            +
              rhrdt_t *dt;
         | 
| 1062 | 
            +
              Data_Get_Struct(self, rhrdt_t, dt);
         | 
| 1063 | 
            +
              RHRDT_FILL_NANOS(dt)
         | 
| 1064 | 
            +
              return rb_float_new(dt->nanos/RHR_NANOS_PER_DAYD);
         | 
| 1065 | 
            +
            }
         | 
| 1066 | 
            +
             | 
| 1067 | 
            +
            /* call-seq:
         | 
| 1068 | 
            +
             *   downto(target){|datetime|} -> DateTime
         | 
| 1069 | 
            +
             *
         | 
| 1070 | 
            +
             * Equivalent to calling +step+ with the +target+ as the first argument
         | 
| 1071 | 
            +
             * and <tt>-1</tt> as the second argument. Returns self.
         | 
| 1072 | 
            +
             * 
         | 
| 1073 | 
            +
             *   DateTime.civil(2009, 1, 2).downto(DateTime.civil(2009, 1, 1)) do |datetime|
         | 
| 1074 | 
            +
             *     puts datetime
         | 
| 1075 | 
            +
             *   end
         | 
| 1076 | 
            +
             *   # Output:
         | 
| 1077 | 
            +
             *   # 2009-01-02T00:00:00+00:00
         | 
| 1078 | 
            +
             *   # 2009-01-01T00:00:00+00:00
         | 
| 1079 | 
            +
             */
         | 
| 1080 | 
            +
            static VALUE rhrdt_downto(VALUE self, VALUE other) {
         | 
| 1081 | 
            +
              VALUE argv[2];
         | 
| 1082 | 
            +
              argv[0] = other;
         | 
| 1083 | 
            +
              argv[1] = INT2FIX(-1);
         | 
| 1084 | 
            +
              return rhrdt_step(2, argv, self);
         | 
| 1085 | 
            +
            }
         | 
| 1086 | 
            +
             | 
| 1087 | 
            +
            /* call-seq:
         | 
| 1088 | 
            +
             *   eql?(datetime) -> true or false
         | 
| 1089 | 
            +
             *
         | 
| 1090 | 
            +
             * Returns true only if the +datetime+ given is the same date and time as the receiver.
         | 
| 1091 | 
            +
             * If +date+ is an instance of +Date+, returns +true+ only if +date+ is
         | 
| 1092 | 
            +
             * for the same date as the receiver and the receiver has no fractional component.
         | 
| 1093 | 
            +
             * Otherwise, returns +false+. Example:
         | 
| 1094 | 
            +
             *
         | 
| 1095 | 
            +
             *   DateTime.civil(2009, 1, 2, 12).eql?(DateTime.civil(2009, 1, 2, 12))
         | 
| 1096 | 
            +
             *   # => true
         | 
| 1097 | 
            +
             *   DateTime.civil(2009, 1, 2, 12).eql?(DateTime.civil(2009, 1, 2, 11))
         | 
| 1098 | 
            +
             *   # => false
         | 
| 1099 | 
            +
             *   DateTime.civil(2009, 1, 2).eql?(Date.civil(2009, 1, 2))
         | 
| 1100 | 
            +
             *   # => true
         | 
| 1101 | 
            +
             *   DateTime.civil(2009, 1, 2, 1).eql?(Date.civil(2009, 1, 2))
         | 
| 1102 | 
            +
             *   # => false
         | 
| 1103 | 
            +
             */
         | 
| 1104 | 
            +
            static VALUE rhrdt_eql_q(VALUE self, VALUE other) {
         | 
| 1105 | 
            +
              rhrdt_t *dt, *odt;
         | 
| 1106 | 
            +
              rhrd_t *o;
         | 
| 1107 | 
            +
              long diff;
         | 
| 1108 | 
            +
             | 
| 1109 | 
            +
              if (RTEST(rb_obj_is_kind_of(other, rhrdt_class))) {
         | 
| 1110 | 
            +
                self = rhrdt__new_offset(self, 0);
         | 
| 1111 | 
            +
                other = rhrdt__new_offset(other, 0);
         | 
| 1112 | 
            +
                Data_Get_Struct(self, rhrdt_t, dt);
         | 
| 1113 | 
            +
                Data_Get_Struct(other, rhrdt_t, odt);
         | 
| 1114 | 
            +
                return rhrdt__spaceship(dt, odt) == 0 ? Qtrue : Qfalse;
         | 
| 1115 | 
            +
              } else if (RTEST(rb_obj_is_kind_of(other, rhrd_class))) {
         | 
| 1116 | 
            +
                Data_Get_Struct(self, rhrdt_t, dt);
         | 
| 1117 | 
            +
                Data_Get_Struct(other, rhrd_t, o);
         | 
| 1118 | 
            +
                RHRDT_FILL_JD(dt)
         | 
| 1119 | 
            +
                RHR_FILL_JD(o)
         | 
| 1120 | 
            +
                RHR_SPACE_SHIP(diff, dt->jd, o->jd)
         | 
| 1121 | 
            +
                if (diff == 0) {
         | 
| 1122 | 
            +
                  RHRDT_FILL_NANOS(dt)
         | 
| 1123 | 
            +
                  RHR_SPACE_SHIP(diff, dt->nanos, 0)
         | 
| 1124 | 
            +
                }
         | 
| 1125 | 
            +
                return diff == 0 ? Qtrue : Qfalse;
         | 
| 1126 | 
            +
              }
         | 
| 1127 | 
            +
              return Qfalse;
         | 
| 1128 | 
            +
            }
         | 
| 1129 | 
            +
             | 
| 1130 | 
            +
            /* call-seq:
         | 
| 1131 | 
            +
             *   hash() -> Integer
         | 
| 1132 | 
            +
             *
         | 
| 1133 | 
            +
             * Return an +Integer+ hash value for the receiver, such that an
         | 
| 1134 | 
            +
             * equal date and time will have the same hash value.
         | 
| 1135 | 
            +
             */
         | 
| 1136 | 
            +
            static VALUE rhrdt_hash(VALUE self) {
         | 
| 1137 | 
            +
              rhrdt_t *d;
         | 
| 1138 | 
            +
              RHR_CACHED_IV(self, rhrd_id_hash)
         | 
| 1139 | 
            +
              Data_Get_Struct(rhrdt__new_offset(self, 0), rhrdt_t, d);
         | 
| 1140 | 
            +
              return rb_ivar_set(self, rhrd_id_hash, rb_funcall(rb_ary_new3(2, LONG2NUM(d->jd), LL2NUM(d->nanos)), rhrd_id_hash, 0));
         | 
| 1141 | 
            +
            }
         | 
| 1142 | 
            +
             | 
| 1143 | 
            +
            /* call-seq:
         | 
| 1144 | 
            +
             *   hour() -> Integer
         | 
| 1145 | 
            +
             *
         | 
| 1146 | 
            +
             * Returns the hour of the day as an +Integer+. Example:
         | 
| 1147 | 
            +
             * 
         | 
| 1148 | 
            +
             *   DateTime.civil(2009, 1, 2, 12, 13, 14).hour
         | 
| 1149 | 
            +
             *   # => 12
         | 
| 1150 | 
            +
             */
         | 
| 1151 | 
            +
            static VALUE rhrdt_hour(VALUE self) {
         | 
| 1152 | 
            +
              rhrdt_t *dt;
         | 
| 1153 | 
            +
              Data_Get_Struct(self, rhrdt_t, dt);
         | 
| 1154 | 
            +
              RHRDT_FILL_HMS(dt)
         | 
| 1155 | 
            +
              return LONG2NUM(dt->hour);
         | 
| 1156 | 
            +
            }
         | 
| 1157 | 
            +
             | 
| 1158 | 
            +
            /* call-seq:
         | 
| 1159 | 
            +
             *   inspect() -> String
         | 
| 1160 | 
            +
             *
         | 
| 1161 | 
            +
             * Return a developer-friendly string containing the civil
         | 
| 1162 | 
            +
             * date and time for the receiver.  Example:
         | 
| 1163 | 
            +
             *
         | 
| 1164 | 
            +
             *   DateTime.civil(2009, 1, 2, 3, 4, 5, 0.5).inspect
         | 
| 1165 | 
            +
             *   # => "#<DateTime 2009-01-02T03:04:05+12:00>"
         | 
| 1166 | 
            +
             */
         | 
| 1167 | 
            +
            static VALUE rhrdt_inspect(VALUE self) {
         | 
| 1168 | 
            +
              VALUE s;
         | 
| 1169 | 
            +
              rhrdt_t *dt;
         | 
| 1170 | 
            +
              int len;
         | 
| 1171 | 
            +
              Data_Get_Struct(self, rhrdt_t, dt);
         | 
| 1172 | 
            +
              RHRDT_FILL_CIVIL(dt)
         | 
| 1173 | 
            +
              RHRDT_FILL_HMS(dt)
         | 
| 1174 | 
            +
             | 
| 1175 | 
            +
              s = rb_str_buf_new(128);
         | 
| 1176 | 
            +
              len = snprintf(RSTRING_PTR(s), 128, "#<DateTime %04li-%02hhi-%02hhiT%02hhi:%02hhi:%02hhi%+03i:%02i>",
         | 
| 1177 | 
            +
                    dt->year, dt->month, dt->day, dt->hour, dt->minute, dt->second, dt->offset/60, abs(dt->offset % 60));
         | 
| 1178 | 
            +
              if (len == -1 || len > 127) {
         | 
| 1179 | 
            +
                rb_raise(rb_eNoMemError, "in DateTime#inspect (in snprintf)");
         | 
| 1180 | 
            +
              }
         | 
| 1181 | 
            +
             | 
| 1182 | 
            +
              RHR_RETURN_RESIZED_STR(s, len)
         | 
| 1183 | 
            +
            }
         | 
| 1184 | 
            +
             | 
| 1185 | 
            +
            /* call-seq:
         | 
| 1186 | 
            +
             *   jd() -> Integer
         | 
| 1187 | 
            +
             *
         | 
| 1188 | 
            +
             * Return the julian day number for the receiver as an +Integer+.
         | 
| 1189 | 
            +
             *
         | 
| 1190 | 
            +
             *   DateTime.civil(2009, 1, 2).jd
         | 
| 1191 | 
            +
             *   # => 2454834
         | 
| 1192 | 
            +
             */
         | 
| 1193 | 
            +
            static VALUE rhrdt_jd(VALUE self) {
         | 
| 1194 | 
            +
              rhrdt_t *d;
         | 
| 1195 | 
            +
              Data_Get_Struct(self, rhrdt_t, d);
         | 
| 1196 | 
            +
              RHRDT_FILL_JD(d)
         | 
| 1197 | 
            +
              return LONG2NUM(d->jd);
         | 
| 1198 | 
            +
            }
         | 
| 1199 | 
            +
             | 
| 1200 | 
            +
            /* call-seq:
         | 
| 1201 | 
            +
             *   ld() -> Integer
         | 
| 1202 | 
            +
             *
         | 
| 1203 | 
            +
             * Return the number of days since the Lilian Date (the day of calendar reform
         | 
| 1204 | 
            +
             * in Italy).
         | 
| 1205 | 
            +
             *
         | 
| 1206 | 
            +
             *   DateTime.civil(2009, 1, 2).ld
         | 
| 1207 | 
            +
             *   # => 155674
         | 
| 1208 | 
            +
             */
         | 
| 1209 | 
            +
            static VALUE rhrdt_ld(VALUE self) {
         | 
| 1210 | 
            +
              rhrdt_t *d;
         | 
| 1211 | 
            +
              Data_Get_Struct(self, rhrdt_t, d);
         | 
| 1212 | 
            +
              RHRDT_FILL_JD(d)
         | 
| 1213 | 
            +
              return LONG2NUM(d->jd - RHR_JD_LD);
         | 
| 1214 | 
            +
            }
         | 
| 1215 | 
            +
             | 
| 1216 | 
            +
            /* call-seq:
         | 
| 1217 | 
            +
             *   leap?() -> true or false
         | 
| 1218 | 
            +
             *
         | 
| 1219 | 
            +
             * Return +true+ if the current year for this date is a leap year
         | 
| 1220 | 
            +
             * in the Gregorian calendar, +false+ otherwise.
         | 
| 1221 | 
            +
             *
         | 
| 1222 | 
            +
             *   DateTime.civil(2009, 1, 2).leap?
         | 
| 1223 | 
            +
             *   # => false
         | 
| 1224 | 
            +
             *   DateTime.civil(2008, 1, 2).leap?
         | 
| 1225 | 
            +
             *   # => true
         | 
| 1226 | 
            +
             */
         | 
| 1227 | 
            +
            static VALUE rhrdt_leap_q(VALUE self) {
         | 
| 1228 | 
            +
              rhrdt_t *d;
         | 
| 1229 | 
            +
              Data_Get_Struct(self, rhrdt_t, d);
         | 
| 1230 | 
            +
              RHRDT_FILL_CIVIL(d)
         | 
| 1231 | 
            +
              return rhrd__leap_year(d->year) ? Qtrue : Qfalse;
         | 
| 1232 | 
            +
            }
         | 
| 1233 | 
            +
             | 
| 1234 | 
            +
            /* call-seq:
         | 
| 1235 | 
            +
             *   min() -> Integer
         | 
| 1236 | 
            +
             *
         | 
| 1237 | 
            +
             * Returns the minute of the hour as an +Integer+. Example:
         | 
| 1238 | 
            +
             * 
         | 
| 1239 | 
            +
             *   DateTime.civil(2009, 1, 2, 12, 13, 14).min
         | 
| 1240 | 
            +
             *   # => 13
         | 
| 1241 | 
            +
             */
         | 
| 1242 | 
            +
            static VALUE rhrdt_min(VALUE self) {
         | 
| 1243 | 
            +
              rhrdt_t *dt;
         | 
| 1244 | 
            +
              Data_Get_Struct(self, rhrdt_t, dt);
         | 
| 1245 | 
            +
              RHRDT_FILL_HMS(dt)
         | 
| 1246 | 
            +
              return LONG2NUM(dt->minute);
         | 
| 1247 | 
            +
            }
         | 
| 1248 | 
            +
             | 
| 1249 | 
            +
            /* call-seq:
         | 
| 1250 | 
            +
             *   mjd() -> Integer
         | 
| 1251 | 
            +
             *
         | 
| 1252 | 
            +
             * Return the number of days since 1858-11-17.
         | 
| 1253 | 
            +
             *
         | 
| 1254 | 
            +
             *   DateTime.civil(2009, 1, 2).mjd
         | 
| 1255 | 
            +
             *   # => 54833
         | 
| 1256 | 
            +
             */
         | 
| 1257 | 
            +
            static VALUE rhrdt_mjd(VALUE self) {
         | 
| 1258 | 
            +
              rhrdt_t *d;
         | 
| 1259 | 
            +
              Data_Get_Struct(self, rhrdt_t, d);
         | 
| 1260 | 
            +
              RHRDT_FILL_JD(d)
         | 
| 1261 | 
            +
              return LONG2NUM(d->jd - RHR_JD_MJD);
         | 
| 1262 | 
            +
            }
         | 
| 1263 | 
            +
             | 
| 1264 | 
            +
            /* call-seq:
         | 
| 1265 | 
            +
             *   month() -> Integer
         | 
| 1266 | 
            +
             *
         | 
| 1267 | 
            +
             * Returns the number of the month as an +Integer+. Example:
         | 
| 1268 | 
            +
             * 
         | 
| 1269 | 
            +
             *   DateTime.civil(2009, 1, 2).month
         | 
| 1270 | 
            +
             *   # => 1
         | 
| 1271 | 
            +
             */
         | 
| 1272 | 
            +
            static VALUE rhrdt_month(VALUE self) {
         | 
| 1273 | 
            +
              rhrdt_t *dt;
         | 
| 1274 | 
            +
              Data_Get_Struct(self, rhrdt_t, dt);
         | 
| 1275 | 
            +
              RHRDT_FILL_CIVIL(dt)
         | 
| 1276 | 
            +
              return LONG2NUM(dt->month);
         | 
| 1277 | 
            +
            }
         | 
| 1278 | 
            +
             | 
| 1279 | 
            +
            /* call-seq:
         | 
| 1280 | 
            +
             *   new_offset() -> DateTime
         | 
| 1281 | 
            +
             *
         | 
| 1282 | 
            +
             * Returns a +DateTime+ with the same absolute time as the current
         | 
| 1283 | 
            +
             * time, but a potentially different local time.  The returned value will
         | 
| 1284 | 
            +
             * be equal to the receiver.
         | 
| 1285 | 
            +
             * Raises +ArgumentError+ if an invalid offset is specified.
         | 
| 1286 | 
            +
             * Example:
         | 
| 1287 | 
            +
             * 
         | 
| 1288 | 
            +
             *   DateTime.civil(2009, 1, 2).new_offset(0.5)
         | 
| 1289 | 
            +
             *   # => #<DateTime 2009-01-02T12:00:00+12:00>
         | 
| 1290 | 
            +
             *   DateTime.civil(2009, 1, 2).new_offset(0.5)
         | 
| 1291 | 
            +
             *   # => #<DateTime 2009-01-01T12:00:00-12:00>
         | 
| 1292 | 
            +
             */
         | 
| 1293 | 
            +
            static VALUE rhrdt_new_offset(int argc, VALUE *argv, VALUE self) {
         | 
| 1294 | 
            +
              double offset;
         | 
| 1295 | 
            +
             | 
| 1296 | 
            +
              switch(argc) {
         | 
| 1297 | 
            +
                case 0:
         | 
| 1298 | 
            +
                  offset = 0;
         | 
| 1299 | 
            +
                  break;
         | 
| 1300 | 
            +
                case 1:
         | 
| 1301 | 
            +
                  if (RTEST(rb_obj_is_kind_of(argv[0], rb_cString))) {
         | 
| 1302 | 
            +
                    offset = NUM2LONG(rhrd_s_zone_to_diff(self, argv[0]))/RHR_SECONDS_PER_DAYD;
         | 
| 1303 | 
            +
                  } else {
         | 
| 1304 | 
            +
                    offset = NUM2DBL(argv[0]);
         | 
| 1305 | 
            +
                  }
         | 
| 1306 | 
            +
                  break;
         | 
| 1307 | 
            +
                default:
         | 
| 1308 | 
            +
                  rb_raise(rb_eArgError, "wrong number of arguments: %i for 1", argc);
         | 
| 1309 | 
            +
                  break;
         | 
| 1310 | 
            +
              }
         | 
| 1311 | 
            +
              return rhrdt__new_offset(self, offset);
         | 
| 1312 | 
            +
            }
         | 
| 1313 | 
            +
             | 
| 1314 | 
            +
            /* call-seq:
         | 
| 1315 | 
            +
             *   next() -> DateTime
         | 
| 1316 | 
            +
             *
         | 
| 1317 | 
            +
             * Returns the +DateTime+ after the receiver's date.  If the receiver
         | 
| 1318 | 
            +
             * has a fractional day component, the result will have the same
         | 
| 1319 | 
            +
             * fractional day component.
         | 
| 1320 | 
            +
             * 
         | 
| 1321 | 
            +
             *   DateTime.civil(2009, 1, 2, 12).next
         | 
| 1322 | 
            +
             *   # => #<DateTime 2009-01-03T12:00:00+00:00>
         | 
| 1323 | 
            +
             */
         | 
| 1324 | 
            +
            static VALUE rhrdt_next(VALUE self) {
         | 
| 1325 | 
            +
               return rhrdt__add_days(self, 1);
         | 
| 1326 | 
            +
            }
         | 
| 1327 | 
            +
             | 
| 1328 | 
            +
            /* call-seq:
         | 
| 1329 | 
            +
             *   offset() -> Float
         | 
| 1330 | 
            +
             *
         | 
| 1331 | 
            +
             * Returns a +Float+ representing the offset from UTC as a fraction
         | 
| 1332 | 
            +
             * of the day, where 0.5 would be 12 hours ahead of UTC ("+12:00"),
         | 
| 1333 | 
            +
             * and -0.5 would be 12 hours behind UTC ("-12:00").
         | 
| 1334 | 
            +
             * 
         | 
| 1335 | 
            +
             *   DateTime.civil(2009, 1, 2, 12, 13, 14, -0.5).offset
         | 
| 1336 | 
            +
             *   # => -0.5
         | 
| 1337 | 
            +
             */
         | 
| 1338 | 
            +
            static VALUE rhrdt_offset(VALUE self) {
         | 
| 1339 | 
            +
              rhrdt_t *dt;
         | 
| 1340 | 
            +
              RHR_CACHED_IV(self, rhrd_id_offset)
         | 
| 1341 | 
            +
              Data_Get_Struct(self, rhrdt_t, dt);
         | 
| 1342 | 
            +
              return rb_ivar_set(self, rhrd_id_offset, rb_float_new(dt->offset/1440.0));
         | 
| 1343 | 
            +
            }
         | 
| 1344 | 
            +
             | 
| 1345 | 
            +
            /* call-seq:
         | 
| 1346 | 
            +
             *   sec() -> Integer
         | 
| 1347 | 
            +
             *
         | 
| 1348 | 
            +
             * Returns the second of the minute as an +Integer+. Example:
         | 
| 1349 | 
            +
             * 
         | 
| 1350 | 
            +
             *   DateTime.civil(2009, 1, 2, 12, 13, 14).sec
         | 
| 1351 | 
            +
             *   # => 14
         | 
| 1352 | 
            +
             */
         | 
| 1353 | 
            +
            static VALUE rhrdt_sec(VALUE self) {
         | 
| 1354 | 
            +
              rhrdt_t *dt;
         | 
| 1355 | 
            +
              Data_Get_Struct(self, rhrdt_t, dt);
         | 
| 1356 | 
            +
              RHRDT_FILL_HMS(dt)
         | 
| 1357 | 
            +
              return LONG2NUM(dt->second);
         | 
| 1358 | 
            +
            }
         | 
| 1359 | 
            +
             | 
| 1360 | 
            +
            /* call-seq:
         | 
| 1361 | 
            +
             *   sec_fraction() -> Float
         | 
| 1362 | 
            +
             *
         | 
| 1363 | 
            +
             * Returns a +Float+ representing the fraction of the second as a
         | 
| 1364 | 
            +
             * fraction of the day, which will always be in the range [0.0, 1/86400.0).
         | 
| 1365 | 
            +
             * 
         | 
| 1366 | 
            +
             *   (DateTime.civil(2009, 1, 2, 12, 13, 14) + (1.5/86400)).sec_fraction
         | 
| 1367 | 
            +
             *   # => 0.000005787037
         | 
| 1368 | 
            +
             */
         | 
| 1369 | 
            +
            static VALUE rhrdt_sec_fraction(VALUE self) {
         | 
| 1370 | 
            +
              rhrdt_t *dt;
         | 
| 1371 | 
            +
              Data_Get_Struct(self, rhrdt_t, dt);
         | 
| 1372 | 
            +
              RHRDT_FILL_NANOS(dt)
         | 
| 1373 | 
            +
              return rb_float_new((dt->nanos % RHR_NANOS_PER_SECOND)/RHR_NANOS_PER_DAYD);
         | 
| 1374 | 
            +
            } 
         | 
| 1375 | 
            +
             | 
| 1376 | 
            +
            /* call-seq:
         | 
| 1377 | 
            +
             *   step(target, step=1){|datetime|} -> DateTime
         | 
| 1378 | 
            +
             *
         | 
| 1379 | 
            +
             * Yields +DateTime+ objects between the receiver and the +target+ date
         | 
| 1380 | 
            +
             * (inclusive), with +step+ days between each yielded date.
         | 
| 1381 | 
            +
             * +step+ may be a an +Integer+, in which case whole days are added,
         | 
| 1382 | 
            +
             * or it can be a +Float+, in which case fractional days are added.
         | 
| 1383 | 
            +
             * +step+ can be negative, in which case the dates are yielded in
         | 
| 1384 | 
            +
             * reverse chronological order.  Returns self in all cases.
         | 
| 1385 | 
            +
             *
         | 
| 1386 | 
            +
             * If +target+ is equal to the receiver, yields self once regardless of
         | 
| 1387 | 
            +
             * +step+. It +target+ is less than receiver and +step+ is nonnegative, or
         | 
| 1388 | 
            +
             * +target+ is greater than receiver and +step+ is nonpositive, does not
         | 
| 1389 | 
            +
             * yield.
         | 
| 1390 | 
            +
             * 
         | 
| 1391 | 
            +
             *   DateTime.civil(2009, 1, 2).step(DateTime.civil(2009, 1, 6), 2) do |datetime|
         | 
| 1392 | 
            +
             *     puts datetime
         | 
| 1393 | 
            +
             *   end
         | 
| 1394 | 
            +
             *   # Output:
         | 
| 1395 | 
            +
             *   # 2009-01-02T00:00:00+00:00
         | 
| 1396 | 
            +
             *   # 2009-01-04T00:00:00+00:00
         | 
| 1397 | 
            +
             *   # 2009-01-06T00:00:00+00:00
         | 
| 1398 | 
            +
             *   # 
         | 
| 1399 | 
            +
             */
         | 
| 1400 | 
            +
            static VALUE rhrdt_step(int argc, VALUE *argv, VALUE self) {
         | 
| 1401 | 
            +
              rhrdt_t *d, *ndt, *d0;
         | 
| 1402 | 
            +
              rhrd_t *nd;
         | 
| 1403 | 
            +
              double step, limit;
         | 
| 1404 | 
            +
              long long step_nanos, limit_nanos, current_nanos;
         | 
| 1405 | 
            +
              long step_jd, limit_jd, current_jd;
         | 
| 1406 | 
            +
              VALUE rlimit, new;
         | 
| 1407 | 
            +
              Data_Get_Struct(self, rhrdt_t, d);
         | 
| 1408 | 
            +
              Data_Get_Struct(rhrdt__new_offset(self, 0), rhrdt_t, d0);
         | 
| 1409 | 
            +
             | 
| 1410 | 
            +
              rb_need_block();
         | 
| 1411 | 
            +
              switch(argc) {
         | 
| 1412 | 
            +
                case 1:
         | 
| 1413 | 
            +
                  step_nanos = 0;
         | 
| 1414 | 
            +
                  step_jd = 1;
         | 
| 1415 | 
            +
                  break;
         | 
| 1416 | 
            +
                case 2:
         | 
| 1417 | 
            +
                  step = NUM2DBL(argv[1]);
         | 
| 1418 | 
            +
                  step_jd = floor(step);
         | 
| 1419 | 
            +
                  step_nanos = llround((step - step_jd)*RHR_NANOS_PER_DAY);
         | 
| 1420 | 
            +
                  break;
         | 
| 1421 | 
            +
                default:
         | 
| 1422 | 
            +
                  rb_raise(rb_eArgError, "wrong number of arguments: %i for 2", argc);
         | 
| 1423 | 
            +
                  break;
         | 
| 1424 | 
            +
              }
         | 
| 1425 | 
            +
             | 
| 1426 | 
            +
              rlimit = argv[0];
         | 
| 1427 | 
            +
              if (RTEST(rb_obj_is_kind_of(rlimit, rb_cNumeric))) {
         | 
| 1428 | 
            +
                limit = NUM2DBL(rlimit);
         | 
| 1429 | 
            +
                limit_jd = floor(limit);
         | 
| 1430 | 
            +
                limit_nanos = llround((limit - limit_jd)*RHR_NANOS_PER_DAY);
         | 
| 1431 | 
            +
              } else if (RTEST((rb_obj_is_kind_of(rlimit, rhrdt_class)))) {
         | 
| 1432 | 
            +
                rlimit = rhrdt__new_offset(rlimit, 0);
         | 
| 1433 | 
            +
                Data_Get_Struct(rlimit, rhrdt_t, ndt);
         | 
| 1434 | 
            +
                RHRDT_FILL_JD(ndt)
         | 
| 1435 | 
            +
                RHRDT_FILL_NANOS(ndt)
         | 
| 1436 | 
            +
                limit_jd = ndt->jd; 
         | 
| 1437 | 
            +
                limit_nanos = ndt->nanos;
         | 
| 1438 | 
            +
              } else if (RTEST((rb_obj_is_kind_of(rlimit, rhrd_class)))) {
         | 
| 1439 | 
            +
                Data_Get_Struct(rlimit, rhrd_t, nd);
         | 
| 1440 | 
            +
                RHR_FILL_JD(nd)
         | 
| 1441 | 
            +
                limit_jd = nd->jd; 
         | 
| 1442 | 
            +
                limit_nanos = d->offset*RHR_NANOS_PER_MINUTE;
         | 
| 1443 | 
            +
                if (limit_nanos < 0) {
         | 
| 1444 | 
            +
                  limit_jd--;
         | 
| 1445 | 
            +
                  limit_nanos += RHR_NANOS_PER_DAY;
         | 
| 1446 | 
            +
                }
         | 
| 1447 | 
            +
              } else {
         | 
| 1448 | 
            +
                rb_raise(rb_eTypeError, "expected numeric or date");
         | 
| 1449 | 
            +
              }
         | 
| 1450 | 
            +
             | 
| 1451 | 
            +
              current_jd = d0->jd;
         | 
| 1452 | 
            +
              current_nanos = d0->nanos;
         | 
| 1453 | 
            +
              new = rhrdt__from_jd_nanos(current_jd, current_nanos, d->offset);
         | 
| 1454 | 
            +
              if (limit_jd > current_jd || (limit_jd == current_jd && limit_nanos > current_nanos)) {
         | 
| 1455 | 
            +
                if (step_jd > 0 || (step_jd == 0 && step_nanos > 0)) {
         | 
| 1456 | 
            +
                  while (limit_jd > current_jd || (limit_jd == current_jd && limit_nanos >= current_nanos)) {
         | 
| 1457 | 
            +
                    rb_yield(new);
         | 
| 1458 | 
            +
                    new = rhrdt__from_jd_nanos(current_jd + step_jd, current_nanos + step_nanos, d->offset);
         | 
| 1459 | 
            +
                    Data_Get_Struct(new, rhrdt_t, ndt);
         | 
| 1460 | 
            +
                    current_jd = ndt->jd;
         | 
| 1461 | 
            +
                    current_nanos = ndt->nanos;
         | 
| 1462 | 
            +
                  }
         | 
| 1463 | 
            +
                }
         | 
| 1464 | 
            +
              } else if (limit_jd < current_jd || (limit_jd == current_jd && limit_nanos < current_nanos)) {
         | 
| 1465 | 
            +
                if (step_jd < 0 || (step_jd == 0 && step_nanos < 0)) {
         | 
| 1466 | 
            +
                  while (limit_jd < current_jd || (limit_jd == current_jd && limit_nanos <= current_nanos)) {
         | 
| 1467 | 
            +
                    rb_yield(new);
         | 
| 1468 | 
            +
                    new = rhrdt__from_jd_nanos(current_jd + step_jd, current_nanos + step_nanos, d->offset);
         | 
| 1469 | 
            +
                    Data_Get_Struct(new, rhrdt_t, ndt);
         | 
| 1470 | 
            +
                    current_jd = ndt->jd;
         | 
| 1471 | 
            +
                    current_nanos = ndt->nanos;
         | 
| 1472 | 
            +
                  }
         | 
| 1473 | 
            +
                }
         | 
| 1474 | 
            +
              } else {
         | 
| 1475 | 
            +
                rb_yield(self);
         | 
| 1476 | 
            +
              }
         | 
| 1477 | 
            +
             | 
| 1478 | 
            +
              return self;
         | 
| 1479 | 
            +
            }
         | 
| 1480 | 
            +
             | 
| 1481 | 
            +
            /* call-seq:
         | 
| 1482 | 
            +
             *   strftime() -> String <br />
         | 
| 1483 | 
            +
             *   strftime(format) -> String
         | 
| 1484 | 
            +
             *
         | 
| 1485 | 
            +
             * If no argument is provided, returns a string in ISO8601 format, just like
         | 
| 1486 | 
            +
             * +to_s+.  If an argument is provided, uses it as a format string and returns
         | 
| 1487 | 
            +
             * a +String+ based on the format. See <tt>Date#strftime</tt> for the supported
         | 
| 1488 | 
            +
             * formats.
         | 
| 1489 | 
            +
             */
         | 
| 1490 | 
            +
            static VALUE rhrdt_strftime(int argc, VALUE *argv, VALUE self) {
         | 
| 1491 | 
            +
              rhrdt_t* dt;
         | 
| 1492 | 
            +
              VALUE r;
         | 
| 1493 | 
            +
             | 
| 1494 | 
            +
              switch(argc) {
         | 
| 1495 | 
            +
                case 0:
         | 
| 1496 | 
            +
                  return rhrdt_to_s(self);
         | 
| 1497 | 
            +
                case 1:
         | 
| 1498 | 
            +
                  r = rb_str_to_str(argv[0]);
         | 
| 1499 | 
            +
                  break;
         | 
| 1500 | 
            +
                default:
         | 
| 1501 | 
            +
                  rb_raise(rb_eArgError, "wrong number of arguments: %i for 1", argc);
         | 
| 1502 | 
            +
                  break;
         | 
| 1503 | 
            +
              }
         | 
| 1504 | 
            +
             | 
| 1505 | 
            +
              Data_Get_Struct(self, rhrdt_t, dt);
         | 
| 1506 | 
            +
              RHRDT_FILL_CIVIL(dt)
         | 
| 1507 | 
            +
              RHRDT_FILL_JD(dt)
         | 
| 1508 | 
            +
              RHRDT_FILL_HMS(dt)
         | 
| 1509 | 
            +
              RHRDT_FILL_NANOS(dt)
         | 
| 1510 | 
            +
              return rhrd__strftime(dt, RSTRING_PTR(r), RSTRING_LEN(r));
         | 
| 1511 | 
            +
            }
         | 
| 1512 | 
            +
             | 
| 1513 | 
            +
            /* call-seq:
         | 
| 1514 | 
            +
             *   to_s() -> String
         | 
| 1515 | 
            +
             *
         | 
| 1516 | 
            +
             * Returns the receiver as an ISO8601 formatted string.
         | 
| 1517 | 
            +
             * 
         | 
| 1518 | 
            +
             *   DateTime.civil(2009, 1, 2, 12, 13, 14, 0.5).to_s
         | 
| 1519 | 
            +
             *   # => "2009-01-02T12:13:14+12:00"
         | 
| 1520 | 
            +
             */
         | 
| 1521 | 
            +
            static VALUE rhrdt_to_s(VALUE self) {
         | 
| 1522 | 
            +
              VALUE s;
         | 
| 1523 | 
            +
              rhrdt_t *dt;
         | 
| 1524 | 
            +
              int len;
         | 
| 1525 | 
            +
              Data_Get_Struct(self, rhrdt_t, dt);
         | 
| 1526 | 
            +
              RHRDT_FILL_CIVIL(dt)
         | 
| 1527 | 
            +
              RHRDT_FILL_HMS(dt)
         | 
| 1528 | 
            +
             | 
| 1529 | 
            +
              s = rb_str_buf_new(128);
         | 
| 1530 | 
            +
              len = snprintf(RSTRING_PTR(s), 128, "%04li-%02hhi-%02hhiT%02hhi:%02hhi:%02hhi%+03i:%02i",
         | 
| 1531 | 
            +
                    dt->year, dt->month, dt->day, dt->hour, dt->minute, dt->second, dt->offset/60, abs(dt->offset % 60));
         | 
| 1532 | 
            +
              if (len == -1 || len > 127) {
         | 
| 1533 | 
            +
                rb_raise(rb_eNoMemError, "in DateTime#to_s (in snprintf)");
         | 
| 1534 | 
            +
              }
         | 
| 1535 | 
            +
             | 
| 1536 | 
            +
              RHR_RETURN_RESIZED_STR(s, len)
         | 
| 1537 | 
            +
            }
         | 
| 1538 | 
            +
             | 
| 1539 | 
            +
            /* call-seq:
         | 
| 1540 | 
            +
             *   upto(target){|datetime|} -> DateTime
         | 
| 1541 | 
            +
             *
         | 
| 1542 | 
            +
             * Equivalent to calling +step+ with the +target+ as the first argument. Returns self.
         | 
| 1543 | 
            +
             * 
         | 
| 1544 | 
            +
             *   DateTime.civil(2009, 1, 1).upto(DateTime.civil(2009, 1, 2)) do |datetime|
         | 
| 1545 | 
            +
             *     puts datetime
         | 
| 1546 | 
            +
             *   end
         | 
| 1547 | 
            +
             *   # Output:
         | 
| 1548 | 
            +
             *   # 2009-01-01T00:00:00+00:00
         | 
| 1549 | 
            +
             *   # 2009-01-02T00:00:00+00:00
         | 
| 1550 | 
            +
             */
         | 
| 1551 | 
            +
            static VALUE rhrdt_upto(VALUE self, VALUE other) {
         | 
| 1552 | 
            +
              VALUE argv[1];
         | 
| 1553 | 
            +
              argv[0] = other;
         | 
| 1554 | 
            +
              return rhrdt_step(1, argv, self);
         | 
| 1555 | 
            +
            }
         | 
| 1556 | 
            +
             | 
| 1557 | 
            +
            /* call-seq:
         | 
| 1558 | 
            +
             *   wday() -> Integer
         | 
| 1559 | 
            +
             *
         | 
| 1560 | 
            +
             * Returns the day of the week as an +Integer+, where Sunday
         | 
| 1561 | 
            +
             * is 0 and Saturday is 6. Example:
         | 
| 1562 | 
            +
             * 
         | 
| 1563 | 
            +
             *   DateTime.civil(2009, 1, 2).wday
         | 
| 1564 | 
            +
             *   # => 5
         | 
| 1565 | 
            +
             */
         | 
| 1566 | 
            +
            static VALUE rhrdt_wday(VALUE self) {
         | 
| 1567 | 
            +
              rhrdt_t *d;
         | 
| 1568 | 
            +
              Data_Get_Struct(self, rhrdt_t, d);
         | 
| 1569 | 
            +
              RHRDT_FILL_JD(d)
         | 
| 1570 | 
            +
              return LONG2NUM(rhrd__jd_to_wday(d->jd));
         | 
| 1571 | 
            +
            }
         | 
| 1572 | 
            +
             | 
| 1573 | 
            +
            /* call-seq:
         | 
| 1574 | 
            +
             *   yday() -> Integer
         | 
| 1575 | 
            +
             *
         | 
| 1576 | 
            +
             * Returns the day of the year as an +Integer+, where January
         | 
| 1577 | 
            +
             * 1st is 1 and December 31 is 365 (or 366 if the year is a leap
         | 
| 1578 | 
            +
             * year). Example:
         | 
| 1579 | 
            +
             * 
         | 
| 1580 | 
            +
             *   DateTime.civil(2009, 2, 2).yday
         | 
| 1581 | 
            +
             *   # => 33
         | 
| 1582 | 
            +
             */
         | 
| 1583 | 
            +
            static VALUE rhrdt_yday(VALUE self) {
         | 
| 1584 | 
            +
              rhrdt_t *d;
         | 
| 1585 | 
            +
              Data_Get_Struct(self, rhrdt_t, d);
         | 
| 1586 | 
            +
              RHRDT_FILL_CIVIL(d)
         | 
| 1587 | 
            +
              return LONG2NUM(rhrd__ordinal_day(d->year, d->month, d->day));
         | 
| 1588 | 
            +
            }
         | 
| 1589 | 
            +
             | 
| 1590 | 
            +
            /* call-seq:
         | 
| 1591 | 
            +
             *   year() -> Integer
         | 
| 1592 | 
            +
             *
         | 
| 1593 | 
            +
             * Returns the year as an +Integer+. Example:
         | 
| 1594 | 
            +
             * 
         | 
| 1595 | 
            +
             *   DateTime.civil(2009, 1, 2).year
         | 
| 1596 | 
            +
             *   # => 2009
         | 
| 1597 | 
            +
             */
         | 
| 1598 | 
            +
            static VALUE rhrdt_year(VALUE self) {
         | 
| 1599 | 
            +
              rhrdt_t *dt;
         | 
| 1600 | 
            +
              Data_Get_Struct(self, rhrdt_t, dt);
         | 
| 1601 | 
            +
              RHRDT_FILL_CIVIL(dt)
         | 
| 1602 | 
            +
              return LONG2NUM(dt->year);
         | 
| 1603 | 
            +
            }
         | 
| 1604 | 
            +
             | 
| 1605 | 
            +
            /* call-seq:
         | 
| 1606 | 
            +
             *   zone() -> String
         | 
| 1607 | 
            +
             *
         | 
| 1608 | 
            +
             * Returns the time zone as a formatted string.  This always uses
         | 
| 1609 | 
            +
             * a numeric representation based on the offset, as +DateTime+ instances
         | 
| 1610 | 
            +
             * do not keep information about named timezones. 
         | 
| 1611 | 
            +
             * 
         | 
| 1612 | 
            +
             *   DateTime.civil(2009, 1, 2, 12, 13, 14, 0.5).zone
         | 
| 1613 | 
            +
             *   # => "+12:00"
         | 
| 1614 | 
            +
             */
         | 
| 1615 | 
            +
            static VALUE rhrdt_zone(VALUE self) {
         | 
| 1616 | 
            +
              VALUE s;
         | 
| 1617 | 
            +
              rhrdt_t *dt;
         | 
| 1618 | 
            +
              int len;
         | 
| 1619 | 
            +
              Data_Get_Struct(self, rhrdt_t, dt);
         | 
| 1620 | 
            +
             | 
| 1621 | 
            +
              s = rb_str_buf_new(128);
         | 
| 1622 | 
            +
              len = snprintf(RSTRING_PTR(s), 128, "%+03i:%02i", dt->offset/60, abs(dt->offset % 60));
         | 
| 1623 | 
            +
              if (len == -1 || len > 127) {
         | 
| 1624 | 
            +
                rb_raise(rb_eNoMemError, "in DateTime#zone (in snprintf)");
         | 
| 1625 | 
            +
              }
         | 
| 1626 | 
            +
             | 
| 1627 | 
            +
              RHR_RETURN_RESIZED_STR(s, len)
         | 
| 1628 | 
            +
            }
         | 
| 1629 | 
            +
             | 
| 1630 | 
            +
            /* Ruby instance operator methods */ 
         | 
| 1631 | 
            +
             | 
| 1632 | 
            +
            /* call-seq:
         | 
| 1633 | 
            +
             *   >>(n) -> DateTime
         | 
| 1634 | 
            +
             *
         | 
| 1635 | 
            +
             * Returns a +DateTime+ that is +n+ months after the receiver. +n+
         | 
| 1636 | 
            +
             * can be negative, in which case it returns a +DateTime+ before
         | 
| 1637 | 
            +
             * the receiver.
         | 
| 1638 | 
            +
             * 
         | 
| 1639 | 
            +
             *   DateTime.civil(2009, 1, 2) >> 2
         | 
| 1640 | 
            +
             *   # => #<DateTime 2009-03-02T00:00:00+00:00>
         | 
| 1641 | 
            +
             *   DateTime.civil(2009, 1, 2) >> -2
         | 
| 1642 | 
            +
             *   # => #<DateTime 2008-11-02T00:00:00+00:00>
         | 
| 1643 | 
            +
             */
         | 
| 1644 | 
            +
            static VALUE rhrdt_op_right_shift(VALUE self, VALUE other) {
         | 
| 1645 | 
            +
              return rhrdt__add_months(self, NUM2LONG(other));
         | 
| 1646 | 
            +
            }
         | 
| 1647 | 
            +
             | 
| 1648 | 
            +
            /* call-seq:
         | 
| 1649 | 
            +
             *   <<(n) -> DateTime
         | 
| 1650 | 
            +
             *
         | 
| 1651 | 
            +
             * Returns a +DateTime+ that is +n+ months before the receiver. +n+
         | 
| 1652 | 
            +
             * can be negative, in which case it returns a +DateTime+ after
         | 
| 1653 | 
            +
             * the receiver.
         | 
| 1654 | 
            +
             * 
         | 
| 1655 | 
            +
             *   DateTime.civil(2009, 1, 2) << 2
         | 
| 1656 | 
            +
             *   # => #<DateTime 2008-11-02T00:00:00+00:00>
         | 
| 1657 | 
            +
             *   DateTime.civil(2009, 1, 2) << -2
         | 
| 1658 | 
            +
             *   # => #<DateTime 2009-03-02T00:00:00+00:00>
         | 
| 1659 | 
            +
             */
         | 
| 1660 | 
            +
            static VALUE rhrdt_op_left_shift(VALUE self, VALUE other) {
         | 
| 1661 | 
            +
              return rhrdt__add_months(self, -NUM2LONG(other));
         | 
| 1662 | 
            +
            }
         | 
| 1663 | 
            +
             | 
| 1664 | 
            +
            /* call-seq:
         | 
| 1665 | 
            +
             *   +(n) -> DateTime
         | 
| 1666 | 
            +
             *
         | 
| 1667 | 
            +
             * Returns a +DateTime+ that is +n+ days after the receiver. +n+
         | 
| 1668 | 
            +
             * can be negative, in which case it returns a +DateTime+ before
         | 
| 1669 | 
            +
             * the receiver.  +n+ can be a +Float+ including a fractional part,
         | 
| 1670 | 
            +
             * in which case it is added as a partial day.
         | 
| 1671 | 
            +
             * 
         | 
| 1672 | 
            +
             *   DateTime.civil(2009, 1, 2, 6, 0, 0) + 2
         | 
| 1673 | 
            +
             *   # => #<DateTime 2009-01-04T06:00:00+00:00>
         | 
| 1674 | 
            +
             *   DateTime.civil(2009, 1, 2, 6, 0, 0) + -2
         | 
| 1675 | 
            +
             *   # => #<DateTime 2008-12-31T06:00:00+00:00>
         | 
| 1676 | 
            +
             *   DateTime.civil(2009, 1, 2, 6, 0, 0) + 0.5
         | 
| 1677 | 
            +
             *   # => #<DateTime 2009-01-02T18:00:00+00:00>
         | 
| 1678 | 
            +
             */
         | 
| 1679 | 
            +
            static VALUE rhrdt_op_plus(VALUE self, VALUE other) {
         | 
| 1680 | 
            +
               return rhrdt__add_days(self, NUM2DBL(other));
         | 
| 1681 | 
            +
            }
         | 
| 1682 | 
            +
             | 
| 1683 | 
            +
            /* call-seq:
         | 
| 1684 | 
            +
             *   -(n) -> DateTime <br />
         | 
| 1685 | 
            +
             *   -(date) -> Float <br />
         | 
| 1686 | 
            +
             *   -(datetime) -> Float
         | 
| 1687 | 
            +
             *
         | 
| 1688 | 
            +
             * If a +Numeric+ argument is given, it is treated as an +Float+,
         | 
| 1689 | 
            +
             * and the number of days it represents is substracted from the
         | 
| 1690 | 
            +
             * receiver to return a new +DateTime+ object. +n+ can be negative, in
         | 
| 1691 | 
            +
             * which case the +DateTime+ returned will be after the receiver.
         | 
| 1692 | 
            +
             *
         | 
| 1693 | 
            +
             * If a +Date+ argument is given, returns the number of days
         | 
| 1694 | 
            +
             * between the current date and the argument as an +Float+. If
         | 
| 1695 | 
            +
             * the receiver has no fractional component, will return a +Float+
         | 
| 1696 | 
            +
             * with no fractional component.  The +Date+ argument is assumed to
         | 
| 1697 | 
            +
             * have the same time zone offset as the receiver.
         | 
| 1698 | 
            +
             *
         | 
| 1699 | 
            +
             * If a +DateTime+ argument is given, returns the number of days
         | 
| 1700 | 
            +
             * between the receiver and the argument as a +Float+.  This
         | 
| 1701 | 
            +
             * handles differences in the time zone offsets between the
         | 
| 1702 | 
            +
             * receiver and the argument.
         | 
| 1703 | 
            +
             * 
         | 
| 1704 | 
            +
             * Other types of arguments raise a +TypeError+.
         | 
| 1705 | 
            +
             *
         | 
| 1706 | 
            +
             *   DateTime.civil(2009, 1, 2) - 2
         | 
| 1707 | 
            +
             *   # => #<DateTime 2008-12-31T00:00:00+00:00>
         | 
| 1708 | 
            +
             *   DateTime.civil(2009, 1, 2) - 2.5
         | 
| 1709 | 
            +
             *   # => #<DateTime 2008-12-30T12:00:00+00:00>
         | 
| 1710 | 
            +
             *   DateTime.civil(2009, 1, 2) - Date.civil(2009, 1, 1)
         | 
| 1711 | 
            +
             *   # => 1.0
         | 
| 1712 | 
            +
             *   DateTime.civil(2009, 1, 2, 12, 0, 0) - Date.civil(2009, 1, 1)
         | 
| 1713 | 
            +
             *   # => 1.5
         | 
| 1714 | 
            +
             *   DateTime.civil(2009, 1, 2, 12, 0, 0, 0.5) - Date.civil(2009, 1, 1)
         | 
| 1715 | 
            +
             *   # => 1.5
         | 
| 1716 | 
            +
             *   DateTime.civil(2009, 1, 2) - DateTime.civil(2009, 1, 3, 12)
         | 
| 1717 | 
            +
             *   # => -1.5
         | 
| 1718 | 
            +
             *   DateTime.civil(2009, 1, 2, 0, 0, 0, 0.5) - DateTime.civil(2009, 1, 3, 12, 0, 0, -0.5)
         | 
| 1719 | 
            +
             *   # => -2.5
         | 
| 1720 | 
            +
             */
         | 
| 1721 | 
            +
            static VALUE rhrdt_op_minus(VALUE self, VALUE other) {
         | 
| 1722 | 
            +
              rhrdt_t *dt;
         | 
| 1723 | 
            +
              rhrdt_t *newdt;
         | 
| 1724 | 
            +
              rhrd_t *newd;
         | 
| 1725 | 
            +
             | 
| 1726 | 
            +
              if (RTEST(rb_obj_is_kind_of(other, rb_cNumeric))) {
         | 
| 1727 | 
            +
                Data_Get_Struct(self, rhrdt_t, dt);
         | 
| 1728 | 
            +
                return rhrdt__add_days(self, -NUM2DBL(other));
         | 
| 1729 | 
            +
              }
         | 
| 1730 | 
            +
              if (RTEST((rb_obj_is_kind_of(other, rhrdt_class)))) {
         | 
| 1731 | 
            +
                self = rhrdt__new_offset(self, 0);
         | 
| 1732 | 
            +
                other = rhrdt__new_offset(other, 0);
         | 
| 1733 | 
            +
                Data_Get_Struct(self, rhrdt_t, dt);
         | 
| 1734 | 
            +
                Data_Get_Struct(other, rhrdt_t, newdt);
         | 
| 1735 | 
            +
                RHRDT_FILL_JD(dt)
         | 
| 1736 | 
            +
                RHRDT_FILL_NANOS(dt)
         | 
| 1737 | 
            +
                RHRDT_FILL_JD(newdt)
         | 
| 1738 | 
            +
                RHRDT_FILL_NANOS(newdt)
         | 
| 1739 | 
            +
                if (dt->nanos == newdt->nanos) {
         | 
| 1740 | 
            +
                  return rb_float_new(dt->jd - newdt->jd);
         | 
| 1741 | 
            +
                } else if (dt->jd == newdt->jd) 
         | 
| 1742 | 
            +
                  return rb_float_new((dt->nanos - newdt->nanos)/RHR_NANOS_PER_DAYD);
         | 
| 1743 | 
            +
                else {
         | 
| 1744 | 
            +
                  return rb_float_new((dt->jd - newdt->jd) + (dt->nanos - newdt->nanos)/RHR_NANOS_PER_DAYD);
         | 
| 1745 | 
            +
                }
         | 
| 1746 | 
            +
              }
         | 
| 1747 | 
            +
              if (RTEST((rb_obj_is_kind_of(other, rhrd_class)))) {
         | 
| 1748 | 
            +
                Data_Get_Struct(self, rhrdt_t, dt);
         | 
| 1749 | 
            +
                Data_Get_Struct(other, rhrd_t, newd);
         | 
| 1750 | 
            +
                RHRDT_FILL_JD(dt)
         | 
| 1751 | 
            +
                RHRDT_FILL_NANOS(dt)
         | 
| 1752 | 
            +
                RHR_FILL_JD(newd)
         | 
| 1753 | 
            +
                return rb_float_new((dt->jd - newd->jd) + dt->nanos/RHR_NANOS_PER_DAYD); 
         | 
| 1754 | 
            +
              }
         | 
| 1755 | 
            +
              rb_raise(rb_eTypeError, "expected numeric or date");
         | 
| 1756 | 
            +
            }
         | 
| 1757 | 
            +
             | 
| 1758 | 
            +
            /* call-seq:
         | 
| 1759 | 
            +
             *   ===(other) -> true or false
         | 
| 1760 | 
            +
             *
         | 
| 1761 | 
            +
             * If +other+ is a +Date+, returns +true+ if +other+ is the
         | 
| 1762 | 
            +
             * same date as the receiver, or +false+ otherwise.
         | 
| 1763 | 
            +
             *
         | 
| 1764 | 
            +
             * If +other+ is a +DateTime+, return +true+ if +other has the same
         | 
| 1765 | 
            +
             * julian date as the receiver, or +false+ otherwise.
         | 
| 1766 | 
            +
             *
         | 
| 1767 | 
            +
             * If +other+ is a +Numeric+, convert it to an +Integer+ and return
         | 
| 1768 | 
            +
             * +true+ if it is equal to the receiver's julian date, or +false+
         | 
| 1769 | 
            +
             * otherwise. 
         | 
| 1770 | 
            +
             */
         | 
| 1771 | 
            +
            static VALUE rhrdt_op_relationship(VALUE self, VALUE other) {
         | 
| 1772 | 
            +
              rhrdt_t *dt, *odt;
         | 
| 1773 | 
            +
              rhrd_t *o;
         | 
| 1774 | 
            +
              long jd;
         | 
| 1775 | 
            +
             | 
| 1776 | 
            +
              if (RTEST(rb_obj_is_kind_of(other, rhrdt_class))) {
         | 
| 1777 | 
            +
                Data_Get_Struct(other, rhrdt_t, odt);
         | 
| 1778 | 
            +
                RHRDT_FILL_JD(odt)
         | 
| 1779 | 
            +
                jd = odt->jd;
         | 
| 1780 | 
            +
              } else if (RTEST(rb_obj_is_kind_of(other, rhrd_class))) {
         | 
| 1781 | 
            +
                Data_Get_Struct(other, rhrd_t, o);
         | 
| 1782 | 
            +
                RHR_FILL_JD(o)
         | 
| 1783 | 
            +
                jd = o->jd;
         | 
| 1784 | 
            +
              } else if (RTEST((rb_obj_is_kind_of(other, rb_cNumeric)))) {
         | 
| 1785 | 
            +
                jd = NUM2LONG(other);
         | 
| 1786 | 
            +
              } else {
         | 
| 1787 | 
            +
                return Qfalse;
         | 
| 1788 | 
            +
              }
         | 
| 1789 | 
            +
             | 
| 1790 | 
            +
              Data_Get_Struct(self, rhrdt_t, dt);
         | 
| 1791 | 
            +
              RHRDT_FILL_JD(dt)
         | 
| 1792 | 
            +
              return dt->jd == jd ? Qtrue : Qfalse;
         | 
| 1793 | 
            +
            }
         | 
| 1794 | 
            +
             | 
| 1795 | 
            +
            /* call-seq:
         | 
| 1796 | 
            +
             *   <=>(other) -> -1, 0, 1, or nil
         | 
| 1797 | 
            +
             *
         | 
| 1798 | 
            +
             * If +other+ is a +DateTime+, returns -1 if the absolute date and time of
         | 
| 1799 | 
            +
             * +other+ is before the absolute time of the receiver chronologically,
         | 
| 1800 | 
            +
             * 0 if +other+ is the same absolute date and time as the receiver,
         | 
| 1801 | 
            +
             * or 1 if the absolute date and time of +other+ is before the receiver
         | 
| 1802 | 
            +
             * chronologically.  Absolute date and time in this case means after taking
         | 
| 1803 | 
            +
             * account the time zone offset.
         | 
| 1804 | 
            +
             *
         | 
| 1805 | 
            +
             * If +other+ is a +Date+, return 0 if +other+ has the same
         | 
| 1806 | 
            +
             * julian date as the receiver and the receiver has no fractional part,
         | 
| 1807 | 
            +
             * 1 if +other+ has a julian date greater than the receiver's, or
         | 
| 1808 | 
            +
             * -1 if +other+ has a julian date less than the receiver's or
         | 
| 1809 | 
            +
             * a julian date the same as the receiver's and the receiver has a
         | 
| 1810 | 
            +
             * fractional part. 
         | 
| 1811 | 
            +
             *
         | 
| 1812 | 
            +
             * If +other+ is a +Numeric+, convert it to an +Float+ and compare
         | 
| 1813 | 
            +
             * it to the receiver's julian date plus the fractional part. 
         | 
| 1814 | 
            +
             *
         | 
| 1815 | 
            +
             * For an unrecognized type, return +nil+.
         | 
| 1816 | 
            +
             */
         | 
| 1817 | 
            +
            static VALUE rhrdt_op_spaceship(VALUE self, VALUE other) {
         | 
| 1818 | 
            +
              rhrdt_t *dt, *odt;
         | 
| 1819 | 
            +
              rhrd_t *od;
         | 
| 1820 | 
            +
              double diff;
         | 
| 1821 | 
            +
              int res;
         | 
| 1822 | 
            +
             | 
| 1823 | 
            +
              if (RTEST(rb_obj_is_kind_of(other, rhrdt_class))) {
         | 
| 1824 | 
            +
                self = rhrdt__new_offset(self, 0);
         | 
| 1825 | 
            +
                other = rhrdt__new_offset(other, 0);
         | 
| 1826 | 
            +
                Data_Get_Struct(self, rhrdt_t, dt);
         | 
| 1827 | 
            +
                Data_Get_Struct(other, rhrdt_t, odt);
         | 
| 1828 | 
            +
                return LONG2NUM(rhrdt__spaceship(dt, odt));
         | 
| 1829 | 
            +
              }
         | 
| 1830 | 
            +
              if (RTEST(rb_obj_is_kind_of(other, rhrd_class))) {
         | 
| 1831 | 
            +
                Data_Get_Struct(self, rhrdt_t, dt);
         | 
| 1832 | 
            +
                Data_Get_Struct(other, rhrd_t, od);
         | 
| 1833 | 
            +
                RHRDT_FILL_JD(dt)
         | 
| 1834 | 
            +
                RHR_FILL_JD(od)
         | 
| 1835 | 
            +
                RHR_SPACE_SHIP(res, dt->jd, od->jd)
         | 
| 1836 | 
            +
                if (res == 0) {
         | 
| 1837 | 
            +
                  RHRDT_FILL_NANOS(dt)
         | 
| 1838 | 
            +
                  RHR_SPACE_SHIP(res, dt->nanos, 0)
         | 
| 1839 | 
            +
                }
         | 
| 1840 | 
            +
                return LONG2NUM(res);
         | 
| 1841 | 
            +
              }
         | 
| 1842 | 
            +
              if (RTEST((rb_obj_is_kind_of(other, rb_cNumeric)))) {
         | 
| 1843 | 
            +
                Data_Get_Struct(self, rhrdt_t, dt);
         | 
| 1844 | 
            +
                diff = NUM2DBL(other);
         | 
| 1845 | 
            +
                RHRDT_FILL_JD(dt)
         | 
| 1846 | 
            +
                RHR_SPACE_SHIP(res, dt->jd, (long)diff)
         | 
| 1847 | 
            +
                if (res == 0) {
         | 
| 1848 | 
            +
                  RHRDT_FILL_NANOS(dt)
         | 
| 1849 | 
            +
                  RHR_SPACE_SHIP(res, dt->nanos, llround((diff - floor(diff)) * RHR_NANOS_PER_DAY))
         | 
| 1850 | 
            +
                }
         | 
| 1851 | 
            +
                return LONG2NUM(res);
         | 
| 1852 | 
            +
              }
         | 
| 1853 | 
            +
              return Qnil;
         | 
| 1854 | 
            +
            }
         | 
| 1855 | 
            +
             | 
| 1856 | 
            +
            #ifdef RUBY19
         | 
| 1857 | 
            +
             | 
| 1858 | 
            +
            /* Ruby 1.9 helper methods */
         | 
| 1859 | 
            +
             | 
| 1860 | 
            +
            /* Same as rhrd__add_years, but for ruby DateTime values. */
         | 
| 1861 | 
            +
            VALUE rhrdt__add_years(VALUE self, long n) {
         | 
| 1862 | 
            +
              rhrdt_t *d;
         | 
| 1863 | 
            +
              rhrdt_t *newd;
         | 
| 1864 | 
            +
              VALUE new;
         | 
| 1865 | 
            +
              Data_Get_Struct(self, rhrdt_t, d);
         | 
| 1866 | 
            +
             | 
| 1867 | 
            +
              new = Data_Make_Struct(rhrdt_class, rhrdt_t, NULL, free, newd);
         | 
| 1868 | 
            +
              RHRDT_FILL_CIVIL(d)
         | 
| 1869 | 
            +
              memcpy(newd, d, sizeof(rhrdt_t));
         | 
| 1870 | 
            +
             | 
| 1871 | 
            +
              newd->year = rhrd__safe_add_long(n, d->year);
         | 
| 1872 | 
            +
              if(d->month == 2 && d->day == 29 && !rhrd__leap_year(newd->year)) {
         | 
| 1873 | 
            +
                newd->day = 28;
         | 
| 1874 | 
            +
              } 
         | 
| 1875 | 
            +
             | 
| 1876 | 
            +
              RHR_CHECK_CIVIL(newd)
         | 
| 1877 | 
            +
              newd->flags &= ~RHR_HAVE_JD;
         | 
| 1878 | 
            +
              return new;
         | 
| 1879 | 
            +
            }
         | 
| 1880 | 
            +
             | 
| 1881 | 
            +
            /* Same as rhrd__day_q, but for ruby DateTime values. */
         | 
| 1882 | 
            +
            VALUE rhrdt__day_q(VALUE self, long day) {
         | 
| 1883 | 
            +
              rhrdt_t *d;
         | 
| 1884 | 
            +
              Data_Get_Struct(self, rhrdt_t, d);
         | 
| 1885 | 
            +
              RHRDT_FILL_JD(d)
         | 
| 1886 | 
            +
              return rhrd__jd_to_wday(d->jd) == day ? Qtrue : Qfalse;
         | 
| 1887 | 
            +
            }
         | 
| 1888 | 
            +
             | 
| 1889 | 
            +
            /* Add i given fractional second decimal places to the string,
         | 
| 1890 | 
            +
             * starting at the given offset len in the string. */
         | 
| 1891 | 
            +
            long rhrdt__add_iso_time_format(rhrdt_t *dt, char *str, long len, long i) {
         | 
| 1892 | 
            +
              int l;
         | 
| 1893 | 
            +
             | 
| 1894 | 
            +
              RHRDT_FILL_HMS(dt)
         | 
| 1895 | 
            +
             | 
| 1896 | 
            +
              if (i < 1) {
         | 
| 1897 | 
            +
                i = 0;
         | 
| 1898 | 
            +
              } else if (i > 9) {
         | 
| 1899 | 
            +
                i = 9;
         | 
| 1900 | 
            +
              }
         | 
| 1901 | 
            +
             | 
| 1902 | 
            +
              l = snprintf(str + len, 128 - len, "T%02hhi:%02hhi:%02hhi", dt->hour, dt->minute, dt->second);
         | 
| 1903 | 
            +
              if (l == -1 || l > 127) {
         | 
| 1904 | 
            +
                rb_raise(rb_eNoMemError, "in DateTime formatting method (in snprintf)");
         | 
| 1905 | 
            +
              }
         | 
| 1906 | 
            +
              len += l;
         | 
| 1907 | 
            +
             | 
| 1908 | 
            +
              if (i) {
         | 
| 1909 | 
            +
                RHRDT_FILL_NANOS(dt)
         | 
| 1910 | 
            +
                l = snprintf(str + len, 128 - len, ".%09lli", dt->nanos % RHR_NANOS_PER_SECOND);
         | 
| 1911 | 
            +
                if (l == -1 || l > 127) {
         | 
| 1912 | 
            +
                  rb_raise(rb_eNoMemError, "in DateTime formatting method (in snprintf)");
         | 
| 1913 | 
            +
                }
         | 
| 1914 | 
            +
                len += i + 1;
         | 
| 1915 | 
            +
              }
         | 
| 1916 | 
            +
             | 
| 1917 | 
            +
              l = snprintf(str + len, 128 - len, "%+03i:%02i", dt->offset/60, abs(dt->offset % 60));
         | 
| 1918 | 
            +
              if (l == -1 || l > 127) {
         | 
| 1919 | 
            +
                rb_raise(rb_eNoMemError, "in DateTime formatting method (in snprintf)");
         | 
| 1920 | 
            +
              }
         | 
| 1921 | 
            +
             | 
| 1922 | 
            +
              return len + l;
         | 
| 1923 | 
            +
            }
         | 
| 1924 | 
            +
             | 
| 1925 | 
            +
            /* Ruby 1.9 class methods */
         | 
| 1926 | 
            +
             | 
| 1927 | 
            +
            /* call-seq:
         | 
| 1928 | 
            +
             *   [ruby 1-9 only] <br />
         | 
| 1929 | 
            +
             *   httpdate() -> DateTime <br />
         | 
| 1930 | 
            +
             *   httpdate(str, sg=nil) -> DateTime
         | 
| 1931 | 
            +
             *
         | 
| 1932 | 
            +
             * If no argument is given, returns a +DateTime+ for julian day 0.
         | 
| 1933 | 
            +
             * If an argument is given, it should be a string that is
         | 
| 1934 | 
            +
             * parsed using +_httpdate+, returning a +DateTime+ or raising
         | 
| 1935 | 
            +
             * an +ArgumentError+ if the string is not in a valid format
         | 
| 1936 | 
            +
             * or the datetime it represents is not a valid date or time.
         | 
| 1937 | 
            +
             * Ignores the 2nd argument.
         | 
| 1938 | 
            +
             * Example:
         | 
| 1939 | 
            +
             * 
         | 
| 1940 | 
            +
             *   DateTime.httpdate("Fri, 02 Jan 2009 03:04:05 GMT")
         | 
| 1941 | 
            +
             *   # => #<DateTime 2009-01-02T03:04:05+00:00>
         | 
| 1942 | 
            +
             */
         | 
| 1943 | 
            +
            static VALUE rhrdt_s_httpdate(int argc, VALUE *argv, VALUE klass) {
         | 
| 1944 | 
            +
              rhrdt_t *d;
         | 
| 1945 | 
            +
              VALUE rd;
         | 
| 1946 | 
            +
              rd = Data_Make_Struct(klass, rhrdt_t, NULL, free, d);
         | 
| 1947 | 
            +
             | 
| 1948 | 
            +
              switch(argc) {
         | 
| 1949 | 
            +
                case 0:
         | 
| 1950 | 
            +
                  d->flags = RHR_HAVE_JD | RHR_HAVE_HMS | RHR_HAVE_NANOS;
         | 
| 1951 | 
            +
                  return rd;
         | 
| 1952 | 
            +
                case 1:
         | 
| 1953 | 
            +
                case 2:
         | 
| 1954 | 
            +
                  rhrdt__fill_from_hash(d, rb_funcall(klass, rhrd_id__httpdate, 1, argv[0]));
         | 
| 1955 | 
            +
                  return rd;
         | 
| 1956 | 
            +
                default:
         | 
| 1957 | 
            +
                  rb_raise(rb_eArgError, "wrong number of arguments (%i for 2)", argc);
         | 
| 1958 | 
            +
                  break;
         | 
| 1959 | 
            +
              }
         | 
| 1960 | 
            +
            }
         | 
| 1961 | 
            +
             | 
| 1962 | 
            +
            /* call-seq:
         | 
| 1963 | 
            +
             *   [ruby 1-9 only] <br />
         | 
| 1964 | 
            +
             *   iso8601() -> DateTime <br />
         | 
| 1965 | 
            +
             *   iso8601(str, sg=nil) -> DateTime
         | 
| 1966 | 
            +
             *
         | 
| 1967 | 
            +
             * If no argument is given, returns a +DateTime+ for julian day 0.
         | 
| 1968 | 
            +
             * If an argument is given, it should be a string that is
         | 
| 1969 | 
            +
             * parsed using +_iso8601+, returning a +DateTime+ or raising
         | 
| 1970 | 
            +
             * an +ArgumentError+ if the string is not in a valid format
         | 
| 1971 | 
            +
             * or the datetime it represents is not a valid date or time.
         | 
| 1972 | 
            +
             * Ignores the 2nd argument.
         | 
| 1973 | 
            +
             * Example:
         | 
| 1974 | 
            +
             * 
         | 
| 1975 | 
            +
             *   DateTime.iso8601("2009-01-02T03:04:05+12:00")
         | 
| 1976 | 
            +
             *   # => #<DateTime 2009-01-02T03:04:05+12:00>
         | 
| 1977 | 
            +
             */
         | 
| 1978 | 
            +
            static VALUE rhrdt_s_iso8601(int argc, VALUE *argv, VALUE klass) {
         | 
| 1979 | 
            +
              rhrdt_t *d;
         | 
| 1980 | 
            +
              VALUE rd;
         | 
| 1981 | 
            +
              rd = Data_Make_Struct(klass, rhrdt_t, NULL, free, d);
         | 
| 1982 | 
            +
             | 
| 1983 | 
            +
              switch(argc) {
         | 
| 1984 | 
            +
                case 0:
         | 
| 1985 | 
            +
                  d->flags = RHR_HAVE_JD | RHR_HAVE_HMS | RHR_HAVE_NANOS;
         | 
| 1986 | 
            +
                  return rd;
         | 
| 1987 | 
            +
                case 1:
         | 
| 1988 | 
            +
                case 2:
         | 
| 1989 | 
            +
                  rhrdt__fill_from_hash(d, rb_funcall(klass, rhrd_id__iso8601, 1, argv[0]));
         | 
| 1990 | 
            +
                  return rd;
         | 
| 1991 | 
            +
                default:
         | 
| 1992 | 
            +
                  rb_raise(rb_eArgError, "wrong number of arguments (%i for 2)", argc);
         | 
| 1993 | 
            +
                  break;
         | 
| 1994 | 
            +
              }
         | 
| 1995 | 
            +
            }
         | 
| 1996 | 
            +
             | 
| 1997 | 
            +
            /* call-seq:
         | 
| 1998 | 
            +
             *   [ruby 1-9 only] <br />
         | 
| 1999 | 
            +
             *   jisx0301() -> DateTime <br />
         | 
| 2000 | 
            +
             *   jisx0301(str, sg=nil) -> DateTime
         | 
| 2001 | 
            +
             *
         | 
| 2002 | 
            +
             * If no argument is given, returns a +DateTime+ for julian day 0.
         | 
| 2003 | 
            +
             * If an argument is given, it should be a string that is
         | 
| 2004 | 
            +
             * parsed using +_jisx0301+, returning a +DateTime+ or raising
         | 
| 2005 | 
            +
             * an +ArgumentError+ if the string is not in a valid format
         | 
| 2006 | 
            +
             * or the datetime it represents is not a valid date or time.
         | 
| 2007 | 
            +
             * Ignores the 2nd argument.
         | 
| 2008 | 
            +
             * Example:
         | 
| 2009 | 
            +
             * 
         | 
| 2010 | 
            +
             *   DateTime.iso8601("H21.01.02T03:04:05+12:00")
         | 
| 2011 | 
            +
             *   # => #<DateTime 2009-01-02T03:04:05+12:00>
         | 
| 2012 | 
            +
             */
         | 
| 2013 | 
            +
            static VALUE rhrdt_s_jisx0301(int argc, VALUE *argv, VALUE klass) {
         | 
| 2014 | 
            +
              rhrdt_t *d;
         | 
| 2015 | 
            +
              VALUE rd;
         | 
| 2016 | 
            +
              rd = Data_Make_Struct(klass, rhrdt_t, NULL, free, d);
         | 
| 2017 | 
            +
             | 
| 2018 | 
            +
              switch(argc) {
         | 
| 2019 | 
            +
                case 0:
         | 
| 2020 | 
            +
                  d->flags = RHR_HAVE_JD | RHR_HAVE_HMS | RHR_HAVE_NANOS;
         | 
| 2021 | 
            +
                  return rd;
         | 
| 2022 | 
            +
                case 1:
         | 
| 2023 | 
            +
                case 2:
         | 
| 2024 | 
            +
                  rhrdt__fill_from_hash(d, rb_funcall(klass, rhrd_id__jisx0301, 1, argv[0]));
         | 
| 2025 | 
            +
                  return rd;
         | 
| 2026 | 
            +
                default:
         | 
| 2027 | 
            +
                  rb_raise(rb_eArgError, "wrong number of arguments (%i for 2)", argc);
         | 
| 2028 | 
            +
                  break;
         | 
| 2029 | 
            +
              }
         | 
| 2030 | 
            +
            }
         | 
| 2031 | 
            +
             | 
| 2032 | 
            +
            /* call-seq:
         | 
| 2033 | 
            +
             *   [ruby 1-9 only] <br />
         | 
| 2034 | 
            +
             *   rfc2822() -> DateTime <br />
         | 
| 2035 | 
            +
             *   rfc2822(str, sg=nil) -> DateTime
         | 
| 2036 | 
            +
             *
         | 
| 2037 | 
            +
             * If no argument is given, returns a +DateTime+ for julian day 0.
         | 
| 2038 | 
            +
             * If an argument is given, it should be a string that is
         | 
| 2039 | 
            +
             * parsed using +_rfc2822+, returning a +DateTime+ or raising
         | 
| 2040 | 
            +
             * an +ArgumentError+ if the string is not in a valid format
         | 
| 2041 | 
            +
             * or the datetime it represents is not a valid date or time.
         | 
| 2042 | 
            +
             * Ignores the 2nd argument.
         | 
| 2043 | 
            +
             * Example:
         | 
| 2044 | 
            +
             * 
         | 
| 2045 | 
            +
             *   DateTime.rfc2822("Fri, 2 Jan 2009 03:04:05 +1200")
         | 
| 2046 | 
            +
             *   # => #<DateTime 2009-01-02T03:04:05+12:00>
         | 
| 2047 | 
            +
             */
         | 
| 2048 | 
            +
            static VALUE rhrdt_s_rfc2822(int argc, VALUE *argv, VALUE klass) {
         | 
| 2049 | 
            +
              rhrdt_t *d;
         | 
| 2050 | 
            +
              VALUE rd;
         | 
| 2051 | 
            +
              rd = Data_Make_Struct(klass, rhrdt_t, NULL, free, d);
         | 
| 2052 | 
            +
             | 
| 2053 | 
            +
              switch(argc) {
         | 
| 2054 | 
            +
                case 0:
         | 
| 2055 | 
            +
                  d->flags = RHR_HAVE_JD | RHR_HAVE_HMS | RHR_HAVE_NANOS;
         | 
| 2056 | 
            +
                  return rd;
         | 
| 2057 | 
            +
                case 1:
         | 
| 2058 | 
            +
                case 2:
         | 
| 2059 | 
            +
                  rhrdt__fill_from_hash(d, rb_funcall(klass, rhrd_id__rfc2822, 1, argv[0]));
         | 
| 2060 | 
            +
                  return rd;
         | 
| 2061 | 
            +
                default:
         | 
| 2062 | 
            +
                  rb_raise(rb_eArgError, "wrong number of arguments (%i for 2)", argc);
         | 
| 2063 | 
            +
                  break;
         | 
| 2064 | 
            +
              }
         | 
| 2065 | 
            +
            }
         | 
| 2066 | 
            +
             | 
| 2067 | 
            +
            /* call-seq:
         | 
| 2068 | 
            +
             *   [ruby 1-9 only] <br />
         | 
| 2069 | 
            +
             *   rfc3339() -> DateTime <br />
         | 
| 2070 | 
            +
             *   rfc3339(str, sg=nil) -> DateTime
         | 
| 2071 | 
            +
             *
         | 
| 2072 | 
            +
             * If no argument is given, returns a +DateTime+ for julian day 0.
         | 
| 2073 | 
            +
             * If an argument is given, it should be a string that is
         | 
| 2074 | 
            +
             * parsed using +_rfc3339+, returning a +DateTime+ or raising
         | 
| 2075 | 
            +
             * an +ArgumentError+ if the string is not in a valid format
         | 
| 2076 | 
            +
             * or the datetime it represents is not a valid date or time.
         | 
| 2077 | 
            +
             * Ignores the 2nd argument.
         | 
| 2078 | 
            +
             * Example:
         | 
| 2079 | 
            +
             * 
         | 
| 2080 | 
            +
             *   DateTime.rfc3339("2009-01-02T03:04:05+12:00")
         | 
| 2081 | 
            +
             *   # => #<DateTime 2009-01-02T03:04:05+12:00>
         | 
| 2082 | 
            +
             */
         | 
| 2083 | 
            +
            static VALUE rhrdt_s_rfc3339(int argc, VALUE *argv, VALUE klass) {
         | 
| 2084 | 
            +
              rhrdt_t *d;
         | 
| 2085 | 
            +
              VALUE rd;
         | 
| 2086 | 
            +
              rd = Data_Make_Struct(klass, rhrdt_t, NULL, free, d);
         | 
| 2087 | 
            +
             | 
| 2088 | 
            +
              switch(argc) {
         | 
| 2089 | 
            +
                case 0:
         | 
| 2090 | 
            +
                  d->flags = RHR_HAVE_JD | RHR_HAVE_HMS | RHR_HAVE_NANOS;
         | 
| 2091 | 
            +
                  return rd;
         | 
| 2092 | 
            +
                case 1:
         | 
| 2093 | 
            +
                case 2:
         | 
| 2094 | 
            +
                  rhrdt__fill_from_hash(d, rb_funcall(klass, rhrd_id__rfc3339, 1, argv[0]));
         | 
| 2095 | 
            +
                  return rd;
         | 
| 2096 | 
            +
                default:
         | 
| 2097 | 
            +
                  rb_raise(rb_eArgError, "wrong number of arguments (%i for 2)", argc);
         | 
| 2098 | 
            +
                  break;
         | 
| 2099 | 
            +
              }
         | 
| 2100 | 
            +
            }
         | 
| 2101 | 
            +
             | 
| 2102 | 
            +
            /* call-seq:
         | 
| 2103 | 
            +
             *   [ruby 1-9 only] <br />
         | 
| 2104 | 
            +
             *   xmlschema() -> DateTime <br />
         | 
| 2105 | 
            +
             *   xmlschema(str, sg=nil) -> DateTime
         | 
| 2106 | 
            +
             *
         | 
| 2107 | 
            +
             * If no argument is given, returns a +DateTime+ for julian day 0.
         | 
| 2108 | 
            +
             * If an argument is given, it should be a string that is
         | 
| 2109 | 
            +
             * parsed using +_xmlschema+, returning a +DateTime+ or raising
         | 
| 2110 | 
            +
             * an +ArgumentError+ if the string is not in a valid format
         | 
| 2111 | 
            +
             * or the datetime it represents is not a valid date or time.
         | 
| 2112 | 
            +
             * Ignores the 2nd argument.
         | 
| 2113 | 
            +
             * Example:
         | 
| 2114 | 
            +
             * 
         | 
| 2115 | 
            +
             *   DateTime.xmlschema("2009-01-02T03:04:05+12:00")
         | 
| 2116 | 
            +
             *   # => #<DateTime 2009-01-02T03:04:05+12:00>
         | 
| 2117 | 
            +
             */
         | 
| 2118 | 
            +
            static VALUE rhrdt_s_xmlschema(int argc, VALUE *argv, VALUE klass) {
         | 
| 2119 | 
            +
              rhrdt_t *d;
         | 
| 2120 | 
            +
              VALUE rd;
         | 
| 2121 | 
            +
              rd = Data_Make_Struct(klass, rhrdt_t, NULL, free, d);
         | 
| 2122 | 
            +
             | 
| 2123 | 
            +
              switch(argc) {
         | 
| 2124 | 
            +
                case 0:
         | 
| 2125 | 
            +
                  d->flags = RHR_HAVE_JD | RHR_HAVE_HMS | RHR_HAVE_NANOS;
         | 
| 2126 | 
            +
                  return rd;
         | 
| 2127 | 
            +
                case 1:
         | 
| 2128 | 
            +
                case 2:
         | 
| 2129 | 
            +
                  rhrdt__fill_from_hash(d, rb_funcall(klass, rhrd_id__xmlschema, 1, argv[0]));
         | 
| 2130 | 
            +
                  return rd;
         | 
| 2131 | 
            +
                default:
         | 
| 2132 | 
            +
                  rb_raise(rb_eArgError, "wrong number of arguments (%i for 2)", argc);
         | 
| 2133 | 
            +
                  break;
         | 
| 2134 | 
            +
              }
         | 
| 2135 | 
            +
            }
         | 
| 2136 | 
            +
             | 
| 2137 | 
            +
            /* Ruby 1.9 instance methods */
         | 
| 2138 | 
            +
             | 
| 2139 | 
            +
            /* call-seq:
         | 
| 2140 | 
            +
             *   [ruby 1-9 only] <br />
         | 
| 2141 | 
            +
             *   httpdate() -> String
         | 
| 2142 | 
            +
             *
         | 
| 2143 | 
            +
             * Returns the receiver as a +String+ in HTTP format. Example:
         | 
| 2144 | 
            +
             * 
         | 
| 2145 | 
            +
             *   DateTime.civil(2009, 1, 2, 3, 4, 5).httpdate
         | 
| 2146 | 
            +
             *   # => "Fri, 02 Jan 2009 03:04:05 GMT"
         | 
| 2147 | 
            +
             */
         | 
| 2148 | 
            +
            static VALUE rhrdt_httpdate(VALUE self) {
         | 
| 2149 | 
            +
              VALUE s;
         | 
| 2150 | 
            +
              rhrdt_t *d;
         | 
| 2151 | 
            +
              int len;
         | 
| 2152 | 
            +
              s = rhrdt__new_offset(self, 0);
         | 
| 2153 | 
            +
              Data_Get_Struct(s, rhrdt_t, d);
         | 
| 2154 | 
            +
              RHRDT_FILL_JD(d)
         | 
| 2155 | 
            +
              RHRDT_FILL_CIVIL(d)
         | 
| 2156 | 
            +
              RHRDT_FILL_HMS(d)
         | 
| 2157 | 
            +
             | 
| 2158 | 
            +
              s = rb_str_buf_new(128);
         | 
| 2159 | 
            +
              len = snprintf(RSTRING_PTR(s), 128, "%s, %02hhi %s %04li %02hhi:%02hhi:%02hhi GMT", 
         | 
| 2160 | 
            +
                    rhrd__abbr_day_names[rhrd__jd_to_wday(d->jd)],
         | 
| 2161 | 
            +
                    d->day,
         | 
| 2162 | 
            +
                    rhrd__abbr_month_names[d->month],
         | 
| 2163 | 
            +
                    d->year, d->hour, d->minute, d->second);
         | 
| 2164 | 
            +
              if (len == -1 || len > 127) {
         | 
| 2165 | 
            +
                rb_raise(rb_eNoMemError, "in DateTime#httpdate (in snprintf)");
         | 
| 2166 | 
            +
              }
         | 
| 2167 | 
            +
             | 
| 2168 | 
            +
              RHR_RETURN_RESIZED_STR(s, len)
         | 
| 2169 | 
            +
            }
         | 
| 2170 | 
            +
             | 
| 2171 | 
            +
            /* call-seq:
         | 
| 2172 | 
            +
             *   [ruby 1-9 only] <br />
         | 
| 2173 | 
            +
             *   iso8601(n=0) -> String
         | 
| 2174 | 
            +
             *
         | 
| 2175 | 
            +
             * Returns the receiver as a +String+ in ISO8601 format.
         | 
| 2176 | 
            +
             * If an argument is given, it should be an +Integer+ representing
         | 
| 2177 | 
            +
             * the number of decimal places to use for the fractional seconds.
         | 
| 2178 | 
            +
             * Example:
         | 
| 2179 | 
            +
             * 
         | 
| 2180 | 
            +
             *   DateTime.civil(2009, 1, 2, 3, 4, 5, 0.5).iso8601
         | 
| 2181 | 
            +
             *   # => "2009-01-02T03:04:05+12:00"
         | 
| 2182 | 
            +
             *   DateTime.civil(2009, 1, 2, 3, 4, 5, 0.5).iso8601(4)
         | 
| 2183 | 
            +
             *   # => "2009-01-02T03:04:05.0000+12:00"
         | 
| 2184 | 
            +
             */
         | 
| 2185 | 
            +
            static VALUE rhrdt_iso8601(int argc, VALUE *argv, VALUE self) {
         | 
| 2186 | 
            +
              long i;
         | 
| 2187 | 
            +
              VALUE s;
         | 
| 2188 | 
            +
              rhrdt_t *dt;
         | 
| 2189 | 
            +
              char * str;
         | 
| 2190 | 
            +
              int len;
         | 
| 2191 | 
            +
              Data_Get_Struct(self, rhrdt_t, dt);
         | 
| 2192 | 
            +
              RHRDT_FILL_CIVIL(dt)
         | 
| 2193 | 
            +
             | 
| 2194 | 
            +
              switch(argc) {
         | 
| 2195 | 
            +
                case 1:
         | 
| 2196 | 
            +
                  i = NUM2LONG(argv[0]);
         | 
| 2197 | 
            +
                  break;
         | 
| 2198 | 
            +
                case 0:
         | 
| 2199 | 
            +
                  i = 0;
         | 
| 2200 | 
            +
                  break;
         | 
| 2201 | 
            +
                default:
         | 
| 2202 | 
            +
                  rb_raise(rb_eArgError, "wrong number of arguments: %i for 1", argc);
         | 
| 2203 | 
            +
                  break;
         | 
| 2204 | 
            +
              }
         | 
| 2205 | 
            +
             | 
| 2206 | 
            +
              s = rb_str_buf_new(128);
         | 
| 2207 | 
            +
              str = RSTRING_PTR(s);
         | 
| 2208 | 
            +
             | 
| 2209 | 
            +
              len = snprintf(str, 128, "%04li-%02hhi-%02hhi", dt->year, dt->month, dt->day);
         | 
| 2210 | 
            +
              if (len == -1 || len > 127) {
         | 
| 2211 | 
            +
                rb_raise(rb_eNoMemError, "in DateTime#to_s (in snprintf)");
         | 
| 2212 | 
            +
              }
         | 
| 2213 | 
            +
             | 
| 2214 | 
            +
              len = rhrdt__add_iso_time_format(dt, str, len, i);
         | 
| 2215 | 
            +
              RHR_RETURN_RESIZED_STR(s, len)
         | 
| 2216 | 
            +
            }
         | 
| 2217 | 
            +
             | 
| 2218 | 
            +
            /* call-seq:
         | 
| 2219 | 
            +
             *   [ruby 1-9 only] <br />
         | 
| 2220 | 
            +
             *   jisx0301(n=0) -> String
         | 
| 2221 | 
            +
             *
         | 
| 2222 | 
            +
             * Returns the receiver as a +String+ in JIS X 0301 format.
         | 
| 2223 | 
            +
             * If an argument is given, it should be an +Integer+ representing
         | 
| 2224 | 
            +
             * the number of decimal places to use for the fractional seconds.
         | 
| 2225 | 
            +
             * Example:
         | 
| 2226 | 
            +
             * 
         | 
| 2227 | 
            +
             *   Date.civil(2009, 1, 2, 3, 4, 5, 0.5).jisx0301
         | 
| 2228 | 
            +
             *   # => "H21.01.02T03:04:05+12:00"
         | 
| 2229 | 
            +
             *   Date.civil(2009, 1, 2, 3, 4, 5, 0.5).jisx0301(4)
         | 
| 2230 | 
            +
             *   # => "H21.01.02T03:04:05.0000+12:00"
         | 
| 2231 | 
            +
             */
         | 
| 2232 | 
            +
            static VALUE rhrdt_jisx0301(int argc, VALUE *argv, VALUE self) {
         | 
| 2233 | 
            +
              VALUE s;
         | 
| 2234 | 
            +
              rhrdt_t *d;
         | 
| 2235 | 
            +
              int len;
         | 
| 2236 | 
            +
              int i;
         | 
| 2237 | 
            +
              char c;
         | 
| 2238 | 
            +
              char * str;
         | 
| 2239 | 
            +
              long year;
         | 
| 2240 | 
            +
              Data_Get_Struct(self, rhrdt_t, d);
         | 
| 2241 | 
            +
              RHRDT_FILL_CIVIL(d)
         | 
| 2242 | 
            +
              RHRDT_FILL_JD(d)
         | 
| 2243 | 
            +
             | 
| 2244 | 
            +
              switch(argc) {
         | 
| 2245 | 
            +
                case 1:
         | 
| 2246 | 
            +
                  i = NUM2LONG(argv[0]);
         | 
| 2247 | 
            +
                  break;
         | 
| 2248 | 
            +
                case 0:
         | 
| 2249 | 
            +
                  i = 0;
         | 
| 2250 | 
            +
                  break;
         | 
| 2251 | 
            +
                default:
         | 
| 2252 | 
            +
                  rb_raise(rb_eArgError, "wrong number of arguments: %i for 1", argc);
         | 
| 2253 | 
            +
                  break;
         | 
| 2254 | 
            +
              }
         | 
| 2255 | 
            +
             | 
| 2256 | 
            +
              s = rb_str_buf_new(128);
         | 
| 2257 | 
            +
              str = RSTRING_PTR(s); 
         | 
| 2258 | 
            +
             | 
| 2259 | 
            +
              if (d->jd < 2405160) {
         | 
| 2260 | 
            +
                len = snprintf(str, 128, "%04li-%02hhi-%02hhi", d->year, d->month, d->day);
         | 
| 2261 | 
            +
              } else {
         | 
| 2262 | 
            +
                if (d->jd >= 2447535) {
         | 
| 2263 | 
            +
                  c = 'H';
         | 
| 2264 | 
            +
                  year = d->year - 1988;
         | 
| 2265 | 
            +
                } else if (d->jd >= 2424875) {
         | 
| 2266 | 
            +
                  c = 'S';
         | 
| 2267 | 
            +
                  year = d->year - 1925;
         | 
| 2268 | 
            +
                } else if (d->jd >= 2419614) {
         | 
| 2269 | 
            +
                  c = 'T';
         | 
| 2270 | 
            +
                  year = d->year - 1911;
         | 
| 2271 | 
            +
                } else {
         | 
| 2272 | 
            +
                  c = 'M';
         | 
| 2273 | 
            +
                  year = d->year - 1867;
         | 
| 2274 | 
            +
                }
         | 
| 2275 | 
            +
                len = snprintf(RSTRING_PTR(s), 128, "%c%02li.%02hhi.%02hhi", c, year, d->month, d->day);
         | 
| 2276 | 
            +
              }
         | 
| 2277 | 
            +
              if (len == -1 || len > 127) {
         | 
| 2278 | 
            +
                rb_raise(rb_eNoMemError, "in DateTime#jisx0301 (in snprintf)");
         | 
| 2279 | 
            +
              }
         | 
| 2280 | 
            +
             | 
| 2281 | 
            +
              len = rhrdt__add_iso_time_format(d, str, len, i);
         | 
| 2282 | 
            +
              RHR_RETURN_RESIZED_STR(s, len)
         | 
| 2283 | 
            +
            }
         | 
| 2284 | 
            +
             | 
| 2285 | 
            +
            /* call-seq:
         | 
| 2286 | 
            +
             *   [ruby 1-9 only] <br />
         | 
| 2287 | 
            +
             *   next_day(n=1) -> DateTime
         | 
| 2288 | 
            +
             *
         | 
| 2289 | 
            +
             * Returns a +DateTime+ +n+ days after the receiver.  If +n+ is negative,
         | 
| 2290 | 
            +
             * returns a +DateTime+ before the receiver.
         | 
| 2291 | 
            +
             * The new +DateTime+ is returned with the same fractional part and offset as the receiver.
         | 
| 2292 | 
            +
             * 
         | 
| 2293 | 
            +
             *   DateTime.civil(2009, 1, 2, 12).next_day
         | 
| 2294 | 
            +
             *   # => #<DateTime 2009-01-03T12:00:00+00:00>
         | 
| 2295 | 
            +
             *   DateTime.civil(2009, 1, 2, 12).next_day(2)
         | 
| 2296 | 
            +
             *   # => #<DateTime 2009-01-04T12:00:00+00:00>
         | 
| 2297 | 
            +
             */
         | 
| 2298 | 
            +
            static VALUE rhrdt_next_day(int argc, VALUE *argv, VALUE self) {
         | 
| 2299 | 
            +
              long i;
         | 
| 2300 | 
            +
             | 
| 2301 | 
            +
              switch(argc) {
         | 
| 2302 | 
            +
                case 0:
         | 
| 2303 | 
            +
                  i = 1;
         | 
| 2304 | 
            +
                  break;
         | 
| 2305 | 
            +
                case 1:
         | 
| 2306 | 
            +
                  i = NUM2LONG(argv[0]);
         | 
| 2307 | 
            +
                  break;
         | 
| 2308 | 
            +
                default:
         | 
| 2309 | 
            +
                  rb_raise(rb_eArgError, "wrong number of arguments: %i for 1", argc);
         | 
| 2310 | 
            +
                  break;
         | 
| 2311 | 
            +
              }
         | 
| 2312 | 
            +
             | 
| 2313 | 
            +
               return rhrdt__add_days(self, i);
         | 
| 2314 | 
            +
            }
         | 
| 2315 | 
            +
             | 
| 2316 | 
            +
            /* call-seq:
         | 
| 2317 | 
            +
             *   [ruby 1-9 only] <br />
         | 
| 2318 | 
            +
             *   next_month(n=1) -> DateTime
         | 
| 2319 | 
            +
             *
         | 
| 2320 | 
            +
             * Returns a +DateTime+ +n+ months after the receiver.  If +n+ is negative,
         | 
| 2321 | 
            +
             * returns a +DateTime+ before the receiver.
         | 
| 2322 | 
            +
             * The new +DateTime+ is returned with the same fractional part and offset as the receiver.
         | 
| 2323 | 
            +
             * 
         | 
| 2324 | 
            +
             *   DateTime.civil(2009, 1, 2, 12).next_month
         | 
| 2325 | 
            +
             *   # => #<DateTime 2009-02-02T12:00:00+00:00>
         | 
| 2326 | 
            +
             *   DateTime.civil(2009, 1, 2, 12).next_month(2)
         | 
| 2327 | 
            +
             *   # => #<DateTime 2009-03-02T12:00:00+00:00>
         | 
| 2328 | 
            +
             */
         | 
| 2329 | 
            +
            static VALUE rhrdt_next_month(int argc, VALUE *argv, VALUE self) {
         | 
| 2330 | 
            +
              long i;
         | 
| 2331 | 
            +
             | 
| 2332 | 
            +
              switch(argc) {
         | 
| 2333 | 
            +
                case 0:
         | 
| 2334 | 
            +
                  i = 1;
         | 
| 2335 | 
            +
                  break;
         | 
| 2336 | 
            +
                case 1:
         | 
| 2337 | 
            +
                  i = NUM2LONG(argv[0]);
         | 
| 2338 | 
            +
                  break;
         | 
| 2339 | 
            +
                default:
         | 
| 2340 | 
            +
                  rb_raise(rb_eArgError, "wrong number of arguments: %i for 1", argc);
         | 
| 2341 | 
            +
                  break;
         | 
| 2342 | 
            +
              }
         | 
| 2343 | 
            +
             | 
| 2344 | 
            +
              return rhrdt__add_months(self, i);
         | 
| 2345 | 
            +
            }
         | 
| 2346 | 
            +
             | 
| 2347 | 
            +
            /* call-seq:
         | 
| 2348 | 
            +
             *   [ruby 1-9 only] <br />
         | 
| 2349 | 
            +
             *   next_year(n=1) -> DateTime
         | 
| 2350 | 
            +
             *
         | 
| 2351 | 
            +
             * Returns a +DateTime+ +n+ years after the receiver.  If +n+ is negative,
         | 
| 2352 | 
            +
             * returns a +DateTime+ before the receiver.
         | 
| 2353 | 
            +
             * The new +DateTime+ is returned with the same fractional part and offset as the receiver.
         | 
| 2354 | 
            +
             * 
         | 
| 2355 | 
            +
             *   DateTime.civil(2009, 1, 2, 12).next_year
         | 
| 2356 | 
            +
             *   # => #<DateTime 2010-01-02T12:00:00+00:00>
         | 
| 2357 | 
            +
             *   DateTime.civil(2009, 1, 2, 12).next_year(2)
         | 
| 2358 | 
            +
             *   # => #<DateTime 2011-01-02T12:00:00+00:00>
         | 
| 2359 | 
            +
             */
         | 
| 2360 | 
            +
            static VALUE rhrdt_next_year(int argc, VALUE *argv, VALUE self) {
         | 
| 2361 | 
            +
              long i;
         | 
| 2362 | 
            +
             | 
| 2363 | 
            +
              switch(argc) {
         | 
| 2364 | 
            +
                case 0:
         | 
| 2365 | 
            +
                  i = 1;
         | 
| 2366 | 
            +
                  break;
         | 
| 2367 | 
            +
                case 1:
         | 
| 2368 | 
            +
                  i = NUM2LONG(argv[0]);
         | 
| 2369 | 
            +
                  break;
         | 
| 2370 | 
            +
                default:
         | 
| 2371 | 
            +
                  rb_raise(rb_eArgError, "wrong number of arguments: %i for 1", argc);
         | 
| 2372 | 
            +
                  break;
         | 
| 2373 | 
            +
              }
         | 
| 2374 | 
            +
             | 
| 2375 | 
            +
              return rhrdt__add_years(self, i);
         | 
| 2376 | 
            +
            }
         | 
| 2377 | 
            +
             | 
| 2378 | 
            +
            /* call-seq:
         | 
| 2379 | 
            +
             *   [ruby 1-9 only] <br />
         | 
| 2380 | 
            +
             *   prev_day(n=1) -> DateTime
         | 
| 2381 | 
            +
             *
         | 
| 2382 | 
            +
             * Returns a +DateTime+ +n+ days before the receiver.  If +n+ is negative,
         | 
| 2383 | 
            +
             * returns a +DateTime+ after the receiver.
         | 
| 2384 | 
            +
             * The new +DateTime+ is returned with the same fractional part and offset as the receiver.
         | 
| 2385 | 
            +
             * 
         | 
| 2386 | 
            +
             *   DateTime.civil(2009, 1, 2, 12).prev_day
         | 
| 2387 | 
            +
             *   # => #<DateTime 2009-01-01T12:00:00+00:00>
         | 
| 2388 | 
            +
             *   DateTime.civil(2009, 1, 2, 12).prev_day(2)
         | 
| 2389 | 
            +
             *   # => #<DateTime 2008-12-31T12:00:00+00:00>
         | 
| 2390 | 
            +
             */
         | 
| 2391 | 
            +
            static VALUE rhrdt_prev_day(int argc, VALUE *argv, VALUE self) {
         | 
| 2392 | 
            +
              long i;
         | 
| 2393 | 
            +
             | 
| 2394 | 
            +
              switch(argc) {
         | 
| 2395 | 
            +
                case 0:
         | 
| 2396 | 
            +
                  i = -1;
         | 
| 2397 | 
            +
                  break;
         | 
| 2398 | 
            +
                case 1:
         | 
| 2399 | 
            +
                  i = -NUM2LONG(argv[0]);
         | 
| 2400 | 
            +
                  break;
         | 
| 2401 | 
            +
                default:
         | 
| 2402 | 
            +
                  rb_raise(rb_eArgError, "wrong number of arguments: %i for 1", argc);
         | 
| 2403 | 
            +
                  break;
         | 
| 2404 | 
            +
              }
         | 
| 2405 | 
            +
             | 
| 2406 | 
            +
               return rhrdt__add_days(self, i);
         | 
| 2407 | 
            +
            }
         | 
| 2408 | 
            +
             | 
| 2409 | 
            +
            /* call-seq:
         | 
| 2410 | 
            +
             *   [ruby 1-9 only] <br />
         | 
| 2411 | 
            +
             *   prev_month(n=1) -> DateTime
         | 
| 2412 | 
            +
             *
         | 
| 2413 | 
            +
             * Returns a +DateTime+ +n+ months before the receiver.  If +n+ is negative,
         | 
| 2414 | 
            +
             * returns a +DateTime+ after the receiver.
         | 
| 2415 | 
            +
             * The new +DateTime+ is returned with the same fractional part and offset as the receiver.
         | 
| 2416 | 
            +
             * 
         | 
| 2417 | 
            +
             *   DateTime.civil(2009, 1, 2, 12).prev_month
         | 
| 2418 | 
            +
             *   # => #<DateTime 2008-12-02T12:00:00+00:00>
         | 
| 2419 | 
            +
             *   DateTime.civil(2009, 1, 2, 12).prev_month(2)
         | 
| 2420 | 
            +
             *   # => #<DateTime 2008-11-02T12:00:00+00:00>
         | 
| 2421 | 
            +
             */
         | 
| 2422 | 
            +
            static VALUE rhrdt_prev_month(int argc, VALUE *argv, VALUE self) {
         | 
| 2423 | 
            +
              long i;
         | 
| 2424 | 
            +
             | 
| 2425 | 
            +
              switch(argc) {
         | 
| 2426 | 
            +
                case 0:
         | 
| 2427 | 
            +
                  i = -1;
         | 
| 2428 | 
            +
                  break;
         | 
| 2429 | 
            +
                case 1:
         | 
| 2430 | 
            +
                  i = -NUM2LONG(argv[0]);
         | 
| 2431 | 
            +
                  break;
         | 
| 2432 | 
            +
                default:
         | 
| 2433 | 
            +
                  rb_raise(rb_eArgError, "wrong number of arguments: %i for 1", argc);
         | 
| 2434 | 
            +
                  break;
         | 
| 2435 | 
            +
              }
         | 
| 2436 | 
            +
             | 
| 2437 | 
            +
              return rhrdt__add_months(self, i);
         | 
| 2438 | 
            +
            }
         | 
| 2439 | 
            +
             | 
| 2440 | 
            +
            /* call-seq:
         | 
| 2441 | 
            +
             *   [ruby 1-9 only] <br />
         | 
| 2442 | 
            +
             *   prev_year(n=1) -> DateTime
         | 
| 2443 | 
            +
             *
         | 
| 2444 | 
            +
             * Returns a +DateTime+ +n+ years before the receiver.  If +n+ is negative,
         | 
| 2445 | 
            +
             * returns a +DateTime+ after the receiver.
         | 
| 2446 | 
            +
             * The new +DateTime+ is returned with the same fractional part and offset as the receiver.
         | 
| 2447 | 
            +
             * 
         | 
| 2448 | 
            +
             *   DateTime.civil(2009, 1, 2, 12).prev_year
         | 
| 2449 | 
            +
             *   # => #<DateTime 2008-01-02T12:00:00+00:00>
         | 
| 2450 | 
            +
             *   DateTime.civil(2009, 1, 2, 12).prev_year(2)
         | 
| 2451 | 
            +
             *   # => #<DateTime 2007-01-02T12:00:00+00:00>
         | 
| 2452 | 
            +
             */
         | 
| 2453 | 
            +
            static VALUE rhrdt_prev_year(int argc, VALUE *argv, VALUE self) {
         | 
| 2454 | 
            +
              long i;
         | 
| 2455 | 
            +
             | 
| 2456 | 
            +
              switch(argc) {
         | 
| 2457 | 
            +
                case 0:
         | 
| 2458 | 
            +
                  i = -1;
         | 
| 2459 | 
            +
                  break;
         | 
| 2460 | 
            +
                case 1:
         | 
| 2461 | 
            +
                  i = -NUM2LONG(argv[0]);
         | 
| 2462 | 
            +
                  break;
         | 
| 2463 | 
            +
                default:
         | 
| 2464 | 
            +
                  rb_raise(rb_eArgError, "wrong number of arguments: %i for 1", argc);
         | 
| 2465 | 
            +
                  break;
         | 
| 2466 | 
            +
              }
         | 
| 2467 | 
            +
             | 
| 2468 | 
            +
              return rhrdt__add_years(self, i);
         | 
| 2469 | 
            +
            }
         | 
| 2470 | 
            +
             | 
| 2471 | 
            +
            /* call-seq:
         | 
| 2472 | 
            +
             *   [ruby 1-9 only] <br />
         | 
| 2473 | 
            +
             *   rfc2822() -> String
         | 
| 2474 | 
            +
             *
         | 
| 2475 | 
            +
             * Returns the receiver as a +String+ in RFC2822 format. Example:
         | 
| 2476 | 
            +
             * 
         | 
| 2477 | 
            +
             *   DateTime.civil(2009, 1, 2, 3, 4, 5, 0.5).rfc2822
         | 
| 2478 | 
            +
             *   # => "Fri, 2 Jan 2009 03:04:05 +1200"
         | 
| 2479 | 
            +
             */
         | 
| 2480 | 
            +
            static VALUE rhrdt_rfc2822(VALUE self) {
         | 
| 2481 | 
            +
              VALUE s;
         | 
| 2482 | 
            +
              rhrdt_t *d;
         | 
| 2483 | 
            +
              int len;
         | 
| 2484 | 
            +
              Data_Get_Struct(self, rhrdt_t, d);
         | 
| 2485 | 
            +
              RHRDT_FILL_CIVIL(d)
         | 
| 2486 | 
            +
              RHRDT_FILL_JD(d)
         | 
| 2487 | 
            +
              RHRDT_FILL_HMS(d)
         | 
| 2488 | 
            +
             | 
| 2489 | 
            +
              s = rb_str_buf_new(128);
         | 
| 2490 | 
            +
              len = snprintf(RSTRING_PTR(s), 128, "%s, %hhi %s %04li %02hhi:%02hhi:%02hhi %+03i%02i", 
         | 
| 2491 | 
            +
                    rhrd__abbr_day_names[rhrd__jd_to_wday(d->jd)],
         | 
| 2492 | 
            +
                    d->day,
         | 
| 2493 | 
            +
                    rhrd__abbr_month_names[d->month],
         | 
| 2494 | 
            +
                    d->year, d->hour, d->minute, d->second, d->offset/60, abs(d->offset % 60));
         | 
| 2495 | 
            +
              if (len == -1 || len > 127) {
         | 
| 2496 | 
            +
                rb_raise(rb_eNoMemError, "in DateTime#rfc2822 (in snprintf)");
         | 
| 2497 | 
            +
              }
         | 
| 2498 | 
            +
             | 
| 2499 | 
            +
              RHR_RETURN_RESIZED_STR(s, len)
         | 
| 2500 | 
            +
            }
         | 
| 2501 | 
            +
             | 
| 2502 | 
            +
            /* call-seq:
         | 
| 2503 | 
            +
             *   [ruby 1-9 only] <br />
         | 
| 2504 | 
            +
             *   to_date() -> Date
         | 
| 2505 | 
            +
             *
         | 
| 2506 | 
            +
             * Returns a +Date+ with the same date as the receiver, ignoring
         | 
| 2507 | 
            +
             * any fractional parts or offsets.
         | 
| 2508 | 
            +
             * 
         | 
| 2509 | 
            +
             *   DateTime.civil(2009, 1, 2, 12).to_date
         | 
| 2510 | 
            +
             *   # => #<Date 2009-01-02>
         | 
| 2511 | 
            +
             */
         | 
| 2512 | 
            +
            static VALUE rhrdt_to_date(VALUE self) {
         | 
| 2513 | 
            +
              rhrd_t *d;
         | 
| 2514 | 
            +
              rhrdt_t *dt;
         | 
| 2515 | 
            +
              VALUE rd = Data_Make_Struct(rhrd_class, rhrd_t, NULL, free, d);
         | 
| 2516 | 
            +
              Data_Get_Struct(self, rhrdt_t, dt);
         | 
| 2517 | 
            +
             | 
| 2518 | 
            +
              if (RHR_HAS_CIVIL(dt)) {
         | 
| 2519 | 
            +
                d->year = dt->year;
         | 
| 2520 | 
            +
                d->month = dt->month;
         | 
| 2521 | 
            +
                d->day = dt->day;
         | 
| 2522 | 
            +
                d->flags |= RHR_HAVE_CIVIL;
         | 
| 2523 | 
            +
              }
         | 
| 2524 | 
            +
              if (RHR_HAS_JD(dt)) {
         | 
| 2525 | 
            +
                d->jd = dt->jd;
         | 
| 2526 | 
            +
                d->flags |= RHR_HAVE_JD;
         | 
| 2527 | 
            +
              }
         | 
| 2528 | 
            +
             | 
| 2529 | 
            +
              return rd;
         | 
| 2530 | 
            +
            }
         | 
| 2531 | 
            +
             | 
| 2532 | 
            +
            /* call-seq:
         | 
| 2533 | 
            +
             *   [ruby 1-9 only] <br />
         | 
| 2534 | 
            +
             *   to_time() -> Time
         | 
| 2535 | 
            +
             *
         | 
| 2536 | 
            +
             * Returns a +Time+ in local time with the same year, month, day,
         | 
| 2537 | 
            +
             * hour, minute, and second as the receiver (in absoute time).
         | 
| 2538 | 
            +
             * 
         | 
| 2539 | 
            +
             *   DateTime.civil(2009, 1, 2, 5).to_time
         | 
| 2540 | 
            +
             *   # => 2009-01-01 21:00:00 -0800
         | 
| 2541 | 
            +
             */
         | 
| 2542 | 
            +
            static VALUE rhrdt_to_time(VALUE self) {
         | 
| 2543 | 
            +
              long h, m, s;
         | 
| 2544 | 
            +
              rhrdt_t *dt;
         | 
| 2545 | 
            +
              Data_Get_Struct(self, rhrdt_t, dt);
         | 
| 2546 | 
            +
              RHRDT_FILL_JD(dt)
         | 
| 2547 | 
            +
              RHRDT_FILL_NANOS(dt)
         | 
| 2548 | 
            +
              self = rhrdt__from_jd_nanos(dt->jd, dt->nanos - dt->offset * RHR_NANOS_PER_MINUTE, 0);
         | 
| 2549 | 
            +
              Data_Get_Struct(self, rhrdt_t, dt);
         | 
| 2550 | 
            +
              RHRDT_FILL_CIVIL(dt)
         | 
| 2551 | 
            +
              RHRDT_FILL_HMS(dt)
         | 
| 2552 | 
            +
             | 
| 2553 | 
            +
              s = dt->nanos/RHR_NANOS_PER_SECOND;
         | 
| 2554 | 
            +
              h = s/RHR_SECONDS_PER_HOUR;
         | 
| 2555 | 
            +
              m = (s % RHR_SECONDS_PER_HOUR) / 60;
         | 
| 2556 | 
            +
              return rb_funcall(rb_funcall(rb_cTime, rhrd_id_utc, 6, LONG2NUM(dt->year), LONG2NUM(dt->month), LONG2NUM(dt->day), LONG2NUM(h), LONG2NUM(m), rb_float_new(s % 60 + (dt->nanos % RHR_NANOS_PER_SECOND)/RHR_NANOS_PER_SECONDD)), rhrd_id_localtime, 0);
         | 
| 2557 | 
            +
            }
         | 
| 2558 | 
            +
             | 
| 2559 | 
            +
            /* call-seq:
         | 
| 2560 | 
            +
             *   [ruby 1-9 only] <br />
         | 
| 2561 | 
            +
             *   to_datetime() -> DateTime
         | 
| 2562 | 
            +
             *
         | 
| 2563 | 
            +
             * Returns a +DateTime+ with the same year, month, day,
         | 
| 2564 | 
            +
             * hour, minute, and second as the receiver in local time.
         | 
| 2565 | 
            +
             * 
         | 
| 2566 | 
            +
             *   Time.local(2009, 1, 2, 12).to_datetime
         | 
| 2567 | 
            +
             *   # => #<DateTime 2009-01-02T12:00:00-08:00>
         | 
| 2568 | 
            +
             */
         | 
| 2569 | 
            +
            static VALUE rhrdt_time_to_datetime(VALUE self) {
         | 
| 2570 | 
            +
              rhrdt_t *dt;
         | 
| 2571 | 
            +
              VALUE rd;
         | 
| 2572 | 
            +
              long t, offset;
         | 
| 2573 | 
            +
              rd = Data_Make_Struct(rhrdt_class, rhrdt_t, NULL, free, dt);
         | 
| 2574 | 
            +
             | 
| 2575 | 
            +
              offset = NUM2LONG(rb_funcall(self, rhrd_id_utc_offset, 0));
         | 
| 2576 | 
            +
              t = NUM2LONG(rb_funcall(self, rhrd_id_to_i, 0)) + offset;
         | 
| 2577 | 
            +
              dt->jd = rhrd__unix_to_jd(t);
         | 
| 2578 | 
            +
            #ifdef RUBY19
         | 
| 2579 | 
            +
              dt->nanos = rhrd__mod(t, RHR_SECONDS_PER_DAY) * RHR_NANOS_PER_SECOND + NUM2LONG(rb_funcall(self, rhrd_id_nsec, 0));
         | 
| 2580 | 
            +
            #else
         | 
| 2581 | 
            +
              dt->nanos = rhrd__mod(t, RHR_SECONDS_PER_DAY) * RHR_NANOS_PER_SECOND + NUM2LONG(rb_funcall(self, rhrd_id_usec, 0)) * 1000;
         | 
| 2582 | 
            +
            #endif
         | 
| 2583 | 
            +
              dt->offset = offset/60;
         | 
| 2584 | 
            +
              dt->flags |= RHR_HAVE_JD | RHR_HAVE_NANOS;
         | 
| 2585 | 
            +
              RHR_CHECK_JD(dt);
         | 
| 2586 | 
            +
              return rd;
         | 
| 2587 | 
            +
            }
         | 
| 2588 | 
            +
             | 
| 2589 | 
            +
            /* 1.9 day? instance methods */
         | 
| 2590 | 
            +
             | 
| 2591 | 
            +
            /* call-seq:
         | 
| 2592 | 
            +
             *   [ruby 1-9 only] <br />
         | 
| 2593 | 
            +
             *   sunday?() -> true or false
         | 
| 2594 | 
            +
             *
         | 
| 2595 | 
            +
             * Returns +true+ if the receiver is a Sunday, +false+ otherwise.
         | 
| 2596 | 
            +
             */
         | 
| 2597 | 
            +
            static VALUE rhrdt_sunday_q(VALUE self) {
         | 
| 2598 | 
            +
              return rhrdt__day_q(self, 0);
         | 
| 2599 | 
            +
            }
         | 
| 2600 | 
            +
             | 
| 2601 | 
            +
            /* call-seq:
         | 
| 2602 | 
            +
             *   [ruby 1-9 only] <br />
         | 
| 2603 | 
            +
             *   monday?() -> true or false
         | 
| 2604 | 
            +
             *
         | 
| 2605 | 
            +
             * Returns +true+ if the receiver is a Monday, +false+ otherwise.
         | 
| 2606 | 
            +
             */
         | 
| 2607 | 
            +
            static VALUE rhrdt_monday_q(VALUE self) {
         | 
| 2608 | 
            +
              return rhrdt__day_q(self, 1);
         | 
| 2609 | 
            +
            }
         | 
| 2610 | 
            +
             | 
| 2611 | 
            +
            /* call-seq:
         | 
| 2612 | 
            +
             *   [ruby 1-9 only] <br />
         | 
| 2613 | 
            +
             *   tuesday?() -> true or false
         | 
| 2614 | 
            +
             *
         | 
| 2615 | 
            +
             * Returns +true+ if the receiver is a Tuesday, +false+ otherwise.
         | 
| 2616 | 
            +
             */
         | 
| 2617 | 
            +
            static VALUE rhrdt_tuesday_q(VALUE self) {
         | 
| 2618 | 
            +
              return rhrdt__day_q(self, 2);
         | 
| 2619 | 
            +
            }
         | 
| 2620 | 
            +
             | 
| 2621 | 
            +
            /* call-seq:
         | 
| 2622 | 
            +
             *   [ruby 1-9 only] <br />
         | 
| 2623 | 
            +
             *   wednesday?() -> true or false
         | 
| 2624 | 
            +
             *
         | 
| 2625 | 
            +
             * Returns +true+ if the receiver is a Wednesday, +false+ otherwise.
         | 
| 2626 | 
            +
             */
         | 
| 2627 | 
            +
            static VALUE rhrdt_wednesday_q(VALUE self) {
         | 
| 2628 | 
            +
              return rhrdt__day_q(self, 3);
         | 
| 2629 | 
            +
            }
         | 
| 2630 | 
            +
             | 
| 2631 | 
            +
            /* call-seq:
         | 
| 2632 | 
            +
             *   [ruby 1-9 only] <br />
         | 
| 2633 | 
            +
             *   thursday?() -> true or false
         | 
| 2634 | 
            +
             *
         | 
| 2635 | 
            +
             * Returns +true+ if the receiver is a Thursday, +false+ otherwise.
         | 
| 2636 | 
            +
             */
         | 
| 2637 | 
            +
            static VALUE rhrdt_thursday_q(VALUE self) {
         | 
| 2638 | 
            +
              return rhrdt__day_q(self, 4);
         | 
| 2639 | 
            +
            }
         | 
| 2640 | 
            +
             | 
| 2641 | 
            +
            /* call-seq:
         | 
| 2642 | 
            +
             *   [ruby 1-9 only] <br />
         | 
| 2643 | 
            +
             *   friday?() -> true or false
         | 
| 2644 | 
            +
             *
         | 
| 2645 | 
            +
             * Returns +true+ if the receiver is a Friday, +false+ otherwise.
         | 
| 2646 | 
            +
             */
         | 
| 2647 | 
            +
            static VALUE rhrdt_friday_q(VALUE self) {
         | 
| 2648 | 
            +
              return rhrdt__day_q(self, 5);
         | 
| 2649 | 
            +
            }
         | 
| 2650 | 
            +
             | 
| 2651 | 
            +
            /* call-seq:
         | 
| 2652 | 
            +
             *   [ruby 1-9 only] <br />
         | 
| 2653 | 
            +
             *   saturday?() -> true or false
         | 
| 2654 | 
            +
             *
         | 
| 2655 | 
            +
             * Returns +true+ if the receiver is a Saturday, +false+ otherwise.
         | 
| 2656 | 
            +
             */
         | 
| 2657 | 
            +
            static VALUE rhrdt_saturday_q(VALUE self) {
         | 
| 2658 | 
            +
              return rhrdt__day_q(self, 6);
         | 
| 2659 | 
            +
            }
         | 
| 2660 | 
            +
             | 
| 2661 | 
            +
            #endif
         | 
| 2662 | 
            +
             | 
| 2663 | 
            +
            /* Library initialization */
         | 
| 2664 | 
            +
             | 
| 2665 | 
            +
            /* +DateTime+ is used to store a single point in time.  It consists of
         | 
| 2666 | 
            +
             * three main parts:
         | 
| 2667 | 
            +
             * 
         | 
| 2668 | 
            +
             * * A single date in the gregorian calendar (similar to +Date+)
         | 
| 2669 | 
            +
             * * A time component (hour, minute, second, fractional second)
         | 
| 2670 | 
            +
             * * A time zone offset in minutes from UTC
         | 
| 2671 | 
            +
             *
         | 
| 2672 | 
            +
             * In general, +DateTime+ objects are created by calling one of the class
         | 
| 2673 | 
            +
             * methods: +civil+, +parse+, +strptime+, +now+.  Once created,
         | 
| 2674 | 
            +
             * +DateTime+ objects are immutable.  Operations that result in a separate
         | 
| 2675 | 
            +
             * datetime (such as adding a number of days), always return a new +DateTime+
         | 
| 2676 | 
            +
             * object.
         | 
| 2677 | 
            +
             * */
         | 
| 2678 | 
            +
            void Init_datetime(void) {
         | 
| 2679 | 
            +
             | 
| 2680 | 
            +
              /* Define class */
         | 
| 2681 | 
            +
             | 
| 2682 | 
            +
              rhrdt_class = rb_define_class("DateTime", rhrd_class);
         | 
| 2683 | 
            +
              rb_undef_alloc_func(rhrdt_class);
         | 
| 2684 | 
            +
              rhrdt_s_class = rb_singleton_class(rhrdt_class);
         | 
| 2685 | 
            +
             | 
| 2686 | 
            +
              /* Define methods for all ruby versions*/
         | 
| 2687 | 
            +
             | 
| 2688 | 
            +
              rb_undef(rhrdt_s_class, rb_intern("today"));
         | 
| 2689 | 
            +
              rb_define_method(rhrdt_s_class, "_load", rhrdt_s__load, 1);
         | 
| 2690 | 
            +
              rb_define_method(rhrdt_s_class, "_strptime", rhrdt_s__strptime, -1);
         | 
| 2691 | 
            +
              rb_define_method(rhrdt_s_class, "civil", rhrdt_s_civil, -1);
         | 
| 2692 | 
            +
              rb_define_method(rhrdt_s_class, "commercial", rhrdt_s_commercial, -1);
         | 
| 2693 | 
            +
              rb_define_method(rhrdt_s_class, "jd", rhrdt_s_jd, -1);
         | 
| 2694 | 
            +
              rb_define_method(rhrdt_s_class, "new!", rhrdt_s_new_b, -1);
         | 
| 2695 | 
            +
              rb_define_method(rhrdt_s_class, "now", rhrdt_s_now, -1);
         | 
| 2696 | 
            +
              rb_define_method(rhrdt_s_class, "ordinal", rhrdt_s_ordinal, -1);
         | 
| 2697 | 
            +
              rb_define_method(rhrdt_s_class, "parse", rhrdt_s_parse, -1);
         | 
| 2698 | 
            +
              rb_define_method(rhrdt_s_class, "strptime", rhrdt_s_strptime, -1);
         | 
| 2699 | 
            +
             | 
| 2700 | 
            +
              rb_define_alias(rhrdt_s_class, "new", "civil");
         | 
| 2701 | 
            +
             | 
| 2702 | 
            +
              rb_define_method(rhrdt_class, "_dump", rhrdt__dump, 1);
         | 
| 2703 | 
            +
              rb_define_method(rhrdt_class, "ajd", rhrdt_ajd, 0);
         | 
| 2704 | 
            +
              rb_define_method(rhrdt_class, "amjd", rhrdt_amjd, 0);
         | 
| 2705 | 
            +
              rb_define_method(rhrdt_class, "asctime", rhrdt_asctime, 0);
         | 
| 2706 | 
            +
              rb_define_method(rhrdt_class, "cwday", rhrdt_cwday, 0);
         | 
| 2707 | 
            +
              rb_define_method(rhrdt_class, "cweek", rhrdt_cweek, 0);
         | 
| 2708 | 
            +
              rb_define_method(rhrdt_class, "cwyear", rhrdt_cwyear, 0);
         | 
| 2709 | 
            +
              rb_define_method(rhrdt_class, "day", rhrdt_day, 0);
         | 
| 2710 | 
            +
              rb_define_method(rhrdt_class, "day_fraction", rhrdt_day_fraction, 0);
         | 
| 2711 | 
            +
              rb_define_method(rhrdt_class, "downto", rhrdt_downto, 1);
         | 
| 2712 | 
            +
              rb_define_method(rhrdt_class, "eql?", rhrdt_eql_q, 1);
         | 
| 2713 | 
            +
              rb_define_method(rhrdt_class, "hash", rhrdt_hash, 0);
         | 
| 2714 | 
            +
              rb_define_method(rhrdt_class, "hour", rhrdt_hour, 0);
         | 
| 2715 | 
            +
              rb_define_method(rhrdt_class, "inspect", rhrdt_inspect, 0);
         | 
| 2716 | 
            +
              rb_define_method(rhrdt_class, "jd", rhrdt_jd, 0);
         | 
| 2717 | 
            +
              rb_define_method(rhrdt_class, "ld", rhrdt_ld, 0);
         | 
| 2718 | 
            +
              rb_define_method(rhrdt_class, "leap?", rhrdt_leap_q, 0);
         | 
| 2719 | 
            +
              rb_define_method(rhrdt_class, "min", rhrdt_min, 0);
         | 
| 2720 | 
            +
              rb_define_method(rhrdt_class, "mjd", rhrdt_mjd, 0);
         | 
| 2721 | 
            +
              rb_define_method(rhrdt_class, "month", rhrdt_month, 0);
         | 
| 2722 | 
            +
              rb_define_method(rhrdt_class, "new_offset", rhrdt_new_offset, -1);
         | 
| 2723 | 
            +
              rb_define_method(rhrdt_class, "next", rhrdt_next, 0);
         | 
| 2724 | 
            +
              rb_define_method(rhrdt_class, "offset", rhrdt_offset, 0);
         | 
| 2725 | 
            +
              rb_define_method(rhrdt_class, "sec", rhrdt_sec, 0);
         | 
| 2726 | 
            +
              rb_define_method(rhrdt_class, "sec_fraction", rhrdt_sec_fraction, 0);
         | 
| 2727 | 
            +
              rb_define_method(rhrdt_class, "step", rhrdt_step, -1);
         | 
| 2728 | 
            +
              rb_define_method(rhrdt_class, "strftime", rhrdt_strftime, -1);
         | 
| 2729 | 
            +
              rb_define_method(rhrdt_class, "to_s", rhrdt_to_s, 0);
         | 
| 2730 | 
            +
              rb_define_method(rhrdt_class, "upto", rhrdt_upto, 1);
         | 
| 2731 | 
            +
              rb_define_method(rhrdt_class, "wday", rhrdt_wday, 0);
         | 
| 2732 | 
            +
              rb_define_method(rhrdt_class, "yday", rhrdt_yday, 0);
         | 
| 2733 | 
            +
              rb_define_method(rhrdt_class, "year", rhrdt_year, 0);
         | 
| 2734 | 
            +
              rb_define_method(rhrdt_class, "zone", rhrdt_zone, 0);
         | 
| 2735 | 
            +
              
         | 
| 2736 | 
            +
              rb_define_method(rhrdt_class, ">>", rhrdt_op_right_shift, 1);
         | 
| 2737 | 
            +
              rb_define_method(rhrdt_class, "<<", rhrdt_op_left_shift, 1);
         | 
| 2738 | 
            +
              rb_define_method(rhrdt_class, "+", rhrdt_op_plus, 1);
         | 
| 2739 | 
            +
              rb_define_method(rhrdt_class, "-", rhrdt_op_minus, 1);
         | 
| 2740 | 
            +
              rb_define_method(rhrdt_class, "===", rhrdt_op_relationship, 1);
         | 
| 2741 | 
            +
              rb_define_method(rhrdt_class, "<=>", rhrdt_op_spaceship, 1);
         | 
| 2742 | 
            +
             | 
| 2743 | 
            +
              rb_define_alias(rhrdt_class, "ctime", "asctime");
         | 
| 2744 | 
            +
              rb_define_alias(rhrdt_class, "mday", "day");
         | 
| 2745 | 
            +
              rb_define_alias(rhrdt_class, "mon", "month");
         | 
| 2746 | 
            +
              rb_define_alias(rhrdt_class, "succ", "next");
         | 
| 2747 | 
            +
             | 
| 2748 | 
            +
            #ifdef RUBY19
         | 
| 2749 | 
            +
             | 
| 2750 | 
            +
              /* Define methods for ruby 1.9 */
         | 
| 2751 | 
            +
             | 
| 2752 | 
            +
              rb_define_method(rhrdt_s_class, "httpdate", rhrdt_s_httpdate, -1);
         | 
| 2753 | 
            +
              rb_define_method(rhrdt_s_class, "iso8601", rhrdt_s_iso8601, -1);
         | 
| 2754 | 
            +
              rb_define_method(rhrdt_s_class, "jisx0301", rhrdt_s_jisx0301, -1);
         | 
| 2755 | 
            +
              rb_define_method(rhrdt_s_class, "rfc2822", rhrdt_s_rfc2822, -1);
         | 
| 2756 | 
            +
              rb_define_method(rhrdt_s_class, "rfc3339", rhrdt_s_rfc3339, -1);
         | 
| 2757 | 
            +
              rb_define_method(rhrdt_s_class, "xmlschema", rhrdt_s_xmlschema, -1);
         | 
| 2758 | 
            +
             | 
| 2759 | 
            +
              rb_define_alias(rhrdt_s_class, "rfc822", "rfc2822");
         | 
| 2760 | 
            +
             | 
| 2761 | 
            +
              rb_define_method(rhrdt_class, "httpdate", rhrdt_httpdate, 0);
         | 
| 2762 | 
            +
              rb_define_method(rhrdt_class, "iso8601", rhrdt_iso8601, -1);
         | 
| 2763 | 
            +
              rb_define_method(rhrdt_class, "jisx0301", rhrdt_jisx0301, -1);
         | 
| 2764 | 
            +
              rb_define_method(rhrdt_class, "next_day", rhrdt_next_day, -1);
         | 
| 2765 | 
            +
              rb_define_method(rhrdt_class, "next_month", rhrdt_next_month, -1);
         | 
| 2766 | 
            +
              rb_define_method(rhrdt_class, "next_year", rhrdt_next_year, -1);
         | 
| 2767 | 
            +
              rb_define_method(rhrdt_class, "prev_day", rhrdt_prev_day, -1);
         | 
| 2768 | 
            +
              rb_define_method(rhrdt_class, "prev_month", rhrdt_prev_month, -1);
         | 
| 2769 | 
            +
              rb_define_method(rhrdt_class, "prev_year", rhrdt_prev_year, -1);
         | 
| 2770 | 
            +
              rb_define_method(rhrdt_class, "rfc2822", rhrdt_rfc2822, 0);
         | 
| 2771 | 
            +
              rb_define_method(rhrdt_class, "to_date", rhrdt_to_date, 0);
         | 
| 2772 | 
            +
              rb_define_method(rhrdt_class, "to_time", rhrdt_to_time, 0);
         | 
| 2773 | 
            +
             | 
| 2774 | 
            +
              rb_define_alias(rhrdt_class, "minute", "min");
         | 
| 2775 | 
            +
              rb_define_alias(rhrdt_class, "rfc3339", "iso8601");
         | 
| 2776 | 
            +
              rb_define_alias(rhrdt_class, "rfc822", "rfc2822");
         | 
| 2777 | 
            +
              rb_define_alias(rhrdt_class, "second", "sec");
         | 
| 2778 | 
            +
              rb_define_alias(rhrdt_class, "second_fraction", "sec_fraction");
         | 
| 2779 | 
            +
              rb_define_alias(rhrdt_class, "to_datetime", "gregorian");
         | 
| 2780 | 
            +
              rb_define_alias(rhrdt_class, "xmlschema", "iso8601");
         | 
| 2781 | 
            +
             | 
| 2782 | 
            +
              rb_define_method(rhrdt_class, "sunday?", rhrdt_sunday_q, 0);
         | 
| 2783 | 
            +
              rb_define_method(rhrdt_class, "monday?", rhrdt_monday_q, 0);
         | 
| 2784 | 
            +
              rb_define_method(rhrdt_class, "tuesday?", rhrdt_tuesday_q, 0);
         | 
| 2785 | 
            +
              rb_define_method(rhrdt_class, "wednesday?", rhrdt_wednesday_q, 0);
         | 
| 2786 | 
            +
              rb_define_method(rhrdt_class, "thursday?", rhrdt_thursday_q, 0);
         | 
| 2787 | 
            +
              rb_define_method(rhrdt_class, "friday?", rhrdt_friday_q, 0);
         | 
| 2788 | 
            +
              rb_define_method(rhrdt_class, "saturday?", rhrdt_saturday_q, 0);
         | 
| 2789 | 
            +
             | 
| 2790 | 
            +
              rb_define_method(rb_cTime, "to_datetime", rhrdt_time_to_datetime, 0);
         | 
| 2791 | 
            +
            #else
         | 
| 2792 | 
            +
             | 
| 2793 | 
            +
              /* Define methods for ruby 1.8 */
         | 
| 2794 | 
            +
             | 
| 2795 | 
            +
              rb_define_alias(rhrdt_s_class, "new0", "new!");
         | 
| 2796 | 
            +
              rb_define_alias(rhrdt_s_class, "new1", "jd");
         | 
| 2797 | 
            +
              rb_define_alias(rhrdt_s_class, "new2", "ordinal");
         | 
| 2798 | 
            +
              rb_define_alias(rhrdt_s_class, "new3", "civil");
         | 
| 2799 | 
            +
              rb_define_alias(rhrdt_s_class, "neww", "commercial");
         | 
| 2800 | 
            +
             | 
| 2801 | 
            +
              rb_define_alias(rhrdt_class, "newof", "new_offset");
         | 
| 2802 | 
            +
              rb_define_alias(rhrdt_class, "of", "offset");
         | 
| 2803 | 
            +
            #endif
         | 
| 2804 | 
            +
            }
         |