home_run 0.9.0-x86-mingw32
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG +3 -0
- data/LICENSE +19 -0
- data/README.rdoc +314 -0
- data/Rakefile +136 -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/date_ext.c
ADDED
@@ -0,0 +1,4548 @@
|
|
1
|
+
|
2
|
+
#include <math.h>
|
3
|
+
#include <stdio.h>
|
4
|
+
#include <stdlib.h>
|
5
|
+
#include <inttypes.h>
|
6
|
+
#include <ruby.h>
|
7
|
+
|
8
|
+
#ifdef RUBY19
|
9
|
+
#define RHR_DEFAULT_CWYEAR -4713
|
10
|
+
#define RHR_DEFAULT_CWEEK 1
|
11
|
+
#define RHR_DEFAULT_CWDAY 1
|
12
|
+
#else
|
13
|
+
#define RHR_DEFAULT_CWYEAR 1582
|
14
|
+
#define RHR_DEFAULT_CWEEK 41
|
15
|
+
#define RHR_DEFAULT_CWDAY 5
|
16
|
+
#endif
|
17
|
+
|
18
|
+
#define RHR_JD_MJD 2400001
|
19
|
+
#define RHR_JD_LD 2299160
|
20
|
+
#define RHR_JD_ITALY 2299161
|
21
|
+
#define RHR_JD_ENGLAND 2361222
|
22
|
+
#define RHR_UNIX_EPOCH 2440588
|
23
|
+
#define RHR_SECONDS_PER_HOUR 3600
|
24
|
+
#define RHR_MINUTES_PER_DAYD 1440.0
|
25
|
+
#define RHR_SECONDS_PER_DAY 86400
|
26
|
+
#define RHR_SECONDS_PER_DAYD 86400.0
|
27
|
+
#define RHR_MAX_OFFSET_MINUTES 864
|
28
|
+
#define RHR_MAX_OFFSET_FRACT 0.6
|
29
|
+
#define RHR_MIN_OFFSET_MINUTES -864
|
30
|
+
#define RHR_MIN_OFFSET_FRACT -0.6
|
31
|
+
|
32
|
+
/*
|
33
|
+
In both the 32-bit and 64-bit cases, the limits are chosen so that you cannot
|
34
|
+
store a civil date where converting it to a jd would cause an overflow.
|
35
|
+
*/
|
36
|
+
#if __LP64__
|
37
|
+
/*
|
38
|
+
On 64-bit systems, the limits depend on the number of significant digits in
|
39
|
+
a double (15). These are slightly below the maximum so that all numbers used
|
40
|
+
in calculations have fewer than 15 digits.
|
41
|
+
*/
|
42
|
+
#define RHR_JD_MAX 999979466117609
|
43
|
+
#define RHR_JD_MIN -999979466119058
|
44
|
+
#define RHR_YEAR_MAX 2737850782415
|
45
|
+
#define RHR_MONTH_MAX 12
|
46
|
+
#define RHR_DAY_MAX 5
|
47
|
+
#define RHR_YEAR_MIN -2737850791845
|
48
|
+
#define RHR_MONTH_MIN 11
|
49
|
+
#define RHR_DAY_MIN 26
|
50
|
+
|
51
|
+
#else
|
52
|
+
/*
|
53
|
+
On 32-bit systems, the limits depend on the storage limits of 32-bit integers.
|
54
|
+
The numbers are slightly less than 2**31 - 1 and slightly greater than -2**31
|
55
|
+
so that no calculations can overflow.
|
56
|
+
*/
|
57
|
+
#define RHR_JD_MAX 2147438064
|
58
|
+
#define RHR_JD_MIN -2145083647
|
59
|
+
#define RHR_YEAR_MAX 5874773
|
60
|
+
#define RHR_MONTH_MAX 8
|
61
|
+
#define RHR_DAY_MAX 15
|
62
|
+
#define RHR_YEAR_MIN -5877752
|
63
|
+
#define RHR_MONTH_MIN 5
|
64
|
+
#define RHR_DAY_MIN 8
|
65
|
+
#endif
|
66
|
+
|
67
|
+
#define RHR_HAVE_JD 1
|
68
|
+
#define RHR_HAVE_CIVIL 2
|
69
|
+
#define RHR_HAVE_NANOS 4
|
70
|
+
#define RHR_HAVE_HMS 8
|
71
|
+
|
72
|
+
#define RHR_NANOS_PER_MILLISECOND 1000000LL
|
73
|
+
#define RHR_NANOS_PER_SECOND 1000000000LL
|
74
|
+
#define RHR_NANOS_PER_MINUTE 60000000000LL
|
75
|
+
#define RHR_NANOS_PER_DAY 86400000000000LL
|
76
|
+
#define RHR_NANOS_PER_DAYD 86400000000000.0
|
77
|
+
#define RHR_NANOS_PER_SECONDD 1000000000.0
|
78
|
+
|
79
|
+
#define RHRR_YEAR_SET 0x1
|
80
|
+
#define RHRR_MONTH_SET 0x2
|
81
|
+
#define RHRR_DAY_SET 0x4
|
82
|
+
#define RHRR_YDAY_SET 0x8
|
83
|
+
#define RHRR_HOUR_SET 0x10
|
84
|
+
#define RHRR_MINUTE_SET 0x20
|
85
|
+
#define RHRR_SECOND_SET 0x40
|
86
|
+
#define RHRR_WDAY_SET 0x80
|
87
|
+
#define RHRR_CENTURY_SET 0x100
|
88
|
+
#define RHRR_CWYEAR_SET 0x200
|
89
|
+
#define RHRR_CWEEK_SET 0x400
|
90
|
+
#define RHRR_CWDAY_SET 0x800
|
91
|
+
#define RHRR_SEC_FRACTION_SET 0x1000
|
92
|
+
#define RHRR_UNIX_SET 0x2000
|
93
|
+
#define RHRR_WNUM0_SET 0x4000
|
94
|
+
#define RHRR_WNUM1_SET 0x8000
|
95
|
+
#define RHRR_MERIDIAN_SET 0x10000
|
96
|
+
#define RHRR_ZONE_SET 0x20000
|
97
|
+
#define RHRR_OFFSET_SET 0x40000
|
98
|
+
#define RHRR_UNIXM_SET 0x80000
|
99
|
+
|
100
|
+
#define RHR_HAS_JD(d) (((d)->flags & RHR_HAVE_JD) == RHR_HAVE_JD)
|
101
|
+
#define RHR_HAS_CIVIL(d) (((d)->flags & RHR_HAVE_CIVIL) == RHR_HAVE_CIVIL)
|
102
|
+
|
103
|
+
#define RHR_FILL_JD(d) if (((d)->flags & RHR_HAVE_JD) == 0) { rhrd__civil_to_jd(d); }
|
104
|
+
#define RHR_FILL_CIVIL(d) if (((d)->flags & RHR_HAVE_CIVIL) == 0) { rhrd__jd_to_civil(d); }
|
105
|
+
|
106
|
+
#define RHRDT_FILL_JD(d) if (!((d)->flags & RHR_HAVE_JD)) { rhrdt__civil_to_jd(d); }
|
107
|
+
#define RHRDT_FILL_CIVIL(d) if (!((d)->flags & RHR_HAVE_CIVIL)) { rhrdt__jd_to_civil(d); }
|
108
|
+
#define RHRDT_FILL_HMS(d) if (!((d)->flags & RHR_HAVE_HMS)) { rhrdt__nanos_to_hms(d); }
|
109
|
+
#define RHRDT_FILL_NANOS(d) if (!((d)->flags & RHR_HAVE_NANOS)) { rhrdt__hms_to_nanos(d); }
|
110
|
+
|
111
|
+
#ifdef RUBY186
|
112
|
+
#define RHR_RETURN_RESIZED_STR(s, len) return rb_str_resize(s, len);
|
113
|
+
#else
|
114
|
+
#define RHR_RETURN_RESIZED_STR(s, len) rb_str_set_len(s, len); return s;
|
115
|
+
#endif
|
116
|
+
|
117
|
+
#define RHR_SPACE_SHIP(x, l, r) if (l < r) { x = -1; } else if (l == r) { x = 0; } else { x = 1; }
|
118
|
+
|
119
|
+
#define RHR_CHECK_JD(d) if ((d->jd > RHR_JD_MAX) || (d->jd < RHR_JD_MIN)) { rb_raise(rb_eRangeError, "date out of range: jd = %li", d->jd);}
|
120
|
+
#define RHR_CHECK_CIVIL(d) if (!rhrd__valid_civil_limits(d->year, d->month, d->day)) { rb_raise(rb_eRangeError, "date out of range: year = %li, month = %hhi, day = %hhi", d->year, d->month, d->day);}
|
121
|
+
|
122
|
+
#define RHR_CACHED_IV(self, iv) VALUE v = rb_ivar_get(self, iv); if (RTEST(v)) {return v;}
|
123
|
+
|
124
|
+
typedef struct rhrd_s {
|
125
|
+
long jd;
|
126
|
+
long year;
|
127
|
+
unsigned char month;
|
128
|
+
unsigned char day;
|
129
|
+
unsigned char flags;
|
130
|
+
} rhrd_t;
|
131
|
+
|
132
|
+
typedef struct rhrdt_s {
|
133
|
+
long long nanos; /* Nanoseconds since start of day */
|
134
|
+
long jd;
|
135
|
+
long year;
|
136
|
+
short offset; /* Offset from UTC in minutes */
|
137
|
+
unsigned char month;
|
138
|
+
unsigned char day;
|
139
|
+
unsigned char hour;
|
140
|
+
unsigned char minute;
|
141
|
+
unsigned char second;
|
142
|
+
unsigned char flags;
|
143
|
+
} rhrdt_t;
|
144
|
+
|
145
|
+
const unsigned char rhrd_days_in_month[13] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
|
146
|
+
const long rhrd_cumulative_days_in_month[13] = {0, 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334};
|
147
|
+
const unsigned char rhrd_yday_to_month[366] = {0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12};
|
148
|
+
const unsigned char rhrd_leap_yday_to_month[367] = {0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12};
|
149
|
+
const char * rhrd__month_names[13] = {"", "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"};
|
150
|
+
const char * rhrd__abbr_month_names[13] = {"", "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"};
|
151
|
+
const char * rhrd__day_names[7] = {"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"};
|
152
|
+
const char * rhrd__abbr_day_names[7] = {"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"};
|
153
|
+
const char rhrd__zone_re_str[] = "\\A(?:gmt|utc?)?[-+]\\d+(?:[,.:]\\d+(?::\\d+)?)?|[[:alpha:].\\s]+(?:standard|daylight)\\s+time\\b|[[:alpha:]]+(?:\\s+dst)?\\b";
|
154
|
+
const char rhrd__zone_dst_re_str[] = "\\s+(?:(?:(standard)|daylight)\\s+time|dst)\\z";
|
155
|
+
const char rhrd__zone_sign_re_str[] = "\\A(?:gmt|utc?)?(?:(-)|\\+)";
|
156
|
+
|
157
|
+
VALUE rhrd_class;
|
158
|
+
VALUE rhrd_s_class;
|
159
|
+
VALUE rhrdt_class;
|
160
|
+
VALUE rhrdt_s_class;
|
161
|
+
VALUE rhrd_monthnames;
|
162
|
+
VALUE rhrd_abbr_monthnames;
|
163
|
+
VALUE rhrd_daynames;
|
164
|
+
VALUE rhrd_abbr_daynames;
|
165
|
+
VALUE rhrd_zone_re;
|
166
|
+
VALUE rhrd_zone_dst_re;
|
167
|
+
VALUE rhrd_zone_sign_re;
|
168
|
+
VALUE rhrd_zones_hash;
|
169
|
+
VALUE rhrd_empty_string;
|
170
|
+
VALUE rhrd_start_num;
|
171
|
+
VALUE rhrd_string_colon;
|
172
|
+
VALUE rhrd_re_comma_period;
|
173
|
+
|
174
|
+
ID rhrd_id_op_array;
|
175
|
+
ID rhrd_id_op_gte;
|
176
|
+
ID rhrd_id_op_lt;
|
177
|
+
ID rhrd_id__parse;
|
178
|
+
ID rhrd_id_cwday;
|
179
|
+
ID rhrd_id_cweek;
|
180
|
+
ID rhrd_id_cwyear;
|
181
|
+
ID rhrd_id_downcase;
|
182
|
+
ID rhrd_id_getlocal;
|
183
|
+
ID rhrd_id_hash;
|
184
|
+
ID rhrd_id_include_q;
|
185
|
+
ID rhrd_id_length;
|
186
|
+
ID rhrd_id_local;
|
187
|
+
ID rhrd_id_localtime;
|
188
|
+
ID rhrd_id_match;
|
189
|
+
ID rhrd_id_now;
|
190
|
+
ID rhrd_id_offset;
|
191
|
+
ID rhrd_id_slice;
|
192
|
+
ID rhrd_id_split;
|
193
|
+
ID rhrd_id_sub_b;
|
194
|
+
ID rhrd_id_to_i;
|
195
|
+
#ifdef RUBY19
|
196
|
+
ID rhrd_id_nsec;
|
197
|
+
#else
|
198
|
+
ID rhrd_id_usec;
|
199
|
+
#endif
|
200
|
+
ID rhrd_id_utc;
|
201
|
+
ID rhrd_id_utc_offset;
|
202
|
+
|
203
|
+
#ifdef RUBY19
|
204
|
+
ID rhrd_id__httpdate;
|
205
|
+
ID rhrd_id__iso8601;
|
206
|
+
ID rhrd_id__jisx0301;
|
207
|
+
ID rhrd_id__rfc2822;
|
208
|
+
ID rhrd_id__rfc3339;
|
209
|
+
ID rhrd_id__xmlschema;
|
210
|
+
#endif
|
211
|
+
|
212
|
+
VALUE rhrd_sym_cwday;
|
213
|
+
VALUE rhrd_sym_cweek;
|
214
|
+
VALUE rhrd_sym_cwyear;
|
215
|
+
VALUE rhrd_sym_hour;
|
216
|
+
#ifdef RUBY19
|
217
|
+
VALUE rhrd_sym_leftover;
|
218
|
+
#endif
|
219
|
+
VALUE rhrd_sym_mday;
|
220
|
+
VALUE rhrd_sym_min;
|
221
|
+
VALUE rhrd_sym_mon;
|
222
|
+
VALUE rhrd_sym_offset;
|
223
|
+
VALUE rhrd_sym_sec;
|
224
|
+
VALUE rhrd_sym_sec_fraction;
|
225
|
+
VALUE rhrd_sym_seconds;
|
226
|
+
VALUE rhrd_sym_wday;
|
227
|
+
VALUE rhrd_sym_wnum0;
|
228
|
+
VALUE rhrd_sym_wnum1;
|
229
|
+
VALUE rhrd_sym_yday;
|
230
|
+
VALUE rhrd_sym_year;
|
231
|
+
VALUE rhrd_sym_zone;
|
232
|
+
|
233
|
+
static VALUE rhrd_step(int argc, VALUE *argv, VALUE self);
|
234
|
+
static VALUE rhrdt_step(int argc, VALUE *argv, VALUE self);
|
235
|
+
static VALUE rhrd_to_s(VALUE self);
|
236
|
+
static VALUE rhrdt_to_s(VALUE self);
|
237
|
+
static VALUE rhrd_s_zone_to_diff(VALUE self, VALUE zone);
|
238
|
+
VALUE rhrdt__new_offset(VALUE self, double offset);
|
239
|
+
void rhrdt__civil_to_jd(rhrdt_t *d);
|
240
|
+
void rhrdt__jd_to_civil(rhrdt_t *date);
|
241
|
+
void rhrdt__nanos_to_hms(rhrdt_t *d);
|
242
|
+
void rhrdt__hms_to_nanos(rhrdt_t *d);
|
243
|
+
|
244
|
+
/* C helper methods */
|
245
|
+
|
246
|
+
/* C % operator can (must in C99) return negative number for negative
|
247
|
+
* dividend, this always returns a positive number, similar to ruby. */
|
248
|
+
long rhrd__mod(long a, long b) {
|
249
|
+
long c;
|
250
|
+
c = a % b;
|
251
|
+
if (c < 0) {
|
252
|
+
c += b;
|
253
|
+
}
|
254
|
+
return c;
|
255
|
+
}
|
256
|
+
|
257
|
+
/* Same as above but for long long dividend. */
|
258
|
+
long rhrd__modll(long long a, long b) {
|
259
|
+
long c;
|
260
|
+
c = a % b;
|
261
|
+
if (c < 0) {
|
262
|
+
c += b;
|
263
|
+
}
|
264
|
+
return c;
|
265
|
+
}
|
266
|
+
|
267
|
+
/* Return 0 if the year, month, day provided are greater than
|
268
|
+
* the allowed limits, 1 otherwise. */
|
269
|
+
int rhrd__valid_civil_limits(long year, long month, long day) {
|
270
|
+
if (year > RHR_YEAR_MAX || year < RHR_YEAR_MIN) {
|
271
|
+
return 0;
|
272
|
+
}
|
273
|
+
else if (year == RHR_YEAR_MAX) {
|
274
|
+
if (month > RHR_MONTH_MAX) {
|
275
|
+
return 0;
|
276
|
+
} else if (month == RHR_MONTH_MAX) {
|
277
|
+
if (day > RHR_DAY_MAX) {
|
278
|
+
return 0;
|
279
|
+
}
|
280
|
+
}
|
281
|
+
} else if (year == RHR_YEAR_MIN) {
|
282
|
+
if (month < RHR_MONTH_MIN) {
|
283
|
+
return 0;
|
284
|
+
} else if (month == RHR_MONTH_MIN) {
|
285
|
+
if (day < RHR_DAY_MIN) {
|
286
|
+
return 0;
|
287
|
+
}
|
288
|
+
}
|
289
|
+
}
|
290
|
+
return 1;
|
291
|
+
}
|
292
|
+
|
293
|
+
/* Add two numbers, raising a RangeError on
|
294
|
+
* overflow. */
|
295
|
+
long rhrd__safe_add_long(long a, long b) {
|
296
|
+
if ((a > 0 && b > 0 && (a > LONG_MAX - b)) ||
|
297
|
+
(a < 0 && b < 0 && (a < LONG_MIN - b))) {
|
298
|
+
rb_raise(rb_eRangeError, "addition would overflow");
|
299
|
+
}
|
300
|
+
return a + b;
|
301
|
+
}
|
302
|
+
|
303
|
+
/* Convert a year, month, day to a julian date. */
|
304
|
+
long rhrd__ymd_to_jd(long year, long month, long day) {
|
305
|
+
long a;
|
306
|
+
if (month <= 2) {
|
307
|
+
a = (long)floor((year - 1)/100.0);
|
308
|
+
return (long)floor(365.25 * (year + 4715)) + \
|
309
|
+
(long)floor(30.6001 * (month + 13)) + \
|
310
|
+
day - 1524 + (2 - a + (long)floor(a / 4.0));
|
311
|
+
} else {
|
312
|
+
a = (long)floor(year/100.0);
|
313
|
+
return (long)floor(365.25 * (year + 4716)) + \
|
314
|
+
(long)floor(30.6001 * (month + 1)) + \
|
315
|
+
day - 1524 + (2 - a + (long)floor(a / 4.0));
|
316
|
+
}
|
317
|
+
}
|
318
|
+
|
319
|
+
/* Fill the jd field rhrd_t with the info from the year,
|
320
|
+
* month, and day fields. This assumes the year,
|
321
|
+
* month, and day fields have already been filled in. */
|
322
|
+
void rhrd__civil_to_jd(rhrd_t *d) {
|
323
|
+
d->jd = rhrd__ymd_to_jd(d->year, d->month, d->day);
|
324
|
+
d->flags |= RHR_HAVE_JD;
|
325
|
+
}
|
326
|
+
|
327
|
+
/* Fill in the year, month, and day fields for an
|
328
|
+
* rhrd_t, using the jd field. This assumes the jd
|
329
|
+
* field has already been filled in. */
|
330
|
+
void rhrd__jd_to_civil(rhrd_t *date) {
|
331
|
+
long x, a, b, c, d, e;
|
332
|
+
x = (long)floor((date->jd - 1867216.25) / 36524.25);
|
333
|
+
a = date->jd + 1 + x - (long)floor(x / 4.0);
|
334
|
+
b = a + 1524;
|
335
|
+
c = (long)floor((b - 122.1) / 365.25);
|
336
|
+
d = (long)floor(365.25 * c);
|
337
|
+
e = (long)floor((b - d) / 30.6001);
|
338
|
+
date->day = b - d - (long)floor(30.6001 * e);
|
339
|
+
if (e <= 13) {
|
340
|
+
date->month = e - 1;
|
341
|
+
date->year = c - 4716;
|
342
|
+
} else {
|
343
|
+
date->month = e - 13;
|
344
|
+
date->year = c - 4715;
|
345
|
+
}
|
346
|
+
date->flags |= RHR_HAVE_CIVIL;
|
347
|
+
}
|
348
|
+
|
349
|
+
/* Returns 1 if the given year is a leap year in the Gregorian
|
350
|
+
* calendar, 0 if not. */
|
351
|
+
int rhrd__leap_year(long year) {
|
352
|
+
if (year % 400 == 0) {
|
353
|
+
return 1;
|
354
|
+
} else if (year % 100 == 0) {
|
355
|
+
return 0;
|
356
|
+
} else if (year % 4 == 0) {
|
357
|
+
return 1;
|
358
|
+
} else {
|
359
|
+
return 0;
|
360
|
+
}
|
361
|
+
}
|
362
|
+
|
363
|
+
/* Check if the year, month, and day given are a valid date
|
364
|
+
* in the Gregorian calendar, filling in the appropriate
|
365
|
+
* fields in the rhrd_t and returning 1 if so. If the fields
|
366
|
+
* given are not a valid date, return 0.
|
367
|
+
* This also handles wrap around if the month or day is negative. */
|
368
|
+
int rhrd__valid_civil(rhrd_t *d, long year, long month, long day) {
|
369
|
+
if (month < 0 && month >= -12) {
|
370
|
+
month += 13;
|
371
|
+
}
|
372
|
+
if (month < 1 || month > 12) {
|
373
|
+
return 0;
|
374
|
+
}
|
375
|
+
|
376
|
+
if (day < 0) {
|
377
|
+
if (month == 2) {
|
378
|
+
day += rhrd__leap_year(year) ? 30 : 29;
|
379
|
+
} else {
|
380
|
+
day += rhrd_days_in_month[month] + 1;
|
381
|
+
}
|
382
|
+
}
|
383
|
+
if (day < 1 || day > 28) {
|
384
|
+
if (day > 31 || day <= 0) {
|
385
|
+
return 0;
|
386
|
+
} else if (month == 2) {
|
387
|
+
if (rhrd__leap_year(year)) {
|
388
|
+
if (day > 29) {
|
389
|
+
return 0;
|
390
|
+
}
|
391
|
+
} else if (day > 28) {
|
392
|
+
return 0;
|
393
|
+
}
|
394
|
+
} else if (day > rhrd_days_in_month[month]) {
|
395
|
+
return 0;
|
396
|
+
}
|
397
|
+
}
|
398
|
+
|
399
|
+
if(!rhrd__valid_civil_limits(year, month, day)) {
|
400
|
+
return 0;
|
401
|
+
}
|
402
|
+
|
403
|
+
d->year = year;
|
404
|
+
d->month = (unsigned char)month;
|
405
|
+
d->day = (unsigned char)day;
|
406
|
+
d->flags |= RHR_HAVE_CIVIL;
|
407
|
+
return 1;
|
408
|
+
}
|
409
|
+
|
410
|
+
/* Return the number of days in the given month in the given year */
|
411
|
+
unsigned char rhrd__days_in_month(long year, unsigned char month) {
|
412
|
+
if (month == 2) {
|
413
|
+
return rhrd__leap_year(year) ? 29 : 28;
|
414
|
+
} else {
|
415
|
+
return rhrd_days_in_month[month];
|
416
|
+
}
|
417
|
+
}
|
418
|
+
|
419
|
+
/* Add n days to the the given Date object. n can be negative if
|
420
|
+
* you want to subtract days from the object. Returns a new ruby
|
421
|
+
* Date object. */
|
422
|
+
VALUE rhrd__add_days(VALUE self, long n) {
|
423
|
+
rhrd_t *d;
|
424
|
+
rhrd_t *newd;
|
425
|
+
VALUE new;
|
426
|
+
long x;
|
427
|
+
Data_Get_Struct(self, rhrd_t, d);
|
428
|
+
new = Data_Make_Struct(rhrd_class, rhrd_t, NULL, free, newd);
|
429
|
+
|
430
|
+
if(!(RHR_HAS_JD(d))) {
|
431
|
+
x = rhrd__safe_add_long(n, (long)(d->day));
|
432
|
+
if (x >= 1 && x <= 28) {
|
433
|
+
newd->year = d->year;
|
434
|
+
newd->month = d->month;
|
435
|
+
newd->day = (unsigned char)x;
|
436
|
+
RHR_CHECK_CIVIL(newd)
|
437
|
+
newd->flags = RHR_HAVE_CIVIL;
|
438
|
+
return new;
|
439
|
+
}
|
440
|
+
RHR_FILL_JD(d)
|
441
|
+
}
|
442
|
+
|
443
|
+
newd->jd = rhrd__safe_add_long(n, d->jd);
|
444
|
+
RHR_CHECK_JD(newd)
|
445
|
+
newd->flags = RHR_HAVE_JD;
|
446
|
+
return new;
|
447
|
+
}
|
448
|
+
|
449
|
+
/* Add n months to the given ruby Date object. n can be negative
|
450
|
+
* if you want to subtract months from the object. Returns a new
|
451
|
+
* ruby Date object. */
|
452
|
+
VALUE rhrd__add_months(VALUE self, long n) {
|
453
|
+
rhrd_t *d;
|
454
|
+
rhrd_t *newd;
|
455
|
+
VALUE new;
|
456
|
+
long x;
|
457
|
+
Data_Get_Struct(self, rhrd_t, d);
|
458
|
+
|
459
|
+
new = Data_Make_Struct(rhrd_class, rhrd_t, NULL, free, newd);
|
460
|
+
RHR_FILL_CIVIL(d)
|
461
|
+
n = rhrd__safe_add_long(n, (long)(d->month));
|
462
|
+
if(n > 1 && n <= 12) {
|
463
|
+
newd->year = d->year;
|
464
|
+
newd->month = n;
|
465
|
+
} else {
|
466
|
+
x = n / 12;
|
467
|
+
n = n % 12;
|
468
|
+
if (n <= 0) {
|
469
|
+
newd->year = d->year + x - 1;
|
470
|
+
newd->month = n + 12;
|
471
|
+
} else {
|
472
|
+
newd->year = d->year + x;
|
473
|
+
newd->month = (unsigned char)n;
|
474
|
+
}
|
475
|
+
}
|
476
|
+
x = rhrd__days_in_month(newd->year, newd->month);
|
477
|
+
newd->day = (unsigned char)(d->day > x ? x : d->day);
|
478
|
+
RHR_CHECK_CIVIL(newd)
|
479
|
+
newd->flags = RHR_HAVE_CIVIL;
|
480
|
+
return new;
|
481
|
+
}
|
482
|
+
|
483
|
+
/* Return 0 if the given two rhrd_t objects have the
|
484
|
+
* same julian or civil dates, -1 if the first is
|
485
|
+
* less than the second, or 1 otherwise. */
|
486
|
+
long rhrd__spaceship(rhrd_t *d, rhrd_t *o) {
|
487
|
+
long diff;
|
488
|
+
if (RHR_HAS_JD(d) && RHR_HAS_JD(o)) {
|
489
|
+
RHR_SPACE_SHIP(diff, d->jd, o->jd)
|
490
|
+
} else if (RHR_HAS_CIVIL(d) && RHR_HAS_CIVIL(o)) {
|
491
|
+
RHR_SPACE_SHIP(diff, d->year, o->year)
|
492
|
+
if (!diff) {
|
493
|
+
RHR_SPACE_SHIP(diff, d->month, o->month)
|
494
|
+
if (!diff) {
|
495
|
+
RHR_SPACE_SHIP(diff, d->day, o->day)
|
496
|
+
}
|
497
|
+
}
|
498
|
+
} else {
|
499
|
+
RHR_FILL_JD(d)
|
500
|
+
RHR_FILL_JD(o)
|
501
|
+
RHR_SPACE_SHIP(diff, d->jd, o->jd)
|
502
|
+
}
|
503
|
+
return diff;
|
504
|
+
}
|
505
|
+
|
506
|
+
/* Convert the given cwyear, cweek, and cwday arguments to
|
507
|
+
* a julian date. */
|
508
|
+
long rhrd__commercial_to_jd(long cwyear, long cweek, long cwday) {
|
509
|
+
rhrd_t n;
|
510
|
+
memset(&n, 0, sizeof(rhrd_t));
|
511
|
+
|
512
|
+
n.year = cwyear;
|
513
|
+
n.month = 1;
|
514
|
+
n.day = 4;
|
515
|
+
rhrd__civil_to_jd(&n);
|
516
|
+
return n.jd - rhrd__mod(n.jd, 7) + 7 * (cweek - 1) + (cwday - 1);
|
517
|
+
}
|
518
|
+
|
519
|
+
/* Convert the given julian date to a cwday (range: [1-7]). */
|
520
|
+
long rhrd__jd_to_cwday(long jd) {
|
521
|
+
long day;
|
522
|
+
day = (jd + 1) % 7;
|
523
|
+
if (day <= 0) {
|
524
|
+
day += 7;
|
525
|
+
}
|
526
|
+
return day;
|
527
|
+
}
|
528
|
+
|
529
|
+
/* Convert the given julian date to a weekday number
|
530
|
+
* (range: [0-6], 0 is Sunday). */
|
531
|
+
long rhrd__jd_to_wday(long jd) {
|
532
|
+
return rhrd__mod(jd + 1, 7);
|
533
|
+
}
|
534
|
+
|
535
|
+
|
536
|
+
/* Fill the given rhrd_t with the commercial week
|
537
|
+
* information specified by its julian date.
|
538
|
+
* Abuses the year, month, and day fields to store
|
539
|
+
* cwyear, cweek, and cwday, so it should not be
|
540
|
+
* used on a ruby Date object that has its civil
|
541
|
+
* date filled in. */
|
542
|
+
void rhrd__fill_commercial(rhrd_t *d) {
|
543
|
+
long a;
|
544
|
+
rhrd_t n;
|
545
|
+
memset(&n, 0, sizeof(rhrd_t));
|
546
|
+
|
547
|
+
n.jd = d->jd - 3;
|
548
|
+
rhrd__jd_to_civil(&n);
|
549
|
+
a = n.year;
|
550
|
+
d->year = d->jd >= rhrd__commercial_to_jd(a + 1, 1, 1) ? a + 1 : a;
|
551
|
+
d->month = 1 + (d->jd - rhrd__commercial_to_jd(d->year, 1, 1)) / 7;
|
552
|
+
d->day = (unsigned char)rhrd__jd_to_cwday(d->jd);
|
553
|
+
}
|
554
|
+
|
555
|
+
/* Fill in the jd field for the given rhrd_t using the cwyear, cweek,
|
556
|
+
* and cwday arguments, if the date is valid, and return 1. If the
|
557
|
+
* date is not valid, return 0. This also handles wrap around if
|
558
|
+
* the cweek or cwday arguments is negative. */
|
559
|
+
int rhrd__valid_commercial(rhrd_t *d, long cwyear, long cweek, long cwday) {
|
560
|
+
rhrd_t n;
|
561
|
+
memset(&n, 0, sizeof(rhrd_t));
|
562
|
+
|
563
|
+
if (cwday < 0) {
|
564
|
+
if (cwday < -8) {
|
565
|
+
return 0;
|
566
|
+
}
|
567
|
+
cwday += 8;
|
568
|
+
}
|
569
|
+
if (cweek < 0) {
|
570
|
+
if (cweek < -53) {
|
571
|
+
return 0;
|
572
|
+
}
|
573
|
+
n.jd = rhrd__commercial_to_jd(cwyear + 1, 1, 1) + cweek * 7;
|
574
|
+
rhrd__fill_commercial(&n);
|
575
|
+
if (n.year != cwyear) {
|
576
|
+
return 0;
|
577
|
+
}
|
578
|
+
cweek = n.month;
|
579
|
+
memset(&n, 0, sizeof(rhrd_t));
|
580
|
+
}
|
581
|
+
|
582
|
+
n.jd = rhrd__commercial_to_jd(cwyear, cweek, cwday);
|
583
|
+
rhrd__fill_commercial(&n);
|
584
|
+
if(cwyear != n.year || cweek != n.month || cwday != n.day) {
|
585
|
+
return 0;
|
586
|
+
}
|
587
|
+
|
588
|
+
if ((n.jd > RHR_JD_MAX) || (n.jd < RHR_JD_MIN)) {
|
589
|
+
return 0;
|
590
|
+
}
|
591
|
+
|
592
|
+
d->jd = n.jd;
|
593
|
+
d->flags = RHR_HAVE_JD;
|
594
|
+
return 1;
|
595
|
+
}
|
596
|
+
|
597
|
+
/* Return the ordinal day number for the given civil day fields. */
|
598
|
+
long rhrd__ordinal_day(long year, unsigned char month, unsigned char day) {
|
599
|
+
long yday;
|
600
|
+
yday = rhrd_cumulative_days_in_month[month] + day;
|
601
|
+
if(month > 2 && rhrd__leap_year(year)) {
|
602
|
+
yday += 1;
|
603
|
+
}
|
604
|
+
return yday;
|
605
|
+
}
|
606
|
+
|
607
|
+
/* Fill in the civil date fields in the rhrd_t with the
|
608
|
+
* given ordinal day fields, if they are valid. Returns
|
609
|
+
* 1 if the date is valid, 0 if not. This also handles
|
610
|
+
* wrap around for a negative yday argument. */
|
611
|
+
int rhrd__valid_ordinal(rhrd_t *d, long year, long yday) {
|
612
|
+
int leap;
|
613
|
+
long month, day;
|
614
|
+
|
615
|
+
leap = rhrd__leap_year(year);
|
616
|
+
if (yday < 0) {
|
617
|
+
if (leap) {
|
618
|
+
yday += 367;
|
619
|
+
} else {
|
620
|
+
yday += 366;
|
621
|
+
}
|
622
|
+
}
|
623
|
+
if (yday < 1 || yday > (leap ? 366 : 365)) {
|
624
|
+
return 0;
|
625
|
+
}
|
626
|
+
if (leap) {
|
627
|
+
month = rhrd_leap_yday_to_month[yday];
|
628
|
+
if (yday > 60) {
|
629
|
+
day = yday - rhrd_cumulative_days_in_month[month] - 1;
|
630
|
+
} else {
|
631
|
+
day = yday - rhrd_cumulative_days_in_month[month];
|
632
|
+
}
|
633
|
+
} else {
|
634
|
+
month = rhrd_yday_to_month[yday];
|
635
|
+
day = yday - rhrd_cumulative_days_in_month[month];
|
636
|
+
}
|
637
|
+
|
638
|
+
if(!rhrd__valid_civil_limits(year, month, day)) {
|
639
|
+
return 0;
|
640
|
+
}
|
641
|
+
|
642
|
+
d->year = year;
|
643
|
+
d->month = (unsigned char)month;
|
644
|
+
d->day = (unsigned char)day;
|
645
|
+
d->flags |= RHR_HAVE_CIVIL;
|
646
|
+
return 1;
|
647
|
+
}
|
648
|
+
|
649
|
+
/* Convert the given jd to the unix time integer
|
650
|
+
* for the given day at midnight UTC. */
|
651
|
+
long long rhrd__jd_to_unix(long long jd) {
|
652
|
+
return (jd - RHR_UNIX_EPOCH) * RHR_SECONDS_PER_DAY;
|
653
|
+
}
|
654
|
+
|
655
|
+
/* Convert the given unix time integer into a
|
656
|
+
* julian date, losing any information about
|
657
|
+
* fractional days. */
|
658
|
+
long rhrd__unix_to_jd(long long t) {
|
659
|
+
return t/RHR_SECONDS_PER_DAY + RHR_UNIX_EPOCH;
|
660
|
+
}
|
661
|
+
|
662
|
+
/* Fill the given rhrt_d's jd field based on the
|
663
|
+
* current local time. */
|
664
|
+
void rhrd__today(rhrd_t * d) {
|
665
|
+
VALUE t;
|
666
|
+
t = rb_funcall(rb_cTime, rhrd_id_now, 0);
|
667
|
+
d->jd = rhrd__unix_to_jd(NUM2LONG(rb_funcall(t, rhrd_id_to_i, 0)) + NUM2LONG(rb_funcall(t, rhrd_id_utc_offset, 0)));
|
668
|
+
d->flags |= RHR_HAVE_JD;
|
669
|
+
RHR_CHECK_JD(d);
|
670
|
+
}
|
671
|
+
|
672
|
+
/* Return the current year. */
|
673
|
+
long rhrd__current_year(void) {
|
674
|
+
rhrd_t d;
|
675
|
+
memset(&d, 0, sizeof(rhrd_t));
|
676
|
+
rhrd__today(&d);
|
677
|
+
RHR_FILL_CIVIL(&d);
|
678
|
+
return d.year;
|
679
|
+
}
|
680
|
+
|
681
|
+
/* Return the current month. */
|
682
|
+
long rhrd__current_month(void) {
|
683
|
+
rhrd_t d;
|
684
|
+
memset(&d, 0, sizeof(rhrd_t));
|
685
|
+
rhrd__today(&d);
|
686
|
+
RHR_FILL_CIVIL(&d);
|
687
|
+
return d.month;
|
688
|
+
}
|
689
|
+
|
690
|
+
/* Return the julian date of the first day of the
|
691
|
+
* given year. */
|
692
|
+
long rhrd__yday1_jd(long year) {
|
693
|
+
rhrd_t d;
|
694
|
+
|
695
|
+
memset(&d, 0, sizeof(rhrd_t));
|
696
|
+
d.year = year;
|
697
|
+
d.month = 1;
|
698
|
+
d.day = 1;
|
699
|
+
d.flags = RHR_HAVE_CIVIL;
|
700
|
+
RHR_FILL_JD(&d);
|
701
|
+
|
702
|
+
return d.jd;
|
703
|
+
}
|
704
|
+
|
705
|
+
/* Convert the given julian date to a week number given that
|
706
|
+
* f is a number representing a week day (Sunday = 0) such that
|
707
|
+
* the week 1 of the year starts on first week day of that year
|
708
|
+
* (with days before then as week 0).
|
709
|
+
* So if January 1st is a Monday and f = 1, January 1-7 would be
|
710
|
+
* in week 1. However, if f = 0, January 1-6 would be in week 0,
|
711
|
+
* and January 7-13 would be in week 1. */
|
712
|
+
long rhrd__jd_to_weeknum(long jd, int f) {
|
713
|
+
long yday1_jd;
|
714
|
+
rhrd_t d;
|
715
|
+
|
716
|
+
memset(&d, 0, sizeof(rhrd_t));
|
717
|
+
d.jd = jd;
|
718
|
+
d.flags = RHR_HAVE_JD;
|
719
|
+
RHR_FILL_CIVIL(&d)
|
720
|
+
|
721
|
+
yday1_jd = rhrd__yday1_jd(d.year) + 6;
|
722
|
+
return (jd - (yday1_jd - (rhrd__mod(yday1_jd - f + 1, 7) + 7))) / 7;
|
723
|
+
}
|
724
|
+
|
725
|
+
/* Convert a given week number and week day to a julian day given
|
726
|
+
* that f means the same as it does in the prior function. */
|
727
|
+
long rhrd__weeknum_to_jd(long year, long week, long wday, int f) {
|
728
|
+
long yday1_jd;
|
729
|
+
yday1_jd = rhrd__yday1_jd(year) + 6;
|
730
|
+
return (yday1_jd - rhrd__mod(yday1_jd - f + 1, 7) - 7) + 7 * week + wday;
|
731
|
+
}
|
732
|
+
|
733
|
+
/* Using the values in the given ruby hash, fill the appropriate date fields
|
734
|
+
* in the given rhrd_t. Returns:
|
735
|
+
* 0: No errors (i.e. jd and/or year, month, day filled)
|
736
|
+
* 1: Bad date information given (e.g. 2009-02-29)
|
737
|
+
* -1: No date information given */
|
738
|
+
int rhrd__fill_from_hash(rhrd_t *d, VALUE hash) {
|
739
|
+
long year = 0;
|
740
|
+
long month = 0;
|
741
|
+
long day = 0;
|
742
|
+
long yday = 0;
|
743
|
+
long wday = 0;
|
744
|
+
long cwyear = 0;
|
745
|
+
long cweek = 0;
|
746
|
+
long cwday = 0;
|
747
|
+
VALUE ryear, rmonth, rday, ryday, rwday, rcwyear, rcweek, rcwday, runix, rwnum0, rwnum1;
|
748
|
+
|
749
|
+
if (!RTEST(hash)) {
|
750
|
+
return -1;
|
751
|
+
}
|
752
|
+
runix = rb_hash_aref(hash, rhrd_sym_seconds);
|
753
|
+
if (RTEST(runix)) {
|
754
|
+
d->jd = rhrd__unix_to_jd(NUM2LL(runix));
|
755
|
+
d->flags |= RHR_HAVE_JD;
|
756
|
+
return 0;
|
757
|
+
}
|
758
|
+
|
759
|
+
ryear = rb_hash_aref(hash, rhrd_sym_year);
|
760
|
+
rmonth = rb_hash_aref(hash, rhrd_sym_mon);
|
761
|
+
rday = rb_hash_aref(hash, rhrd_sym_mday);
|
762
|
+
ryday = rb_hash_aref(hash, rhrd_sym_yday);
|
763
|
+
rwday = rb_hash_aref(hash, rhrd_sym_wday);
|
764
|
+
rcwyear = rb_hash_aref(hash, rhrd_sym_cwyear);
|
765
|
+
rcweek = rb_hash_aref(hash, rhrd_sym_cweek);
|
766
|
+
rcwday = rb_hash_aref(hash, rhrd_sym_cwday);
|
767
|
+
rwnum0 = rb_hash_aref(hash, rhrd_sym_wnum0);
|
768
|
+
rwnum1 = rb_hash_aref(hash, rhrd_sym_wnum1);
|
769
|
+
|
770
|
+
if (RTEST(ryear)) {
|
771
|
+
year = NUM2LONG(ryear);
|
772
|
+
if (RTEST(ryday)) {
|
773
|
+
yday = NUM2LONG(ryday);
|
774
|
+
} else if (RTEST(rmonth) && RTEST(rday)) {
|
775
|
+
month = NUM2LONG(rmonth);
|
776
|
+
day = NUM2LONG(rday);
|
777
|
+
} else if (RTEST(rwday)) {
|
778
|
+
d->jd = rhrd__yday1_jd(year);
|
779
|
+
d->flags |= RHR_HAVE_JD;
|
780
|
+
rhrd__fill_commercial(d);
|
781
|
+
if(!rhrd__valid_commercial(d, d->year, 1, NUM2LONG(rwday))) {
|
782
|
+
return 1;
|
783
|
+
}
|
784
|
+
d->flags &= ~RHR_HAVE_CIVIL;
|
785
|
+
return 0;
|
786
|
+
} else if (RTEST(rwnum0)) {
|
787
|
+
d->jd = rhrd__weeknum_to_jd(year, NUM2LONG(rwnum0), RTEST(rwday) ? NUM2LONG(rwday) : (RTEST(rcwday) ? rhrd__mod(NUM2LONG(rcwday), 7) : 0), 0);
|
788
|
+
d->flags |= RHR_HAVE_JD;
|
789
|
+
return 0;
|
790
|
+
} else if (RTEST(rwnum1)) {
|
791
|
+
d->jd = rhrd__weeknum_to_jd(year, NUM2LONG(rwnum1), RTEST(rwday) ? rhrd__mod(NUM2LONG(rwday) - 1, 7) : (RTEST(rcwday) ? rhrd__mod(NUM2LONG(rcwday) - 1, 7) : 0), 1);
|
792
|
+
d->flags |= RHR_HAVE_JD;
|
793
|
+
return 0;
|
794
|
+
} else {
|
795
|
+
month = RTEST(rmonth) ? NUM2LONG(rmonth) : 1;
|
796
|
+
day = RTEST(rday) ? NUM2LONG(rday) : 1;
|
797
|
+
}
|
798
|
+
} else if (RTEST(rmonth)) {
|
799
|
+
year = rhrd__current_year();
|
800
|
+
month = NUM2LONG(rmonth);
|
801
|
+
day = RTEST(rday) ? NUM2LONG(rday) : 1;
|
802
|
+
} else if (RTEST(rday)) {
|
803
|
+
year = rhrd__current_year();
|
804
|
+
month = rhrd__current_month();
|
805
|
+
day = NUM2LONG(rday);
|
806
|
+
} else if (RTEST(ryday)) {
|
807
|
+
year = rhrd__current_year();
|
808
|
+
yday = NUM2LONG(ryday);
|
809
|
+
} else if (RTEST(rwnum0)) {
|
810
|
+
d->jd = rhrd__weeknum_to_jd(rhrd__current_year(), NUM2LONG(rwnum0), RTEST(rwday) ? NUM2LONG(rwday) : (RTEST(rcwday) ? rhrd__mod(NUM2LONG(rcwday), 7) : 0), 0);
|
811
|
+
d->flags |= RHR_HAVE_JD;
|
812
|
+
return 0;
|
813
|
+
} else if (RTEST(rwnum1)) {
|
814
|
+
d->jd = rhrd__weeknum_to_jd(rhrd__current_year(), NUM2LONG(rwnum1), RTEST(rwday) ? rhrd__mod(NUM2LONG(rwday) - 1, 7) : (RTEST(rcwday) ? rhrd__mod(NUM2LONG(rcwday) - 1, 7) : 0), 1);
|
815
|
+
d->flags |= RHR_HAVE_JD;
|
816
|
+
return 0;
|
817
|
+
} else if (RTEST(rcwyear)) {
|
818
|
+
cwyear = NUM2LONG(rcwyear);
|
819
|
+
cweek = RTEST(rcweek) ? NUM2LONG(rcweek) : 1;
|
820
|
+
cwday = RTEST(rcwday) ? NUM2LONG(rcwday) : 1;
|
821
|
+
} else if (RTEST(rcweek)) {
|
822
|
+
cwyear = rhrd__current_year();
|
823
|
+
cweek = NUM2LONG(rcweek);
|
824
|
+
cwday = RTEST(rcwday) ? NUM2LONG(rcwday) : 1;
|
825
|
+
} else if (RTEST(rcwday)) {
|
826
|
+
cwyear = rhrd__current_year();
|
827
|
+
cweek = 1;
|
828
|
+
cwday = NUM2LONG(rcwday);
|
829
|
+
} else if (RTEST(rwday)) {
|
830
|
+
wday = NUM2LONG(rwday);
|
831
|
+
rhrd__today(d);
|
832
|
+
d->jd += wday - rhrd__jd_to_wday(d->jd);
|
833
|
+
d->flags &= ~RHR_HAVE_CIVIL;
|
834
|
+
return 0;
|
835
|
+
} else {
|
836
|
+
return -1;
|
837
|
+
}
|
838
|
+
if (yday && rhrd__valid_ordinal(d, year, yday)) {
|
839
|
+
return 0;
|
840
|
+
} else if (cweek && cwday && rhrd__valid_commercial(d, cwyear, cweek, cwday)) {
|
841
|
+
return 0;
|
842
|
+
} else if (!rhrd__valid_civil(d, year, month, day)) {
|
843
|
+
return 1;
|
844
|
+
}
|
845
|
+
|
846
|
+
return 0;
|
847
|
+
}
|
848
|
+
|
849
|
+
/* Returns a new ruby object filled with information from
|
850
|
+
* the given hash, or raises an error if the given hash
|
851
|
+
* did not contain valid date information. */
|
852
|
+
VALUE rhrd__from_hash(VALUE hash) {
|
853
|
+
rhrd_t *d;
|
854
|
+
VALUE rd = Data_Make_Struct(rhrd_class, rhrd_t, NULL, free, d);
|
855
|
+
if(rhrd__fill_from_hash(d, hash)) {
|
856
|
+
rb_raise(rb_eArgError, "invalid date");
|
857
|
+
} else {
|
858
|
+
RHR_FILL_JD(d)
|
859
|
+
RHR_CHECK_JD(d)
|
860
|
+
return rd;
|
861
|
+
}
|
862
|
+
}
|
863
|
+
|
864
|
+
/* Return a ruby string using the information in the given
|
865
|
+
* rhrdt_t and the given format string information. */
|
866
|
+
VALUE rhrd__strftime(rhrdt_t *d, const char * fmt, int fmt_len) {
|
867
|
+
int i;
|
868
|
+
int cp = 0;
|
869
|
+
int str_len = 128;
|
870
|
+
int str_lim = 64;
|
871
|
+
int mod = 0;
|
872
|
+
char * str;
|
873
|
+
char c;
|
874
|
+
VALUE s;
|
875
|
+
rhrd_t cd;
|
876
|
+
|
877
|
+
memset(&cd, 0, sizeof(rhrd_t));
|
878
|
+
cd.jd = d->jd;
|
879
|
+
cd.flags = RHR_HAVE_JD;
|
880
|
+
rhrd__fill_commercial(&cd);
|
881
|
+
|
882
|
+
s = rb_str_buf_new(str_len);
|
883
|
+
str = RSTRING_PTR(s);
|
884
|
+
for (i = 0; i < fmt_len; i++) {
|
885
|
+
if (cp >= str_lim) {
|
886
|
+
str_len *= 2;
|
887
|
+
str_lim = str_len - 64;
|
888
|
+
#ifndef RUBY186
|
889
|
+
rb_str_set_len(s, cp);
|
890
|
+
#endif
|
891
|
+
s = rb_str_resize(s, str_len);
|
892
|
+
str = RSTRING_PTR(s);
|
893
|
+
}
|
894
|
+
c = fmt[i];
|
895
|
+
|
896
|
+
if (mod) {
|
897
|
+
switch (c) {
|
898
|
+
case 'a':
|
899
|
+
cp += sprintf(str + cp, "%s", rhrd__abbr_day_names[rhrd__jd_to_wday(d->jd)]);
|
900
|
+
break;
|
901
|
+
case 'A':
|
902
|
+
cp += sprintf(str + cp, "%s", rhrd__day_names[rhrd__jd_to_wday(d->jd)]);
|
903
|
+
break;
|
904
|
+
case 'h':
|
905
|
+
case 'b':
|
906
|
+
cp += sprintf(str + cp, "%s", rhrd__abbr_month_names[d->month]);
|
907
|
+
break;
|
908
|
+
case 'B':
|
909
|
+
cp += sprintf(str + cp, "%s", rhrd__month_names[d->month]);
|
910
|
+
break;
|
911
|
+
case 'c':
|
912
|
+
cp += sprintf(str + cp, "%s %s %2hhi %02hhi:%02hhi:%02hhi %04li", rhrd__abbr_day_names[rhrd__jd_to_wday(d->jd)], rhrd__abbr_month_names[d->month], d->day, d->hour, d->minute, d->second, d->year);
|
913
|
+
break;
|
914
|
+
case 'C':
|
915
|
+
cp += sprintf(str + cp, "%02li", d->year / 100);
|
916
|
+
break;
|
917
|
+
case 'd':
|
918
|
+
cp += sprintf(str + cp, "%02hhi", d->day);
|
919
|
+
break;
|
920
|
+
case 'e':
|
921
|
+
cp += sprintf(str + cp, "%2hhi", d->day);
|
922
|
+
break;
|
923
|
+
case 'F':
|
924
|
+
cp += sprintf(str + cp, "%04li-%02hhi-%02hhi", d->year, d->month, d->day);
|
925
|
+
break;
|
926
|
+
case 'g':
|
927
|
+
cp += sprintf(str + cp, "%02li", cd.year % 100);
|
928
|
+
break;
|
929
|
+
case 'G':
|
930
|
+
cp += sprintf(str + cp, "%04li", cd.year);
|
931
|
+
break;
|
932
|
+
case 'H':
|
933
|
+
cp += sprintf(str + cp, "%02hhi", d->hour);
|
934
|
+
break;
|
935
|
+
case 'I':
|
936
|
+
cp += sprintf(str + cp, "%02hhi", (d->hour == 12 || d->hour == 0) ? 12 : d->hour % 12);
|
937
|
+
break;
|
938
|
+
case 'j':
|
939
|
+
cp += sprintf(str + cp, "%03li", rhrd__ordinal_day(d->year, d->month, d->day));
|
940
|
+
break;
|
941
|
+
case 'k':
|
942
|
+
cp += sprintf(str + cp, "%2hhi", d->hour);
|
943
|
+
break;
|
944
|
+
case 'l':
|
945
|
+
cp += sprintf(str + cp, "%2hhi", (d->hour == 12 || d->hour == 0) ? 12 : d->hour % 12);
|
946
|
+
break;
|
947
|
+
case 'L':
|
948
|
+
cp += sprintf(str + cp, "%03" PRId64, (d->nanos % RHR_NANOS_PER_SECOND)/1000000);
|
949
|
+
break;
|
950
|
+
case 'm':
|
951
|
+
cp += sprintf(str + cp, "%02hhi", d->month);
|
952
|
+
break;
|
953
|
+
case 'M':
|
954
|
+
cp += sprintf(str + cp, "%02hhi", d->minute);
|
955
|
+
break;
|
956
|
+
case 'N':
|
957
|
+
cp += sprintf(str + cp, "%09" PRId64, (d->nanos % RHR_NANOS_PER_SECOND));
|
958
|
+
break;
|
959
|
+
case 'n':
|
960
|
+
cp += sprintf(str + cp, "\n");
|
961
|
+
break;
|
962
|
+
case 'p':
|
963
|
+
cp += sprintf(str + cp, d->hour >= 12 ? "PM" : "AM");
|
964
|
+
break;
|
965
|
+
case 'P':
|
966
|
+
cp += sprintf(str + cp, d->hour >= 12 ? "pm" : "am");
|
967
|
+
break;
|
968
|
+
case 'Q':
|
969
|
+
cp += sprintf(str + cp, "%" PRId64, rhrd__jd_to_unix(d->jd) * 1000 + d->nanos/RHR_NANOS_PER_MILLISECOND - d->offset * 60000);
|
970
|
+
break;
|
971
|
+
case 'r':
|
972
|
+
cp += sprintf(str + cp, "%2hhi:%02hhi:%02hhi %s", (d->hour == 12 || d->hour == 0) ? 12 : d->hour % 12, d->minute, d->second, d->hour >= 12 ? "PM" : "AM");
|
973
|
+
break;
|
974
|
+
case 'R':
|
975
|
+
cp += sprintf(str + cp, "%02hhi:%02hhi", d->hour, d->minute);
|
976
|
+
break;
|
977
|
+
case 's':
|
978
|
+
cp += sprintf(str + cp, "%" PRId64, rhrd__jd_to_unix(d->jd) + d->nanos/RHR_NANOS_PER_SECOND - d->offset * 60);
|
979
|
+
break;
|
980
|
+
case 'S':
|
981
|
+
cp += sprintf(str + cp, "%02hhi", d->second);
|
982
|
+
break;
|
983
|
+
case 't':
|
984
|
+
cp += sprintf(str + cp, "\t");
|
985
|
+
break;
|
986
|
+
case 'X':
|
987
|
+
case 'T':
|
988
|
+
cp += sprintf(str + cp, "%02hhi:%02hhi:%02hhi", d->hour, d->minute, d->second);
|
989
|
+
break;
|
990
|
+
case 'u':
|
991
|
+
cp += sprintf(str + cp, "%hhi", cd.day);
|
992
|
+
break;
|
993
|
+
case 'U':
|
994
|
+
cp += sprintf(str + cp, "%li", rhrd__jd_to_weeknum(d->jd, 0));
|
995
|
+
break;
|
996
|
+
case 'v':
|
997
|
+
cp += sprintf(str + cp, "%2hhi-%s-%04li", d->day, rhrd__abbr_month_names[d->month], d->year);
|
998
|
+
break;
|
999
|
+
case 'V':
|
1000
|
+
cp += sprintf(str + cp, "%02hhi", cd.month);
|
1001
|
+
break;
|
1002
|
+
case 'w':
|
1003
|
+
cp += sprintf(str + cp, "%li", rhrd__jd_to_wday(d->jd));
|
1004
|
+
break;
|
1005
|
+
case 'W':
|
1006
|
+
cp += sprintf(str + cp, "%li", rhrd__jd_to_weeknum(d->jd, 1));
|
1007
|
+
break;
|
1008
|
+
case 'D':
|
1009
|
+
case 'x':
|
1010
|
+
cp += sprintf(str + cp, "%02hhi/%02hhi/%02li", d->month, d->day, d->year % 100);
|
1011
|
+
break;
|
1012
|
+
case 'y':
|
1013
|
+
cp += sprintf(str + cp, "%02li", d->year % 100);
|
1014
|
+
break;
|
1015
|
+
case 'Y':
|
1016
|
+
cp += sprintf(str + cp, "%04li", d->year);
|
1017
|
+
break;
|
1018
|
+
case 'z':
|
1019
|
+
cp += sprintf(str + cp, "%+03i%02i", d->offset/60, abs(d->offset % 60));
|
1020
|
+
break;
|
1021
|
+
case 'Z':
|
1022
|
+
cp += sprintf(str + cp, "%+03i:%02i", d->offset/60, abs(d->offset % 60));
|
1023
|
+
break;
|
1024
|
+
case '+':
|
1025
|
+
cp += sprintf(str + cp, "%s %s %2hhi %02hhi:%02hhi:%02hhi %+03i:%02i %04li", rhrd__abbr_day_names[rhrd__jd_to_wday(d->jd)], rhrd__abbr_month_names[d->month], d->day, d->hour, d->minute, d->second, d->offset/60, abs(d->offset % 60), d->year);
|
1026
|
+
break;
|
1027
|
+
default:
|
1028
|
+
str[cp] = c;
|
1029
|
+
cp += 1;
|
1030
|
+
}
|
1031
|
+
mod = 0;
|
1032
|
+
} else {
|
1033
|
+
if (c == '%') {
|
1034
|
+
mod = 1;
|
1035
|
+
} else {
|
1036
|
+
str[cp] = c;
|
1037
|
+
cp += 1;
|
1038
|
+
}
|
1039
|
+
}
|
1040
|
+
}
|
1041
|
+
|
1042
|
+
RHR_RETURN_RESIZED_STR(s, cp)
|
1043
|
+
}
|
1044
|
+
|
1045
|
+
/* Return a ruby hash using the given ruby string and the format
|
1046
|
+
* string information. */
|
1047
|
+
VALUE rhrd__strptime(VALUE rstr, const char *fmt_str, long fmt_len) {
|
1048
|
+
char * str;
|
1049
|
+
long len;
|
1050
|
+
long year = 0;
|
1051
|
+
long month = 0;
|
1052
|
+
long day = 0;
|
1053
|
+
long yday = 0;
|
1054
|
+
long wday = 0;
|
1055
|
+
long cwyear = 0;
|
1056
|
+
long cweek = 0;
|
1057
|
+
long cwday = 0;
|
1058
|
+
long century = 0;
|
1059
|
+
long hour = 0;
|
1060
|
+
long minute = 0;
|
1061
|
+
long second = 0;
|
1062
|
+
long long seconds = 0;
|
1063
|
+
long long milliseconds = 0;
|
1064
|
+
long sec_fraction_num = 0;
|
1065
|
+
double sec_fraction = 0.0;
|
1066
|
+
long meridian = 0;
|
1067
|
+
long state = 0;
|
1068
|
+
long mod = 0;
|
1069
|
+
long pos = 0;
|
1070
|
+
long wnum0 = 0;
|
1071
|
+
long wnum1 = 0;
|
1072
|
+
long i;
|
1073
|
+
long fmt_pos;
|
1074
|
+
int scan_len;
|
1075
|
+
VALUE zone = Qnil;
|
1076
|
+
VALUE hash;
|
1077
|
+
rstr = rb_str_to_str(rstr);
|
1078
|
+
str = RSTRING_PTR(rstr);
|
1079
|
+
len = RSTRING_LEN(rstr);
|
1080
|
+
|
1081
|
+
for (fmt_pos = 0; fmt_pos < fmt_len; fmt_pos++) {
|
1082
|
+
if (pos >= len) {
|
1083
|
+
#ifdef DEBUG
|
1084
|
+
printf("format longer than input\n");
|
1085
|
+
#endif
|
1086
|
+
return Qnil;
|
1087
|
+
}
|
1088
|
+
if (mod) {
|
1089
|
+
scan_len = 0;
|
1090
|
+
switch (fmt_str[fmt_pos]) {
|
1091
|
+
case 'a':
|
1092
|
+
#define RHR_PARSE_a if (pos + 3 > len) {\
|
1093
|
+
return Qnil;\
|
1094
|
+
}\
|
1095
|
+
for(i = 0; i < 7; i++) {\
|
1096
|
+
if(strncasecmp(str + pos, rhrd__abbr_day_names[i], 3) == 0) {\
|
1097
|
+
wday = i;\
|
1098
|
+
break;\
|
1099
|
+
}\
|
1100
|
+
}\
|
1101
|
+
if (i >= 7) {\
|
1102
|
+
return Qnil;\
|
1103
|
+
}\
|
1104
|
+
scan_len = 3;\
|
1105
|
+
state |= RHRR_WDAY_SET;
|
1106
|
+
RHR_PARSE_a
|
1107
|
+
break;
|
1108
|
+
case 'A':
|
1109
|
+
for(i = 0; i < 7; i++) {
|
1110
|
+
scan_len = strlen(rhrd__day_names[i]);
|
1111
|
+
if (pos + scan_len <= len) {
|
1112
|
+
if(strncasecmp(str + pos, rhrd__day_names[i], scan_len) == 0) {
|
1113
|
+
wday = i;
|
1114
|
+
break;
|
1115
|
+
}
|
1116
|
+
}
|
1117
|
+
}
|
1118
|
+
if (i >= 7) {
|
1119
|
+
return Qnil;
|
1120
|
+
}
|
1121
|
+
state |= RHRR_WDAY_SET;
|
1122
|
+
break;
|
1123
|
+
case 'h':
|
1124
|
+
case 'b':
|
1125
|
+
#define RHR_PARSE_b if (pos + 3 > len) {\
|
1126
|
+
return Qnil;\
|
1127
|
+
}\
|
1128
|
+
for(i = 1; i < 13; i++) {\
|
1129
|
+
if(strncasecmp(str + pos, rhrd__abbr_month_names[i], 3) == 0) {\
|
1130
|
+
month = i;\
|
1131
|
+
break;\
|
1132
|
+
}\
|
1133
|
+
}\
|
1134
|
+
if (i >= 13) {\
|
1135
|
+
return Qnil;\
|
1136
|
+
}\
|
1137
|
+
scan_len = 3;\
|
1138
|
+
state |= RHRR_MONTH_SET;
|
1139
|
+
RHR_PARSE_b
|
1140
|
+
break;
|
1141
|
+
case 'B':
|
1142
|
+
for(i = 1; i < 13; i++) {
|
1143
|
+
scan_len = strlen(rhrd__month_names[i]);
|
1144
|
+
if (pos + scan_len <= len) {
|
1145
|
+
if(strncasecmp(str + pos, rhrd__month_names[i], scan_len) == 0) {
|
1146
|
+
month = i;
|
1147
|
+
break;
|
1148
|
+
}
|
1149
|
+
}
|
1150
|
+
}
|
1151
|
+
if (i >= 13) {
|
1152
|
+
return Qnil;
|
1153
|
+
}
|
1154
|
+
state |= RHRR_MONTH_SET;
|
1155
|
+
break;
|
1156
|
+
case 'C':
|
1157
|
+
if (sscanf(str + pos, "%2ld%n", ¢ury, &scan_len) != 1) {
|
1158
|
+
return Qnil;
|
1159
|
+
}
|
1160
|
+
state |= RHRR_CENTURY_SET;
|
1161
|
+
break;
|
1162
|
+
case 'e':
|
1163
|
+
case 'd':
|
1164
|
+
#define RHR_PARSE_d if (sscanf(str + pos, "%02ld%n", &day, &scan_len) != 1) {\
|
1165
|
+
return Qnil;\
|
1166
|
+
}\
|
1167
|
+
if (day < 1 || day > 31) {\
|
1168
|
+
return Qnil;\
|
1169
|
+
}\
|
1170
|
+
state |= RHRR_DAY_SET;
|
1171
|
+
RHR_PARSE_d
|
1172
|
+
break;
|
1173
|
+
case 'g':
|
1174
|
+
if (sscanf(str + pos, "%02ld%n", &cwyear, &scan_len) != 1) {
|
1175
|
+
return Qnil;
|
1176
|
+
}
|
1177
|
+
if (!(state & RHRR_CENTURY_SET)) {
|
1178
|
+
century = cwyear < 69 ? 20 : 19;
|
1179
|
+
}
|
1180
|
+
state |= RHRR_CWYEAR_SET | RHRR_CENTURY_SET;
|
1181
|
+
break;
|
1182
|
+
case 'G':
|
1183
|
+
if (sscanf(str + pos, "%ld%n", &cwyear, &scan_len) != 1) {
|
1184
|
+
return Qnil;
|
1185
|
+
}
|
1186
|
+
state |= RHRR_CWYEAR_SET + RHRR_CENTURY_SET;
|
1187
|
+
break;
|
1188
|
+
case 'k':
|
1189
|
+
case 'H':
|
1190
|
+
#define RHR_PARSE_H if (sscanf(str + pos, "%02ld%n", &hour, &scan_len) != 1) {\
|
1191
|
+
return Qnil;\
|
1192
|
+
}\
|
1193
|
+
if (hour < 0 || hour > 24) {\
|
1194
|
+
return Qnil;\
|
1195
|
+
}\
|
1196
|
+
state |= RHRR_HOUR_SET;
|
1197
|
+
RHR_PARSE_H
|
1198
|
+
break;
|
1199
|
+
case 'l':
|
1200
|
+
case 'I':
|
1201
|
+
#define RHR_PARSE_I if (sscanf(str + pos, "%02ld%n", &hour, &scan_len) != 1) {\
|
1202
|
+
return Qnil;\
|
1203
|
+
}\
|
1204
|
+
if (hour < 1 || hour > 12) {\
|
1205
|
+
return Qnil;\
|
1206
|
+
}\
|
1207
|
+
state |= RHRR_HOUR_SET;
|
1208
|
+
RHR_PARSE_I
|
1209
|
+
break;
|
1210
|
+
case 'j':
|
1211
|
+
if (sscanf(str + pos, "%03ld%n", &yday, &scan_len) != 1) {
|
1212
|
+
return Qnil;
|
1213
|
+
}
|
1214
|
+
if (yday < 1 || yday > 366) {
|
1215
|
+
return Qnil;
|
1216
|
+
}
|
1217
|
+
state |= RHRR_YDAY_SET;
|
1218
|
+
break;
|
1219
|
+
case 'L':
|
1220
|
+
if (sscanf(str + pos, "%03ld%n", &sec_fraction_num, &scan_len) != 1) {
|
1221
|
+
return Qnil;
|
1222
|
+
}
|
1223
|
+
sec_fraction = sec_fraction_num/pow(10, scan_len);
|
1224
|
+
state |= RHRR_SEC_FRACTION_SET;
|
1225
|
+
break;
|
1226
|
+
case 'm':
|
1227
|
+
#define RHR_PARSE_m if (sscanf(str + pos, "%02ld%n", &month, &scan_len) != 1) {\
|
1228
|
+
return Qnil;\
|
1229
|
+
}\
|
1230
|
+
if (month < 1 || month > 12) {\
|
1231
|
+
return Qnil;\
|
1232
|
+
}\
|
1233
|
+
state |= RHRR_MONTH_SET;
|
1234
|
+
RHR_PARSE_m
|
1235
|
+
break;
|
1236
|
+
case 'M':
|
1237
|
+
#define RHR_PARSE_M if (sscanf(str + pos, "%02ld%n", &minute, &scan_len) != 1) {\
|
1238
|
+
return Qnil;\
|
1239
|
+
}\
|
1240
|
+
if (minute < 0 || minute > 59) {\
|
1241
|
+
return Qnil;\
|
1242
|
+
}\
|
1243
|
+
state |= RHRR_MINUTE_SET;
|
1244
|
+
RHR_PARSE_M
|
1245
|
+
break;
|
1246
|
+
case 'n':
|
1247
|
+
if (str[pos] != '\n') {
|
1248
|
+
return Qnil;
|
1249
|
+
}
|
1250
|
+
pos++;
|
1251
|
+
break;
|
1252
|
+
case 'N':
|
1253
|
+
if (sscanf(str + pos, "%09ld%n", &sec_fraction_num, &scan_len) != 1) {
|
1254
|
+
return Qnil;
|
1255
|
+
}
|
1256
|
+
sec_fraction = sec_fraction_num/pow(10, scan_len);
|
1257
|
+
state |= RHRR_SEC_FRACTION_SET;
|
1258
|
+
break;
|
1259
|
+
case 'P':
|
1260
|
+
case 'p':
|
1261
|
+
#define RHR_PARSE_p if (!(str[pos] == 'a' || str[pos] == 'A' ||\
|
1262
|
+
str[pos] == 'p' || str[pos] == 'P')) {\
|
1263
|
+
return Qnil;\
|
1264
|
+
} else {\
|
1265
|
+
state |= RHRR_MERIDIAN_SET;\
|
1266
|
+
meridian = str[pos] == 'p' || str[pos] == 'P';\
|
1267
|
+
}\
|
1268
|
+
if (pos + 2 <= len) {\
|
1269
|
+
if (!(str[pos + 1] == 'M' || str[pos + 1] == 'm')) {\
|
1270
|
+
if (pos + 4 <= len) {\
|
1271
|
+
if (!((str[pos + 2] == 'M' || str[pos + 2] == 'm') &&\
|
1272
|
+
str[pos + 1] == '.' && str[pos + 3] == '.')) {\
|
1273
|
+
return Qnil;\
|
1274
|
+
}\
|
1275
|
+
} else {\
|
1276
|
+
return Qnil;\
|
1277
|
+
}\
|
1278
|
+
}\
|
1279
|
+
} else {\
|
1280
|
+
return Qnil;\
|
1281
|
+
}
|
1282
|
+
RHR_PARSE_p
|
1283
|
+
break;
|
1284
|
+
case 'Q':
|
1285
|
+
if (sscanf(str + pos, "%" SCNd64 "%n", &milliseconds, &scan_len) != 1) {
|
1286
|
+
return Qnil;
|
1287
|
+
}
|
1288
|
+
state |= RHRR_UNIXM_SET;
|
1289
|
+
break;
|
1290
|
+
case 's':
|
1291
|
+
if (sscanf(str + pos, "%" SCNd64 "%n", &seconds, &scan_len) != 1) {
|
1292
|
+
return Qnil;
|
1293
|
+
}
|
1294
|
+
state |= RHRR_UNIX_SET;
|
1295
|
+
break;
|
1296
|
+
case 'S':
|
1297
|
+
#define RHR_PARSE_S if (sscanf(str + pos, "%02ld%n", &second, &scan_len) != 1) {\
|
1298
|
+
return Qnil;\
|
1299
|
+
}\
|
1300
|
+
if (second < 0 || second > 59) {\
|
1301
|
+
return Qnil;\
|
1302
|
+
}\
|
1303
|
+
state |= RHRR_SECOND_SET;
|
1304
|
+
RHR_PARSE_S
|
1305
|
+
break;
|
1306
|
+
case 't':
|
1307
|
+
if (str[pos] != '\t') {
|
1308
|
+
return Qnil;
|
1309
|
+
}
|
1310
|
+
pos++;
|
1311
|
+
break;
|
1312
|
+
case 'u':
|
1313
|
+
if (sscanf(str + pos, "%02ld%n", &cwday, &scan_len) != 1) {
|
1314
|
+
return Qnil;
|
1315
|
+
}
|
1316
|
+
if (cwday < 1 || cwday > 7) {
|
1317
|
+
return Qnil;
|
1318
|
+
}
|
1319
|
+
state |= RHRR_CWDAY_SET;
|
1320
|
+
break;
|
1321
|
+
case 'U':
|
1322
|
+
if (sscanf(str + pos, "%02ld%n", &wnum0, &scan_len) != 1) {
|
1323
|
+
return Qnil;
|
1324
|
+
}
|
1325
|
+
if (wnum0 < 0 || wnum0 > 53) {
|
1326
|
+
return Qnil;
|
1327
|
+
}
|
1328
|
+
state |= RHRR_WNUM0_SET;
|
1329
|
+
break;
|
1330
|
+
case 'V':
|
1331
|
+
if (sscanf(str + pos, "%02ld%n", &cweek, &scan_len) != 1) {
|
1332
|
+
return Qnil;
|
1333
|
+
}
|
1334
|
+
if (cweek < 1 || cweek > 53) {
|
1335
|
+
return Qnil;
|
1336
|
+
}
|
1337
|
+
state |= RHRR_CWEEK_SET;
|
1338
|
+
break;
|
1339
|
+
case 'w':
|
1340
|
+
if (sscanf(str + pos, "%02ld%n", &wday, &scan_len) != 1) {
|
1341
|
+
return Qnil;
|
1342
|
+
}
|
1343
|
+
if (wday < 0 || wday > 6) {
|
1344
|
+
return Qnil;
|
1345
|
+
}
|
1346
|
+
state |= RHRR_WDAY_SET;
|
1347
|
+
break;
|
1348
|
+
case 'W':
|
1349
|
+
if (sscanf(str + pos, "%02ld%n", &wnum1, &scan_len) != 1) {
|
1350
|
+
return Qnil;
|
1351
|
+
}
|
1352
|
+
if (wnum1 < 0 || wnum1 > 53) {
|
1353
|
+
return Qnil;
|
1354
|
+
}
|
1355
|
+
state |= RHRR_WNUM1_SET;
|
1356
|
+
break;
|
1357
|
+
case 'y':
|
1358
|
+
#define RHR_PARSE_y if (sscanf(str + pos, "%02ld%n", &year, &scan_len) != 1) {\
|
1359
|
+
return Qnil;\
|
1360
|
+
}\
|
1361
|
+
if (!(state & RHRR_CENTURY_SET)) {\
|
1362
|
+
century = year < 69 ? 20 : 19;\
|
1363
|
+
}\
|
1364
|
+
state |= RHRR_YEAR_SET | RHRR_CENTURY_SET;
|
1365
|
+
RHR_PARSE_y
|
1366
|
+
break;
|
1367
|
+
case 'Y':
|
1368
|
+
#define RHR_PARSE_Y if (sscanf(str + pos, "%ld%n", &year, &scan_len) != 1) {\
|
1369
|
+
return Qnil;\
|
1370
|
+
}\
|
1371
|
+
state |= RHRR_YEAR_SET + RHRR_CENTURY_SET;
|
1372
|
+
RHR_PARSE_Y
|
1373
|
+
break;
|
1374
|
+
case 'z':
|
1375
|
+
case 'Z':
|
1376
|
+
#define RHR_PARSE_Z zone = rb_funcall(rhrd_zone_re, rhrd_id_match, 1, rb_funcall(rstr, rhrd_id_slice, 2, LONG2NUM(pos), LONG2NUM(len)));\
|
1377
|
+
if (RTEST(zone)) {\
|
1378
|
+
zone = rb_funcall(zone, rhrd_id_op_array, 1, LONG2NUM(0));\
|
1379
|
+
scan_len = NUM2LONG(rb_funcall(zone, rhrd_id_length, 0));\
|
1380
|
+
} else {\
|
1381
|
+
return Qnil;\
|
1382
|
+
}
|
1383
|
+
RHR_PARSE_Z
|
1384
|
+
break;
|
1385
|
+
/* Composite formats */
|
1386
|
+
#define RHR_PARSE_sep(x) pos += scan_len;\
|
1387
|
+
scan_len = 0;\
|
1388
|
+
if (str[pos] != x) {\
|
1389
|
+
return Qnil;\
|
1390
|
+
}\
|
1391
|
+
pos++;
|
1392
|
+
case 'c':
|
1393
|
+
RHR_PARSE_a
|
1394
|
+
RHR_PARSE_sep(' ')
|
1395
|
+
RHR_PARSE_b
|
1396
|
+
RHR_PARSE_sep(' ')
|
1397
|
+
RHR_PARSE_d
|
1398
|
+
RHR_PARSE_sep(' ')
|
1399
|
+
RHR_PARSE_H
|
1400
|
+
RHR_PARSE_sep(':')
|
1401
|
+
RHR_PARSE_M
|
1402
|
+
RHR_PARSE_sep(':')
|
1403
|
+
RHR_PARSE_S
|
1404
|
+
RHR_PARSE_sep(' ')
|
1405
|
+
RHR_PARSE_Y
|
1406
|
+
break;
|
1407
|
+
case 'x':
|
1408
|
+
case 'D':
|
1409
|
+
RHR_PARSE_m
|
1410
|
+
RHR_PARSE_sep('/')
|
1411
|
+
RHR_PARSE_d
|
1412
|
+
RHR_PARSE_sep('/')
|
1413
|
+
RHR_PARSE_y
|
1414
|
+
break;
|
1415
|
+
case 'F':
|
1416
|
+
RHR_PARSE_Y
|
1417
|
+
RHR_PARSE_sep('-')
|
1418
|
+
RHR_PARSE_m
|
1419
|
+
RHR_PARSE_sep('-')
|
1420
|
+
RHR_PARSE_d
|
1421
|
+
break;
|
1422
|
+
case 'r':
|
1423
|
+
RHR_PARSE_I
|
1424
|
+
RHR_PARSE_sep(':')
|
1425
|
+
RHR_PARSE_M
|
1426
|
+
RHR_PARSE_sep(':')
|
1427
|
+
RHR_PARSE_S
|
1428
|
+
RHR_PARSE_sep(' ')
|
1429
|
+
RHR_PARSE_p
|
1430
|
+
break;
|
1431
|
+
case 'R':
|
1432
|
+
RHR_PARSE_H
|
1433
|
+
RHR_PARSE_sep(':')
|
1434
|
+
RHR_PARSE_M
|
1435
|
+
break;
|
1436
|
+
case 'X':
|
1437
|
+
case 'T':
|
1438
|
+
RHR_PARSE_H
|
1439
|
+
RHR_PARSE_sep(':')
|
1440
|
+
RHR_PARSE_M
|
1441
|
+
RHR_PARSE_sep(':')
|
1442
|
+
RHR_PARSE_S
|
1443
|
+
break;
|
1444
|
+
case 'v':
|
1445
|
+
RHR_PARSE_d
|
1446
|
+
RHR_PARSE_sep('-')
|
1447
|
+
RHR_PARSE_b
|
1448
|
+
RHR_PARSE_sep('-')
|
1449
|
+
RHR_PARSE_Y
|
1450
|
+
break;
|
1451
|
+
case '+':
|
1452
|
+
RHR_PARSE_a
|
1453
|
+
RHR_PARSE_sep(' ')
|
1454
|
+
RHR_PARSE_b
|
1455
|
+
RHR_PARSE_sep(' ')
|
1456
|
+
RHR_PARSE_d
|
1457
|
+
RHR_PARSE_sep(' ')
|
1458
|
+
RHR_PARSE_H
|
1459
|
+
RHR_PARSE_sep(':')
|
1460
|
+
RHR_PARSE_M
|
1461
|
+
RHR_PARSE_sep(':')
|
1462
|
+
RHR_PARSE_S
|
1463
|
+
RHR_PARSE_sep(' ')
|
1464
|
+
RHR_PARSE_Z
|
1465
|
+
RHR_PARSE_sep(' ')
|
1466
|
+
RHR_PARSE_Y
|
1467
|
+
break;
|
1468
|
+
default:
|
1469
|
+
if (str[pos] != fmt_str[fmt_pos]) {
|
1470
|
+
return Qnil;
|
1471
|
+
}
|
1472
|
+
pos++;
|
1473
|
+
break;
|
1474
|
+
}
|
1475
|
+
pos += scan_len;
|
1476
|
+
mod = 0;
|
1477
|
+
} else if (fmt_str[fmt_pos] == '%') {
|
1478
|
+
mod = 1;
|
1479
|
+
} else {
|
1480
|
+
pos++;
|
1481
|
+
}
|
1482
|
+
}
|
1483
|
+
|
1484
|
+
hash = rb_hash_new();
|
1485
|
+
if(state & RHRR_YEAR_SET) {
|
1486
|
+
if (state & RHRR_CENTURY_SET && year < 100) {
|
1487
|
+
year += century * 100;
|
1488
|
+
}
|
1489
|
+
rb_hash_aset(hash, rhrd_sym_year, LONG2NUM(year));
|
1490
|
+
}
|
1491
|
+
if(state & RHRR_MONTH_SET) {
|
1492
|
+
rb_hash_aset(hash, rhrd_sym_mon, LONG2NUM(month));
|
1493
|
+
}
|
1494
|
+
if(state & RHRR_DAY_SET) {
|
1495
|
+
rb_hash_aset(hash, rhrd_sym_mday, LONG2NUM(day));
|
1496
|
+
}
|
1497
|
+
if(state & RHRR_YDAY_SET) {
|
1498
|
+
rb_hash_aset(hash, rhrd_sym_yday, LONG2NUM(yday));
|
1499
|
+
}
|
1500
|
+
if(state & RHRR_WDAY_SET) {
|
1501
|
+
rb_hash_aset(hash, rhrd_sym_wday, LONG2NUM(wday));
|
1502
|
+
}
|
1503
|
+
if(state & RHRR_CWYEAR_SET) {
|
1504
|
+
if (state & RHRR_CENTURY_SET && cwyear < 100) {
|
1505
|
+
cwyear += century * 100;
|
1506
|
+
}
|
1507
|
+
rb_hash_aset(hash, rhrd_sym_cwyear, LONG2NUM(cwyear));
|
1508
|
+
}
|
1509
|
+
if(state & RHRR_CWEEK_SET) {
|
1510
|
+
rb_hash_aset(hash, rhrd_sym_cweek, LONG2NUM(cweek));
|
1511
|
+
}
|
1512
|
+
if(state & RHRR_CWDAY_SET) {
|
1513
|
+
rb_hash_aset(hash, rhrd_sym_cwday, LONG2NUM(cwday));
|
1514
|
+
}
|
1515
|
+
if(state & RHRR_HOUR_SET) {
|
1516
|
+
if (state & RHRR_MERIDIAN_SET) {
|
1517
|
+
if (meridian) {
|
1518
|
+
if (hour < 12) {
|
1519
|
+
hour += 12;
|
1520
|
+
}
|
1521
|
+
}
|
1522
|
+
else if (hour == 12) {
|
1523
|
+
hour = 0;
|
1524
|
+
}
|
1525
|
+
}
|
1526
|
+
rb_hash_aset(hash, rhrd_sym_hour, LONG2NUM(hour));
|
1527
|
+
}
|
1528
|
+
if(state & RHRR_MINUTE_SET) {
|
1529
|
+
rb_hash_aset(hash, rhrd_sym_min, LONG2NUM(minute));
|
1530
|
+
}
|
1531
|
+
if(state & RHRR_SECOND_SET) {
|
1532
|
+
rb_hash_aset(hash, rhrd_sym_sec, LONG2NUM(second));
|
1533
|
+
}
|
1534
|
+
if(state & RHRR_SEC_FRACTION_SET) {
|
1535
|
+
rb_hash_aset(hash, rhrd_sym_sec_fraction, rb_float_new(sec_fraction));
|
1536
|
+
}
|
1537
|
+
if(state & RHRR_UNIX_SET) {
|
1538
|
+
rb_hash_aset(hash, rhrd_sym_seconds, LL2NUM(seconds));
|
1539
|
+
}
|
1540
|
+
if(state & RHRR_UNIXM_SET) {
|
1541
|
+
rb_hash_aset(hash, rhrd_sym_seconds, LL2NUM(milliseconds/1000));
|
1542
|
+
rb_hash_aset(hash, rhrd_sym_sec_fraction, rb_float_new((milliseconds % 1000)/1000.0));
|
1543
|
+
}
|
1544
|
+
if(RTEST(zone)) {
|
1545
|
+
rb_hash_aset(hash, rhrd_sym_zone, zone);
|
1546
|
+
zone = rhrd_s_zone_to_diff(rstr, zone);
|
1547
|
+
if(RTEST(zone)) {
|
1548
|
+
rb_hash_aset(hash, rhrd_sym_offset, zone);
|
1549
|
+
}
|
1550
|
+
}
|
1551
|
+
if(state & RHRR_WNUM0_SET) {
|
1552
|
+
rb_hash_aset(hash, rhrd_sym_wnum0, LONG2NUM(wnum0));
|
1553
|
+
}
|
1554
|
+
if(state & RHRR_WNUM1_SET) {
|
1555
|
+
rb_hash_aset(hash, rhrd_sym_wnum1, LONG2NUM(wnum1));
|
1556
|
+
}
|
1557
|
+
#ifdef RUBY19
|
1558
|
+
if(pos < len) {
|
1559
|
+
rb_hash_aset(hash, rhrd_sym_leftover, rb_str_new(str + pos, len - pos));
|
1560
|
+
}
|
1561
|
+
#endif
|
1562
|
+
return hash;
|
1563
|
+
}
|
1564
|
+
|
1565
|
+
/* Set the commercial week cached instance variables. */
|
1566
|
+
void rhrd__set_cw_ivs(VALUE self, rhrd_t *d) {
|
1567
|
+
rb_ivar_set(self, rhrd_id_cwyear, LONG2NUM(d->year));
|
1568
|
+
rb_ivar_set(self, rhrd_id_cweek, LONG2NUM(d->month));
|
1569
|
+
rb_ivar_set(self, rhrd_id_cwday, LONG2NUM(d->day));
|
1570
|
+
}
|
1571
|
+
|
1572
|
+
#include "date_parser.c"
|
1573
|
+
|
1574
|
+
/* Ruby class methods */
|
1575
|
+
|
1576
|
+
/* call-seq:
|
1577
|
+
* _load(string) -> Date
|
1578
|
+
*
|
1579
|
+
* Unmarshal a dumped +Date+ object. Not generally called directly,
|
1580
|
+
* usually called by <tt>Marshal.load</tt>.
|
1581
|
+
*
|
1582
|
+
* Note that this does not handle the marshalling format used by
|
1583
|
+
* the stdlib's +Date+, it only handles marshalled versions of
|
1584
|
+
* this library's +Date+ objects.
|
1585
|
+
*/
|
1586
|
+
static VALUE rhrd_s__load(VALUE klass, VALUE string) {
|
1587
|
+
rhrd_t * d;
|
1588
|
+
VALUE jd, rd;
|
1589
|
+
jd = rb_marshal_load(string);
|
1590
|
+
rd = Data_Make_Struct(klass, rhrd_t, NULL, free, d);
|
1591
|
+
d->jd = NUM2LONG(jd);
|
1592
|
+
RHR_CHECK_JD(d)
|
1593
|
+
d->flags = RHR_HAVE_JD;
|
1594
|
+
return rd;
|
1595
|
+
}
|
1596
|
+
|
1597
|
+
|
1598
|
+
/* call-seq:
|
1599
|
+
* _ragel_parse(string) -> Hash or nil
|
1600
|
+
*
|
1601
|
+
* Attemps to parse the string with Ragel, returning a hash
|
1602
|
+
* if there is a match (or +nil+ if no match).
|
1603
|
+
*/
|
1604
|
+
static VALUE rhrd_s__ragel_parse(VALUE klass, VALUE s) {
|
1605
|
+
s = rb_str_to_str(s);
|
1606
|
+
return rhrd__ragel_parse(RSTRING_PTR(s), RSTRING_LEN(s));
|
1607
|
+
}
|
1608
|
+
|
1609
|
+
/* call-seq:
|
1610
|
+
* _strptime(string, format='%F') -> Hash or nil
|
1611
|
+
*
|
1612
|
+
* Attemps to parse the string using the given format, returning
|
1613
|
+
* a hash if there is a match (or +nil+ if no match).
|
1614
|
+
*
|
1615
|
+
* +_strptime+ supports the same formats that <tt>Date#strftime</tt> does.
|
1616
|
+
*/
|
1617
|
+
static VALUE rhrd_s__strptime(int argc, VALUE *argv, VALUE klass) {
|
1618
|
+
const char * fmt_str = "%F";
|
1619
|
+
long fmt_len = 2;
|
1620
|
+
VALUE r;
|
1621
|
+
|
1622
|
+
switch(argc) {
|
1623
|
+
case 2:
|
1624
|
+
r = rb_str_to_str(argv[1]);
|
1625
|
+
fmt_str = RSTRING_PTR(r);
|
1626
|
+
fmt_len = RSTRING_LEN(r);
|
1627
|
+
case 1:
|
1628
|
+
break;
|
1629
|
+
default:
|
1630
|
+
rb_raise(rb_eArgError, "wrong number of arguments (%i for 2)", argc);
|
1631
|
+
break;
|
1632
|
+
}
|
1633
|
+
|
1634
|
+
return rhrd__strptime(argv[0], fmt_str, fmt_len);
|
1635
|
+
}
|
1636
|
+
|
1637
|
+
/* call-seq:
|
1638
|
+
* civil() -> Date <br />
|
1639
|
+
* civil(year, month=1, day=1, sg=nil) -> Date
|
1640
|
+
*
|
1641
|
+
* If no arguments are given, returns a +Date+ for julian day 0.
|
1642
|
+
* Otherwise, returns a +Date+ for the year, month, and day given.
|
1643
|
+
* Raises an +ArgumentError+ for invalid dates.
|
1644
|
+
* Ignores the 4th argument.
|
1645
|
+
*/
|
1646
|
+
static VALUE rhrd_s_civil(int argc, VALUE *argv, VALUE klass) {
|
1647
|
+
rhrd_t *d;
|
1648
|
+
long year;
|
1649
|
+
long month = 1;
|
1650
|
+
long day = 1;
|
1651
|
+
VALUE rd = Data_Make_Struct(klass, rhrd_t, NULL, free, d);
|
1652
|
+
|
1653
|
+
switch(argc) {
|
1654
|
+
case 3:
|
1655
|
+
case 4:
|
1656
|
+
day = NUM2LONG(argv[2]);
|
1657
|
+
case 2:
|
1658
|
+
month = NUM2LONG(argv[1]);
|
1659
|
+
case 1:
|
1660
|
+
year = NUM2LONG(argv[0]);
|
1661
|
+
break;
|
1662
|
+
case 0:
|
1663
|
+
d->flags = RHR_HAVE_JD;
|
1664
|
+
return rd;
|
1665
|
+
default:
|
1666
|
+
rb_raise(rb_eArgError, "wrong number of arguments: %i for 4", argc);
|
1667
|
+
break;
|
1668
|
+
}
|
1669
|
+
|
1670
|
+
if (!rhrd__valid_civil(d, year, month, day)) {
|
1671
|
+
RHR_CHECK_CIVIL(d)
|
1672
|
+
rb_raise(rb_eArgError, "invalid date (year: %li, month: %li, day: %li)", year, month, day);
|
1673
|
+
}
|
1674
|
+
return rd;
|
1675
|
+
}
|
1676
|
+
|
1677
|
+
/* call-seq:
|
1678
|
+
* commercial() -> Date <br />
|
1679
|
+
* commercial(cwyear, cweek=41, cwday=5, sg=nil) -> Date [ruby 1-8] <br />
|
1680
|
+
* commercial(cwyear, cweek=1, cwday=1, sg=nil) -> Date [ruby 1-9]
|
1681
|
+
*
|
1682
|
+
* If no arguments are given:
|
1683
|
+
* * ruby 1.8: returns a +Date+ for 1582-10-15 (the Day of Calendar Reform in Italy)
|
1684
|
+
* * ruby 1.9: returns a +Date+ for julian day 0
|
1685
|
+
*
|
1686
|
+
* Otherwise, returns a +Date+ for the commercial week year, commercial week, and
|
1687
|
+
* commercial week day given.
|
1688
|
+
* Raises an +ArgumentError+ for invalid dates.
|
1689
|
+
* Ignores the 4th argument.
|
1690
|
+
*/
|
1691
|
+
static VALUE rhrd_s_commercial(int argc, VALUE *argv, VALUE klass) {
|
1692
|
+
rhrd_t *d;
|
1693
|
+
long cwyear = RHR_DEFAULT_CWYEAR;
|
1694
|
+
long cweek = RHR_DEFAULT_CWEEK;
|
1695
|
+
long cwday = RHR_DEFAULT_CWDAY;
|
1696
|
+
VALUE rd = Data_Make_Struct(klass, rhrd_t, NULL, free, d);
|
1697
|
+
|
1698
|
+
switch(argc) {
|
1699
|
+
case 3:
|
1700
|
+
case 4:
|
1701
|
+
cwday = NUM2LONG(argv[2]);
|
1702
|
+
case 2:
|
1703
|
+
cweek = NUM2LONG(argv[1]);
|
1704
|
+
case 1:
|
1705
|
+
cwyear = NUM2LONG(argv[0]);
|
1706
|
+
#ifdef RUBY19
|
1707
|
+
break;
|
1708
|
+
case 0:
|
1709
|
+
d->flags = RHR_HAVE_JD;
|
1710
|
+
return rd;
|
1711
|
+
#else
|
1712
|
+
case 0:
|
1713
|
+
break;
|
1714
|
+
#endif
|
1715
|
+
default:
|
1716
|
+
rb_raise(rb_eArgError, "wrong number of arguments: %i for 4", argc);
|
1717
|
+
break;
|
1718
|
+
}
|
1719
|
+
|
1720
|
+
if(!rhrd__valid_commercial(d, cwyear, cweek, cwday)) {
|
1721
|
+
RHR_CHECK_JD(d)
|
1722
|
+
rb_raise(rb_eArgError, "invalid date (cwyear: %li, cweek: %li, cwday: %li)", cwyear, cweek, cwday);
|
1723
|
+
}
|
1724
|
+
return rd;
|
1725
|
+
}
|
1726
|
+
|
1727
|
+
/* call-seq:
|
1728
|
+
* gregorian_leap?(year) -> true or false
|
1729
|
+
*
|
1730
|
+
* Returns true if the given year is a leap year in the Gregorian
|
1731
|
+
* calendar, or false if not.
|
1732
|
+
*/
|
1733
|
+
static VALUE rhrd_s_gregorian_leap_q(VALUE klass, VALUE year) {
|
1734
|
+
return rhrd__leap_year(NUM2LONG(year)) ? Qtrue : Qfalse;
|
1735
|
+
}
|
1736
|
+
|
1737
|
+
/* call-seq:
|
1738
|
+
* jd(jd=0, sg=nil) -> Date
|
1739
|
+
*
|
1740
|
+
* Returns a +Date+ for the julian day number given.
|
1741
|
+
* Ignores the 2nd argument.
|
1742
|
+
*/
|
1743
|
+
static VALUE rhrd_s_jd (int argc, VALUE *argv, VALUE klass) {
|
1744
|
+
rhrd_t *d;
|
1745
|
+
VALUE rd = Data_Make_Struct(klass, rhrd_t, NULL, free, d);
|
1746
|
+
|
1747
|
+
switch(argc) {
|
1748
|
+
case 0:
|
1749
|
+
d->flags = RHR_HAVE_JD;
|
1750
|
+
return rd;
|
1751
|
+
case 1:
|
1752
|
+
case 2:
|
1753
|
+
d->jd = NUM2LONG(argv[0]);
|
1754
|
+
break;
|
1755
|
+
default:
|
1756
|
+
rb_raise(rb_eArgError, "wrong number of arguments: %i for 2", argc);
|
1757
|
+
break;
|
1758
|
+
}
|
1759
|
+
RHR_CHECK_JD(d)
|
1760
|
+
d->flags = RHR_HAVE_JD;
|
1761
|
+
return rd;
|
1762
|
+
}
|
1763
|
+
|
1764
|
+
/* call-seq:
|
1765
|
+
* julian_leap?(year) -> true or false
|
1766
|
+
*
|
1767
|
+
* Returns true if the given year is a leap year in the Julian
|
1768
|
+
* calendar (i.e. divisible by 4), or false if not.
|
1769
|
+
*/
|
1770
|
+
static VALUE rhrd_s_julian_leap_q(VALUE klass, VALUE y) {
|
1771
|
+
return NUM2LONG(y) % 4 == 0 ? Qtrue : Qfalse;
|
1772
|
+
}
|
1773
|
+
|
1774
|
+
/* call-seq:
|
1775
|
+
* new!(jd=0, offset=nil, sg=nil) -> Date
|
1776
|
+
*
|
1777
|
+
* Returns a +Date+ for the julian day number given.
|
1778
|
+
* Ignores the 2nd and 3rd arguments.
|
1779
|
+
*/
|
1780
|
+
static VALUE rhrd_s_new_b(int argc, VALUE *argv, VALUE klass) {
|
1781
|
+
rhrd_t *d;
|
1782
|
+
VALUE rd = Data_Make_Struct(klass, rhrd_t, NULL, free, d);
|
1783
|
+
|
1784
|
+
switch(argc) {
|
1785
|
+
case 0:
|
1786
|
+
d->flags = RHR_HAVE_JD;
|
1787
|
+
return rd;
|
1788
|
+
case 1:
|
1789
|
+
case 2:
|
1790
|
+
case 3:
|
1791
|
+
d->jd = NUM2LONG(argv[0]);
|
1792
|
+
break;
|
1793
|
+
default:
|
1794
|
+
rb_raise(rb_eArgError, "wrong number of arguments: %i for 3", argc);
|
1795
|
+
break;
|
1796
|
+
}
|
1797
|
+
RHR_CHECK_JD(d)
|
1798
|
+
d->flags = RHR_HAVE_JD;
|
1799
|
+
return rd;
|
1800
|
+
}
|
1801
|
+
|
1802
|
+
/* call-seq:
|
1803
|
+
* ordinal() -> Date <br />
|
1804
|
+
* ordinal(year, yday=1, sg=nil) -> Date
|
1805
|
+
*
|
1806
|
+
* If no arguments are given, returns a +Date+ for julian day 0.
|
1807
|
+
* Otherwise, returns a +Date+ for the year and day of year given.
|
1808
|
+
* Raises an +ArgumentError+ for invalid dates.
|
1809
|
+
* Ignores the 3rd argument.
|
1810
|
+
*/
|
1811
|
+
static VALUE rhrd_s_ordinal(int argc, VALUE *argv, VALUE klass) {
|
1812
|
+
long year;
|
1813
|
+
long day = 1;
|
1814
|
+
rhrd_t *d;
|
1815
|
+
VALUE rd = Data_Make_Struct(klass, rhrd_t, NULL, free, d);
|
1816
|
+
|
1817
|
+
switch(argc) {
|
1818
|
+
case 2:
|
1819
|
+
case 3:
|
1820
|
+
day = NUM2LONG(argv[1]);
|
1821
|
+
case 1:
|
1822
|
+
year = NUM2LONG(argv[0]);
|
1823
|
+
if(!rhrd__valid_ordinal(d, year, day)) {
|
1824
|
+
RHR_CHECK_JD(d)
|
1825
|
+
rb_raise(rb_eArgError, "invalid date (year: %li, yday: %li)", year, day);
|
1826
|
+
}
|
1827
|
+
break;
|
1828
|
+
case 0:
|
1829
|
+
d->flags = RHR_HAVE_JD;
|
1830
|
+
return rd;
|
1831
|
+
default:
|
1832
|
+
rb_raise(rb_eArgError, "wrong number of arguments: %i for 3", argc);
|
1833
|
+
break;
|
1834
|
+
}
|
1835
|
+
|
1836
|
+
return rd;
|
1837
|
+
}
|
1838
|
+
|
1839
|
+
/* call-seq:
|
1840
|
+
* parse() -> Date <br />
|
1841
|
+
* parse(string, comp=true, sg=nil) -> Date
|
1842
|
+
*
|
1843
|
+
* If no arguments are given, returns a +Date+ for julian day 0.
|
1844
|
+
* Otherwise returns a +Date+ for the date represented by the given
|
1845
|
+
* +string+. Raises an +ArgumentError+ if the string was not in
|
1846
|
+
* a recognized format, or if the recognized format represents
|
1847
|
+
* an invalid date.
|
1848
|
+
* If +comp+ is true, expands 2-digit years to 4-digits years.
|
1849
|
+
* Ignores the 3rd argument.
|
1850
|
+
*/
|
1851
|
+
static VALUE rhrd_s_parse(int argc, VALUE *argv, VALUE klass) {
|
1852
|
+
rhrd_t *d;
|
1853
|
+
VALUE rd;
|
1854
|
+
|
1855
|
+
switch(argc) {
|
1856
|
+
case 0:
|
1857
|
+
rd = Data_Make_Struct(klass, rhrd_t, NULL, free, d);
|
1858
|
+
d->flags = RHR_HAVE_JD;
|
1859
|
+
return rd;
|
1860
|
+
case 1:
|
1861
|
+
return rhrd__from_hash(rb_funcall(klass, rhrd_id__parse, 1, argv[0]));
|
1862
|
+
case 2:
|
1863
|
+
case 3:
|
1864
|
+
return rhrd__from_hash(rb_funcall(klass, rhrd_id__parse, 2, argv[0], argv[1]));
|
1865
|
+
default:
|
1866
|
+
rb_raise(rb_eArgError, "wrong number of arguments (%i for 3)", argc);
|
1867
|
+
break;
|
1868
|
+
}
|
1869
|
+
}
|
1870
|
+
|
1871
|
+
/* call-seq:
|
1872
|
+
* strptime() -> Date <br />
|
1873
|
+
* strptime(string, format="%F", sg=nil) -> Date
|
1874
|
+
*
|
1875
|
+
* If no arguments are given, returns a +Date+ for julian day 0.
|
1876
|
+
* Other returns a +Date+ for the date represented by the given
|
1877
|
+
* +string+, parsed using the given +format+.
|
1878
|
+
* Raises an +ArgumentError+ if the string did not match the format
|
1879
|
+
* given, or if it did match and it represented an invalid date.
|
1880
|
+
* Ignores the 3rd argument.
|
1881
|
+
*/
|
1882
|
+
static VALUE rhrd_s_strptime(int argc, VALUE *argv, VALUE klass) {
|
1883
|
+
rhrd_t *d;
|
1884
|
+
VALUE rd;
|
1885
|
+
|
1886
|
+
switch(argc) {
|
1887
|
+
case 0:
|
1888
|
+
rd = Data_Make_Struct(klass, rhrd_t, NULL, free, d);
|
1889
|
+
d->flags = RHR_HAVE_JD;
|
1890
|
+
return rd;
|
1891
|
+
case 1:
|
1892
|
+
case 2:
|
1893
|
+
break;
|
1894
|
+
case 3:
|
1895
|
+
argc = 2;
|
1896
|
+
break;
|
1897
|
+
default:
|
1898
|
+
rb_raise(rb_eArgError, "wrong number of arguments (%i for 3)", argc);
|
1899
|
+
break;
|
1900
|
+
}
|
1901
|
+
|
1902
|
+
rd = rhrd_s__strptime(argc, argv, klass);
|
1903
|
+
if (RTEST(rd)) {
|
1904
|
+
return rhrd__from_hash(rd);
|
1905
|
+
}
|
1906
|
+
rb_raise(rb_eArgError, "invalid date");
|
1907
|
+
}
|
1908
|
+
|
1909
|
+
/* call-seq:
|
1910
|
+
* today(sg=nil) -> Date
|
1911
|
+
*
|
1912
|
+
* Returns a +Date+ representing the current local date.
|
1913
|
+
* Ignores an argument if given.
|
1914
|
+
*/
|
1915
|
+
static VALUE rhrd_s_today(int argc, VALUE *argv, VALUE klass) {
|
1916
|
+
rhrd_t *d;
|
1917
|
+
VALUE rd = Data_Make_Struct(klass, rhrd_t, NULL, free, d);
|
1918
|
+
|
1919
|
+
switch(argc) {
|
1920
|
+
case 0:
|
1921
|
+
case 1:
|
1922
|
+
break;
|
1923
|
+
default:
|
1924
|
+
rb_raise(rb_eArgError, "wrong number of arguments: %i for 1", argc);
|
1925
|
+
break;
|
1926
|
+
}
|
1927
|
+
|
1928
|
+
rhrd__today(d);
|
1929
|
+
return rd;
|
1930
|
+
}
|
1931
|
+
|
1932
|
+
/* call-seq:
|
1933
|
+
* valid_civil?(year, month, day, sg=nil) -> Integer or nil [ruby 1-8] <br />
|
1934
|
+
* valid_civil?(year, month, day, sg=nil) -> true or false [ruby 1-9]
|
1935
|
+
*
|
1936
|
+
* On ruby 1.8, returns the julian date +Integer+ for the given +year+, +month+,
|
1937
|
+
* and +day+, or nil if the given values are not a valid date.
|
1938
|
+
*
|
1939
|
+
* On ruby 1.9, returns true if the given +year+, +month+, and +day+ represent
|
1940
|
+
* a valid date, or false otherwise.
|
1941
|
+
*
|
1942
|
+
* Ignores the 4th argument.
|
1943
|
+
*/
|
1944
|
+
static VALUE rhrd_s_valid_civil_q(int argc, VALUE *argv, VALUE klass) {
|
1945
|
+
rhrd_t d;
|
1946
|
+
memset(&d, 0, sizeof(rhrd_t));
|
1947
|
+
|
1948
|
+
switch(argc) {
|
1949
|
+
case 3:
|
1950
|
+
case 4:
|
1951
|
+
if (!rhrd__valid_civil(&d, NUM2LONG(argv[0]), NUM2LONG(argv[1]), NUM2LONG(argv[2]))) {
|
1952
|
+
#ifdef RUBY19
|
1953
|
+
return Qfalse;
|
1954
|
+
#else
|
1955
|
+
return Qnil;
|
1956
|
+
#endif
|
1957
|
+
}
|
1958
|
+
break;
|
1959
|
+
default:
|
1960
|
+
rb_raise(rb_eArgError, "wrong number of arguments: %i for 4", argc);
|
1961
|
+
break;
|
1962
|
+
}
|
1963
|
+
|
1964
|
+
#ifdef RUBY19
|
1965
|
+
return Qtrue;
|
1966
|
+
#else
|
1967
|
+
RHR_FILL_JD(&d)
|
1968
|
+
return LONG2NUM(d.jd);
|
1969
|
+
#endif
|
1970
|
+
}
|
1971
|
+
|
1972
|
+
/* call-seq:
|
1973
|
+
* valid_commercial?(cwyear, cweek, cwday, sg=nil) -> Integer or nil [ruby 1-8] <br />
|
1974
|
+
* valid_commercial?(cwyear, cweek, cwday, sg=nil) -> true or false [ruby 1-9]
|
1975
|
+
*
|
1976
|
+
* On ruby 1.8, returns the julian date +Integer+ for the given +cwyear+, +cweek+,
|
1977
|
+
* and +cwday+, or nil if the given values are not a valid date.
|
1978
|
+
*
|
1979
|
+
* On ruby 1.9, returns true if the given +cwyear+, +cweek+, and +cwday+ represent
|
1980
|
+
* a valid date, or false otherwise.
|
1981
|
+
*
|
1982
|
+
* Ignores the 4th argument.
|
1983
|
+
*/
|
1984
|
+
static VALUE rhrd_s_valid_commercial_q(int argc, VALUE *argv, VALUE klass) {
|
1985
|
+
rhrd_t d;
|
1986
|
+
memset(&d, 0, sizeof(rhrd_t));
|
1987
|
+
|
1988
|
+
switch(argc) {
|
1989
|
+
case 3:
|
1990
|
+
case 4:
|
1991
|
+
if (!rhrd__valid_commercial(&d, NUM2LONG(argv[0]), NUM2LONG(argv[1]), NUM2LONG(argv[2]))) {
|
1992
|
+
#ifdef RUBY19
|
1993
|
+
return Qfalse;
|
1994
|
+
#else
|
1995
|
+
return Qnil;
|
1996
|
+
#endif
|
1997
|
+
}
|
1998
|
+
break;
|
1999
|
+
default:
|
2000
|
+
rb_raise(rb_eArgError, "wrong number of arguments: %i for 4", argc);
|
2001
|
+
break;
|
2002
|
+
}
|
2003
|
+
|
2004
|
+
#ifdef RUBY19
|
2005
|
+
return Qtrue;
|
2006
|
+
#else
|
2007
|
+
return LONG2NUM(d.jd);
|
2008
|
+
#endif
|
2009
|
+
}
|
2010
|
+
|
2011
|
+
/* call-seq:
|
2012
|
+
* valid_jd?(jd, sg=nil) -> Object [ruby 1-8] <br />
|
2013
|
+
* valid_jd?(jd, sg=nil) -> true [ruby 1-9]
|
2014
|
+
*
|
2015
|
+
* On ruby 1.8, returns the first argument.
|
2016
|
+
* On ruby 1.9, returns true.
|
2017
|
+
* Ignores the 2nd argument.
|
2018
|
+
*/
|
2019
|
+
static VALUE rhrd_s_valid_jd_q(int argc, VALUE *argv, VALUE klass) {
|
2020
|
+
switch(argc) {
|
2021
|
+
case 1:
|
2022
|
+
case 2:
|
2023
|
+
break;
|
2024
|
+
default:
|
2025
|
+
rb_raise(rb_eArgError, "wrong number of arguments: %i for 2", argc);
|
2026
|
+
break;
|
2027
|
+
}
|
2028
|
+
|
2029
|
+
#ifdef RUBY19
|
2030
|
+
return Qtrue;
|
2031
|
+
#else
|
2032
|
+
return argv[0];
|
2033
|
+
#endif
|
2034
|
+
}
|
2035
|
+
|
2036
|
+
/* call-seq:
|
2037
|
+
* valid_ordinal?(year, yday, sg=nil) -> Integer or nil [ruby 1-8] <br />
|
2038
|
+
* valid_ordinal?(year, yday, sg=nil) -> true or false [ruby 1-9]
|
2039
|
+
*
|
2040
|
+
* On ruby 1.8, returns the julian date +Integer+ for the given +year+ and +yday+,
|
2041
|
+
* or nil if the given values are not a valid date.
|
2042
|
+
*
|
2043
|
+
* On ruby 1.9, returns true if the given +year+ and +yday+ represent
|
2044
|
+
* a valid date, or false otherwise.
|
2045
|
+
*
|
2046
|
+
* Ignores the 3rd argument.
|
2047
|
+
*/
|
2048
|
+
static VALUE rhrd_s_valid_ordinal_q(int argc, VALUE *argv, VALUE klass) {
|
2049
|
+
rhrd_t d;
|
2050
|
+
memset(&d, 0, sizeof(rhrd_t));
|
2051
|
+
|
2052
|
+
switch(argc) {
|
2053
|
+
case 2:
|
2054
|
+
case 3:
|
2055
|
+
if (!rhrd__valid_ordinal(&d, NUM2LONG(argv[0]), NUM2LONG(argv[1]))) {
|
2056
|
+
#ifdef RUBY19
|
2057
|
+
return Qfalse;
|
2058
|
+
#else
|
2059
|
+
return Qnil;
|
2060
|
+
#endif
|
2061
|
+
}
|
2062
|
+
break;
|
2063
|
+
default:
|
2064
|
+
rb_raise(rb_eArgError, "wrong number of arguments: %i for 3", argc);
|
2065
|
+
break;
|
2066
|
+
}
|
2067
|
+
|
2068
|
+
#ifdef RUBY19
|
2069
|
+
return Qtrue;
|
2070
|
+
#else
|
2071
|
+
RHR_FILL_JD(&d)
|
2072
|
+
return LONG2NUM(d.jd);
|
2073
|
+
#endif
|
2074
|
+
}
|
2075
|
+
|
2076
|
+
/* call-seq:
|
2077
|
+
* zone_to_diff(zone) -> Integer <br />
|
2078
|
+
*
|
2079
|
+
* Returns an +Integer+ representing the number of seconds that the given
|
2080
|
+
* zone string is offset from UTC. For example, 'PDT' is Pacific Daylight Time, which
|
2081
|
+
* 7 hours before UTC, so <tt>Date.zone_to_diff('PDT')</tt> will return <tt>-25200</tt>.
|
2082
|
+
*
|
2083
|
+
* In addition to handling time zone names, this also handles time zones specified
|
2084
|
+
* numerically, such as <tt>"+08:00"</tt> and <tt>"-0800"</tt>.
|
2085
|
+
*
|
2086
|
+
* If the time zone is not recognized, returns 0.
|
2087
|
+
*
|
2088
|
+
* On ruby 1.9, this method is private.
|
2089
|
+
*/
|
2090
|
+
static VALUE rhrd_s_zone_to_diff(VALUE klass, VALUE str) {
|
2091
|
+
long offset = 0;
|
2092
|
+
long len, i, j;
|
2093
|
+
char *s;
|
2094
|
+
VALUE v, e;
|
2095
|
+
|
2096
|
+
str = rb_funcall(str, rhrd_id_downcase, 0);
|
2097
|
+
if(RTEST(rb_funcall(str, rhrd_id_sub_b, 2, rhrd_zone_dst_re, rhrd_empty_string))) {
|
2098
|
+
if (!RTEST(rb_reg_nth_match(1, rb_gv_get("$~")))) {
|
2099
|
+
offset += RHR_SECONDS_PER_HOUR;
|
2100
|
+
}
|
2101
|
+
}
|
2102
|
+
|
2103
|
+
if(RTEST(v = rb_hash_aref(rhrd_zones_hash, str))) {
|
2104
|
+
return LONG2NUM(offset + NUM2LONG(v));
|
2105
|
+
}
|
2106
|
+
|
2107
|
+
if(RTEST(rb_funcall(str, rhrd_id_sub_b, 2, rhrd_zone_sign_re, rhrd_empty_string))) {
|
2108
|
+
if (RTEST(rb_reg_nth_match(1, rb_gv_get("$~")))) {
|
2109
|
+
offset = -1;
|
2110
|
+
} else {
|
2111
|
+
offset = 1;
|
2112
|
+
}
|
2113
|
+
str = rb_str_to_str(str);
|
2114
|
+
s = RSTRING_PTR(str);
|
2115
|
+
len = RSTRING_LEN(str);
|
2116
|
+
for(i=0; i < len; i++) {
|
2117
|
+
if(s[i] == ':') {
|
2118
|
+
v = rb_funcall(str, rhrd_id_split, 1, rhrd_string_colon);
|
2119
|
+
return LONG2NUM((NUM2LONG(rb_funcall(rb_ary_entry(v, 0), rhrd_id_to_i, 0)) * RHR_SECONDS_PER_HOUR
|
2120
|
+
+ NUM2LONG(rb_funcall(rb_ary_entry(v, 1), rhrd_id_to_i, 0)) * 60
|
2121
|
+
+ NUM2LONG(rb_funcall(rb_ary_entry(v, 2), rhrd_id_to_i, 0))) * offset);
|
2122
|
+
}
|
2123
|
+
}
|
2124
|
+
for(i=0; i < len; i++) {
|
2125
|
+
if((s[i] == ',') || (s[i] == '.')) {
|
2126
|
+
v = rb_funcall(str, rhrd_id_split, 1, rhrd_re_comma_period);
|
2127
|
+
e = rb_ary_entry(v, 1);
|
2128
|
+
return LONG2NUM((NUM2LONG(rb_funcall(rb_ary_entry(v, 0), rhrd_id_to_i, 0)) * RHR_SECONDS_PER_HOUR)
|
2129
|
+
+ (NUM2LONG(rb_funcall(e, rhrd_id_to_i, 0)) * RHR_SECONDS_PER_HOUR) / (long)pow(10, RSTRING_LEN(rb_str_to_str(e))) * offset);
|
2130
|
+
}
|
2131
|
+
}
|
2132
|
+
switch (len) {
|
2133
|
+
case 0:
|
2134
|
+
return LONG2NUM(0);
|
2135
|
+
case 1:
|
2136
|
+
case 2:
|
2137
|
+
return LONG2NUM(atol(s) * RHR_SECONDS_PER_HOUR * offset);
|
2138
|
+
case 3:
|
2139
|
+
i = atol(s + 1);
|
2140
|
+
s[1] = '\0';
|
2141
|
+
len = atol(s);
|
2142
|
+
return LONG2NUM((len * RHR_SECONDS_PER_HOUR + i * 60) * offset);
|
2143
|
+
case 4:
|
2144
|
+
i = atol(s + 2);
|
2145
|
+
s[2] = '\0';
|
2146
|
+
len = atol(s);
|
2147
|
+
return LONG2NUM((len * RHR_SECONDS_PER_HOUR + i * 60) * offset);
|
2148
|
+
default:
|
2149
|
+
s[6] = '\0';
|
2150
|
+
case 6:
|
2151
|
+
case 5:
|
2152
|
+
j = atol(s + 4);
|
2153
|
+
s[4] = '\0';
|
2154
|
+
i = atol(s + 2);
|
2155
|
+
s[2] = '\0';
|
2156
|
+
len = atol(s);
|
2157
|
+
return LONG2NUM((len * RHR_SECONDS_PER_HOUR + i * 60 + j) * offset);
|
2158
|
+
}
|
2159
|
+
}
|
2160
|
+
|
2161
|
+
return LONG2NUM(0);
|
2162
|
+
}
|
2163
|
+
|
2164
|
+
/* Ruby instance methods */
|
2165
|
+
|
2166
|
+
/* call-seq:
|
2167
|
+
* _dump(limit) -> String
|
2168
|
+
*
|
2169
|
+
* Returns a marshalled representation of the receiver as a +String+.
|
2170
|
+
* Generally not called directly, usually called by <tt>Marshal.dump</tt>.
|
2171
|
+
*/
|
2172
|
+
static VALUE rhrd__dump(VALUE self, VALUE limit) {
|
2173
|
+
rhrd_t *d;
|
2174
|
+
Data_Get_Struct(self, rhrd_t, d);
|
2175
|
+
RHR_FILL_JD(d)
|
2176
|
+
return rb_marshal_dump(LONG2NUM(d->jd), LONG2NUM(NUM2LONG(limit) - 1));
|
2177
|
+
}
|
2178
|
+
|
2179
|
+
/* call-seq:
|
2180
|
+
* asctime() -> String
|
2181
|
+
*
|
2182
|
+
* Returns a string representation of the receiver. Example:
|
2183
|
+
*
|
2184
|
+
* Date.civil(2009, 1, 2).asctime
|
2185
|
+
* # => "Fri Jan 2 00:00:00 2009"
|
2186
|
+
*/
|
2187
|
+
static VALUE rhrd_asctime(VALUE self) {
|
2188
|
+
VALUE s;
|
2189
|
+
rhrd_t *d;
|
2190
|
+
int len;
|
2191
|
+
Data_Get_Struct(self, rhrd_t, d);
|
2192
|
+
RHR_FILL_CIVIL(d)
|
2193
|
+
RHR_FILL_JD(d)
|
2194
|
+
|
2195
|
+
s = rb_str_buf_new(128);
|
2196
|
+
len = snprintf(RSTRING_PTR(s), 128, "%s %s %2hhi 00:00:00 %04li",
|
2197
|
+
rhrd__abbr_day_names[rhrd__jd_to_wday(d->jd)],
|
2198
|
+
rhrd__abbr_month_names[d->month],
|
2199
|
+
d->day,
|
2200
|
+
d->year);
|
2201
|
+
if (len == -1 || len > 127) {
|
2202
|
+
rb_raise(rb_eNoMemError, "in Date#asctime (in snprintf)");
|
2203
|
+
}
|
2204
|
+
|
2205
|
+
RHR_RETURN_RESIZED_STR(s, len)
|
2206
|
+
}
|
2207
|
+
|
2208
|
+
/* call-seq:
|
2209
|
+
* cwday() -> Integer
|
2210
|
+
*
|
2211
|
+
* Returns the commercial week day as an +Integer+. Example:
|
2212
|
+
*
|
2213
|
+
* Date.civil(2009, 1, 2).cwday
|
2214
|
+
* # => 5
|
2215
|
+
* Date.civil(2010, 1, 2).cwday
|
2216
|
+
* # => 6
|
2217
|
+
*/
|
2218
|
+
static VALUE rhrd_cwday(VALUE self) {
|
2219
|
+
rhrd_t *d;
|
2220
|
+
rhrd_t n;
|
2221
|
+
RHR_CACHED_IV(self, rhrd_id_cwday)
|
2222
|
+
memset(&n, 0, sizeof(rhrd_t));
|
2223
|
+
Data_Get_Struct(self, rhrd_t, d);
|
2224
|
+
RHR_FILL_JD(d)
|
2225
|
+
n.jd = d->jd;
|
2226
|
+
rhrd__fill_commercial(&n);
|
2227
|
+
rhrd__set_cw_ivs(self, &n);
|
2228
|
+
return LONG2NUM(n.day);
|
2229
|
+
}
|
2230
|
+
|
2231
|
+
/* call-seq:
|
2232
|
+
* cweek() -> Integer
|
2233
|
+
*
|
2234
|
+
* Returns the commercial week as an +Integer+. Example:
|
2235
|
+
*
|
2236
|
+
* Date.civil(2009, 1, 2).cweek
|
2237
|
+
* # => 1
|
2238
|
+
* Date.civil(2010, 1, 2).cweek
|
2239
|
+
* # => 53
|
2240
|
+
*/
|
2241
|
+
static VALUE rhrd_cweek(VALUE self) {
|
2242
|
+
rhrd_t *d;
|
2243
|
+
rhrd_t n;
|
2244
|
+
RHR_CACHED_IV(self, rhrd_id_cweek)
|
2245
|
+
memset(&n, 0, sizeof(rhrd_t));
|
2246
|
+
Data_Get_Struct(self, rhrd_t, d);
|
2247
|
+
RHR_FILL_JD(d)
|
2248
|
+
n.jd = d->jd;
|
2249
|
+
rhrd__fill_commercial(&n);
|
2250
|
+
rhrd__set_cw_ivs(self, &n);
|
2251
|
+
return LONG2NUM(n.month);
|
2252
|
+
}
|
2253
|
+
|
2254
|
+
/* call-seq:
|
2255
|
+
* cwyear() -> Integer
|
2256
|
+
*
|
2257
|
+
* Returns the commercial week year as an +Integer+. Example:
|
2258
|
+
*
|
2259
|
+
* Date.civil(2009, 1, 2).cwyear
|
2260
|
+
* # => 2009
|
2261
|
+
* Date.civil(2010, 1, 2).cwyear
|
2262
|
+
* # => 2009
|
2263
|
+
*/
|
2264
|
+
static VALUE rhrd_cwyear(VALUE self) {
|
2265
|
+
rhrd_t *d;
|
2266
|
+
rhrd_t n;
|
2267
|
+
RHR_CACHED_IV(self, rhrd_id_cwyear)
|
2268
|
+
memset(&n, 0, sizeof(rhrd_t));
|
2269
|
+
Data_Get_Struct(self, rhrd_t, d);
|
2270
|
+
RHR_FILL_JD(d)
|
2271
|
+
n.jd = d->jd;
|
2272
|
+
rhrd__fill_commercial(&n);
|
2273
|
+
rhrd__set_cw_ivs(self, &n);
|
2274
|
+
return LONG2NUM(n.year);
|
2275
|
+
}
|
2276
|
+
|
2277
|
+
/* call-seq:
|
2278
|
+
* day() -> Integer
|
2279
|
+
*
|
2280
|
+
* Returns the day of the month as an +Integer+. Example:
|
2281
|
+
*
|
2282
|
+
* Date.civil(2009, 1, 2).day
|
2283
|
+
* # => 2
|
2284
|
+
*/
|
2285
|
+
static VALUE rhrd_day(VALUE self) {
|
2286
|
+
rhrd_t *d;
|
2287
|
+
Data_Get_Struct(self, rhrd_t, d);
|
2288
|
+
RHR_FILL_CIVIL(d)
|
2289
|
+
return LONG2NUM(d->day);
|
2290
|
+
}
|
2291
|
+
|
2292
|
+
/* call-seq:
|
2293
|
+
* day_fraction() -> 0
|
2294
|
+
*
|
2295
|
+
* +Date+ objects due not hold fractional days, so 0 is always returned.
|
2296
|
+
*/
|
2297
|
+
static VALUE rhrd_day_fraction(VALUE self) {
|
2298
|
+
return LONG2NUM(0);
|
2299
|
+
}
|
2300
|
+
|
2301
|
+
/* call-seq:
|
2302
|
+
* downto(target){|date|} -> Date
|
2303
|
+
*
|
2304
|
+
* Equivalent to calling +step+ with the +target+ as the first argument
|
2305
|
+
* and <tt>-1</tt> as the second argument. Returns self.
|
2306
|
+
*
|
2307
|
+
* Date.civil(2009, 1, 2).downto(Date.civil(2009, 1, 1)) do |date|
|
2308
|
+
* puts date
|
2309
|
+
* end
|
2310
|
+
* # Output:
|
2311
|
+
* # 2009-01-02
|
2312
|
+
* # 2009-01-01
|
2313
|
+
*/
|
2314
|
+
static VALUE rhrd_downto(VALUE self, VALUE other) {
|
2315
|
+
VALUE argv[2];
|
2316
|
+
argv[0] = other;
|
2317
|
+
argv[1] = INT2FIX(-1);
|
2318
|
+
return rhrd_step(2, argv, self);
|
2319
|
+
}
|
2320
|
+
|
2321
|
+
/* call-seq:
|
2322
|
+
* eql?(date) -> true or false
|
2323
|
+
*
|
2324
|
+
* Returns true only if the +date+ given is the same date as the receiver.
|
2325
|
+
* If +date+ is an instance of +DateTime+, returns +true+ only if +date+ is
|
2326
|
+
* for the same date as the receiver and has no fractional component.
|
2327
|
+
* Otherwise, returns +false+. Example:
|
2328
|
+
*
|
2329
|
+
* Date.civil(2009, 1, 2).eql?(Date.civil(2009, 1, 2))
|
2330
|
+
* # => true
|
2331
|
+
* Date.civil(2009, 1, 2).eql?(Date.civil(2009, 1, 1))
|
2332
|
+
* # => false
|
2333
|
+
* Date.civil(2009, 1, 2).eql?(DateTime.civil(2009, 1, 2))
|
2334
|
+
* # => true
|
2335
|
+
* Date.civil(2009, 1, 2).eql?(DateTime.civil(2009, 1, 2, 1))
|
2336
|
+
* # => false
|
2337
|
+
*/
|
2338
|
+
static VALUE rhrd_eql_q(VALUE self, VALUE other) {
|
2339
|
+
rhrd_t *d, *o;
|
2340
|
+
rhrdt_t *odt;
|
2341
|
+
long diff;
|
2342
|
+
Data_Get_Struct(self, rhrd_t, d);
|
2343
|
+
|
2344
|
+
if (RTEST(rb_obj_is_kind_of(other, rhrdt_class))) {
|
2345
|
+
Data_Get_Struct(other, rhrdt_t, odt);
|
2346
|
+
RHR_FILL_JD(d)
|
2347
|
+
RHRDT_FILL_JD(odt)
|
2348
|
+
RHR_SPACE_SHIP(diff, d->jd, odt->jd)
|
2349
|
+
if (diff == 0) {
|
2350
|
+
RHRDT_FILL_NANOS(odt)
|
2351
|
+
RHR_SPACE_SHIP(diff, 0, odt->nanos)
|
2352
|
+
}
|
2353
|
+
return diff == 0 ? Qtrue : Qfalse;
|
2354
|
+
} else if (RTEST(rb_obj_is_kind_of(other, rhrd_class))) {
|
2355
|
+
Data_Get_Struct(other, rhrd_t, o);
|
2356
|
+
return rhrd__spaceship(d, o) == 0 ? Qtrue : Qfalse;
|
2357
|
+
}
|
2358
|
+
return Qfalse;
|
2359
|
+
}
|
2360
|
+
|
2361
|
+
/* call-seq:
|
2362
|
+
* gregorian() -> Date
|
2363
|
+
*
|
2364
|
+
* This library does not support modifying the day of calendar
|
2365
|
+
* reform, so this always returns self.
|
2366
|
+
*/
|
2367
|
+
static VALUE rhrd_gregorian(VALUE self) {
|
2368
|
+
return self;
|
2369
|
+
}
|
2370
|
+
|
2371
|
+
/* call-seq:
|
2372
|
+
* gregorian?() -> true
|
2373
|
+
*
|
2374
|
+
* This library always uses the Gregorian calendar, so this
|
2375
|
+
* always returns +true+.
|
2376
|
+
*/
|
2377
|
+
static VALUE rhrd_gregorian_q(VALUE self) {
|
2378
|
+
return Qtrue;
|
2379
|
+
}
|
2380
|
+
|
2381
|
+
/* call-seq:
|
2382
|
+
* hash() -> Integer
|
2383
|
+
*
|
2384
|
+
* Return an Integer hash value for the receiver, such that an
|
2385
|
+
* equal date will have the same hash value.
|
2386
|
+
*/
|
2387
|
+
static VALUE rhrd_hash(VALUE self) {
|
2388
|
+
rhrd_t *d;
|
2389
|
+
RHR_CACHED_IV(self, rhrd_id_hash)
|
2390
|
+
Data_Get_Struct(self, rhrd_t, d);
|
2391
|
+
RHR_FILL_JD(d)
|
2392
|
+
return rb_ivar_set(self, rhrd_id_hash, rb_funcall(LONG2NUM(d->jd), rhrd_id_hash, 0));
|
2393
|
+
}
|
2394
|
+
|
2395
|
+
/* call-seq:
|
2396
|
+
* inspect() -> String
|
2397
|
+
*
|
2398
|
+
* Return a developer-friendly string containing the civil
|
2399
|
+
* date for the receiver. Example:
|
2400
|
+
*
|
2401
|
+
* Date.civil(2009, 1, 2).inspect
|
2402
|
+
* # => "#<Date 2009-01-02>"
|
2403
|
+
*/
|
2404
|
+
static VALUE rhrd_inspect(VALUE self) {
|
2405
|
+
VALUE s;
|
2406
|
+
rhrd_t *d;
|
2407
|
+
int len;
|
2408
|
+
Data_Get_Struct(self, rhrd_t, d);
|
2409
|
+
RHR_FILL_CIVIL(d)
|
2410
|
+
|
2411
|
+
s = rb_str_buf_new(128);
|
2412
|
+
len = snprintf(RSTRING_PTR(s), 128, "#<Date %04li-%02hhi-%02hhi>",
|
2413
|
+
d->year, d->month, d->day);
|
2414
|
+
if (len == -1 || len > 127) {
|
2415
|
+
rb_raise(rb_eNoMemError, "in Date#inspect (in snprintf)");
|
2416
|
+
}
|
2417
|
+
|
2418
|
+
RHR_RETURN_RESIZED_STR(s, len)
|
2419
|
+
}
|
2420
|
+
|
2421
|
+
/* call-seq:
|
2422
|
+
* jd() -> Integer
|
2423
|
+
*
|
2424
|
+
* Return the julian day number for the receiver as an +Integer+.
|
2425
|
+
*
|
2426
|
+
* Date.civil(2009, 1, 2).jd
|
2427
|
+
* # => 2454834
|
2428
|
+
*/
|
2429
|
+
static VALUE rhrd_jd(VALUE self) {
|
2430
|
+
rhrd_t *d;
|
2431
|
+
Data_Get_Struct(self, rhrd_t, d);
|
2432
|
+
RHR_FILL_JD(d)
|
2433
|
+
return LONG2NUM(d->jd);
|
2434
|
+
}
|
2435
|
+
|
2436
|
+
/* call-seq:
|
2437
|
+
* julian?() -> false
|
2438
|
+
*
|
2439
|
+
* This library always uses the Gregorian calendar, so this
|
2440
|
+
* always returns +false+.
|
2441
|
+
*/
|
2442
|
+
static VALUE rhrd_julian_q(VALUE self) {
|
2443
|
+
return Qfalse;
|
2444
|
+
}
|
2445
|
+
|
2446
|
+
/* call-seq:
|
2447
|
+
* ld() -> Integer
|
2448
|
+
*
|
2449
|
+
* Return the number of days since the Lilian Date (the day of calendar reform
|
2450
|
+
* in Italy).
|
2451
|
+
*
|
2452
|
+
* Date.civil(2009, 1, 2).ld
|
2453
|
+
* # => 155674
|
2454
|
+
*/
|
2455
|
+
static VALUE rhrd_ld(VALUE self) {
|
2456
|
+
rhrd_t *d;
|
2457
|
+
Data_Get_Struct(self, rhrd_t, d);
|
2458
|
+
RHR_FILL_JD(d)
|
2459
|
+
return LONG2NUM(d->jd - RHR_JD_LD);
|
2460
|
+
}
|
2461
|
+
|
2462
|
+
/* call-seq:
|
2463
|
+
* leap?() -> true or false
|
2464
|
+
*
|
2465
|
+
* Return +true+ if the current year for this date is a leap year
|
2466
|
+
* in the Gregorian calendar, +false+ otherwise.
|
2467
|
+
*
|
2468
|
+
* Date.civil(2009, 1, 2).leap?
|
2469
|
+
* # => false
|
2470
|
+
* Date.civil(2008, 1, 2).leap?
|
2471
|
+
* # => true
|
2472
|
+
*/
|
2473
|
+
static VALUE rhrd_leap_q(VALUE self) {
|
2474
|
+
rhrd_t *d;
|
2475
|
+
Data_Get_Struct(self, rhrd_t, d);
|
2476
|
+
RHR_FILL_CIVIL(d)
|
2477
|
+
return rhrd__leap_year(d->year) ? Qtrue : Qfalse;
|
2478
|
+
}
|
2479
|
+
|
2480
|
+
/* call-seq:
|
2481
|
+
* mjd() -> Integer
|
2482
|
+
*
|
2483
|
+
* Return the number of days since 1858-11-17.
|
2484
|
+
*
|
2485
|
+
* Date.civil(2009, 1, 2).mjd
|
2486
|
+
* # => 54833
|
2487
|
+
*/
|
2488
|
+
static VALUE rhrd_mjd(VALUE self) {
|
2489
|
+
rhrd_t *d;
|
2490
|
+
Data_Get_Struct(self, rhrd_t, d);
|
2491
|
+
RHR_FILL_JD(d)
|
2492
|
+
return LONG2NUM(d->jd - RHR_JD_MJD);
|
2493
|
+
}
|
2494
|
+
|
2495
|
+
/* call-seq:
|
2496
|
+
* month() -> Integer
|
2497
|
+
*
|
2498
|
+
* Returns the number of the month as an +Integer+. Example:
|
2499
|
+
*
|
2500
|
+
* Date.civil(2009, 1, 2).month
|
2501
|
+
* # => 1
|
2502
|
+
*/
|
2503
|
+
static VALUE rhrd_month(VALUE self) {
|
2504
|
+
rhrd_t *d;
|
2505
|
+
Data_Get_Struct(self, rhrd_t, d);
|
2506
|
+
RHR_FILL_CIVIL(d)
|
2507
|
+
return LONG2NUM(d->month);
|
2508
|
+
}
|
2509
|
+
|
2510
|
+
/* call-seq:
|
2511
|
+
* next() -> Date
|
2512
|
+
*
|
2513
|
+
* Returns the +Date+ after the receiver's date:
|
2514
|
+
*
|
2515
|
+
* Date.civil(2009, 1, 2).next
|
2516
|
+
* # => #<Date 2009-01-03>
|
2517
|
+
*/
|
2518
|
+
static VALUE rhrd_next(VALUE self) {
|
2519
|
+
return rhrd__add_days(self, 1);
|
2520
|
+
}
|
2521
|
+
|
2522
|
+
/* call-seq:
|
2523
|
+
* new_start(sg=nil) -> Date
|
2524
|
+
*
|
2525
|
+
* Returns self. Ignores an argument if given.
|
2526
|
+
*/
|
2527
|
+
static VALUE rhrd_new_start(int argc, VALUE *argv, VALUE self) {
|
2528
|
+
switch(argc) {
|
2529
|
+
case 0:
|
2530
|
+
case 1:
|
2531
|
+
break;
|
2532
|
+
default:
|
2533
|
+
rb_raise(rb_eArgError, "wrong number of arguments: %i for 1", argc);
|
2534
|
+
break;
|
2535
|
+
}
|
2536
|
+
|
2537
|
+
return self;
|
2538
|
+
}
|
2539
|
+
|
2540
|
+
/* call-seq:
|
2541
|
+
* start() -> Integer
|
2542
|
+
*
|
2543
|
+
* Returns a number lower than the lowest julian date that can be
|
2544
|
+
* correctly handled. Because this library always uses the Gregorian
|
2545
|
+
* calendar, the day of calendar reform is chosen to be less than any
|
2546
|
+
* date that this library can handle.
|
2547
|
+
*/
|
2548
|
+
static VALUE rhrd_start(VALUE self) {
|
2549
|
+
return rhrd_start_num;
|
2550
|
+
}
|
2551
|
+
|
2552
|
+
/* call-seq:
|
2553
|
+
* step(target, step=1){|date|} -> Date
|
2554
|
+
*
|
2555
|
+
* Yields +Date+ objects between the receiver and the +target+ date
|
2556
|
+
* (inclusive), with +step+ integer days between each yielded date.
|
2557
|
+
* +step+ can be negative, in which case the dates are yielded in
|
2558
|
+
* reverse chronological order. Returns self in all cases.
|
2559
|
+
*
|
2560
|
+
* If +target+ is equal to the receiver, yields self once regardless of
|
2561
|
+
* +step+. It +target+ is less than receiver and +step+ is nonnegative, or
|
2562
|
+
* +target+ is greater than receiver and +step+ is nonpositive, does not
|
2563
|
+
* yield.
|
2564
|
+
*
|
2565
|
+
* Date.civil(2009, 1, 2).step(Date.civil(2009, 1, 6), 2) do |date|
|
2566
|
+
* puts date
|
2567
|
+
* end
|
2568
|
+
* # Output:
|
2569
|
+
* # 2009-01-02
|
2570
|
+
* # 2009-01-04
|
2571
|
+
* # 2009-01-06
|
2572
|
+
*/
|
2573
|
+
static VALUE rhrd_step(int argc, VALUE *argv, VALUE self) {
|
2574
|
+
rhrd_t *d, *n, *newd;
|
2575
|
+
rhrdt_t *ndt;
|
2576
|
+
long step, limit, current;
|
2577
|
+
VALUE rlimit, new;
|
2578
|
+
Data_Get_Struct(self, rhrd_t, d);
|
2579
|
+
RHR_FILL_JD(d)
|
2580
|
+
|
2581
|
+
rb_need_block();
|
2582
|
+
switch(argc) {
|
2583
|
+
case 1:
|
2584
|
+
step = 1;
|
2585
|
+
break;
|
2586
|
+
case 2:
|
2587
|
+
step = NUM2LONG(argv[1]);
|
2588
|
+
break;
|
2589
|
+
default:
|
2590
|
+
rb_raise(rb_eArgError, "wrong number of arguments: %i for 2", argc);
|
2591
|
+
break;
|
2592
|
+
}
|
2593
|
+
|
2594
|
+
rlimit = argv[0];
|
2595
|
+
if (RTEST(rb_obj_is_kind_of(rlimit, rb_cNumeric))) {
|
2596
|
+
limit = NUM2LONG(rlimit);
|
2597
|
+
} else if (RTEST((rb_obj_is_kind_of(rlimit, rhrdt_class)))) {
|
2598
|
+
Data_Get_Struct(rlimit, rhrdt_t, ndt);
|
2599
|
+
RHRDT_FILL_JD(ndt)
|
2600
|
+
limit = ndt->jd;
|
2601
|
+
} else if (RTEST((rb_obj_is_kind_of(rlimit, rhrd_class)))) {
|
2602
|
+
Data_Get_Struct(rlimit, rhrd_t, n);
|
2603
|
+
RHR_FILL_JD(n)
|
2604
|
+
limit = n->jd;
|
2605
|
+
} else {
|
2606
|
+
rb_raise(rb_eTypeError, "expected numeric or date");
|
2607
|
+
}
|
2608
|
+
|
2609
|
+
current = d->jd;
|
2610
|
+
if (limit > current) {
|
2611
|
+
if (step > 0) {
|
2612
|
+
while(limit >= current) {
|
2613
|
+
new = Data_Make_Struct(rhrd_class, rhrd_t, NULL, free, newd);
|
2614
|
+
newd->jd = current;
|
2615
|
+
RHR_CHECK_JD(newd)
|
2616
|
+
newd->flags = RHR_HAVE_JD;
|
2617
|
+
current += step;
|
2618
|
+
rb_yield(new);
|
2619
|
+
}
|
2620
|
+
}
|
2621
|
+
} else if (limit < current) {
|
2622
|
+
if (step < 0) {
|
2623
|
+
while(limit <= current) {
|
2624
|
+
new = Data_Make_Struct(rhrd_class, rhrd_t, NULL, free, newd);
|
2625
|
+
newd->jd = current;
|
2626
|
+
RHR_CHECK_JD(newd)
|
2627
|
+
newd->flags = RHR_HAVE_JD;
|
2628
|
+
current += step;
|
2629
|
+
rb_yield(new);
|
2630
|
+
}
|
2631
|
+
}
|
2632
|
+
} else {
|
2633
|
+
rb_yield(self);
|
2634
|
+
}
|
2635
|
+
|
2636
|
+
return self;
|
2637
|
+
}
|
2638
|
+
|
2639
|
+
/* call-seq:
|
2640
|
+
* strftime() -> String <br />
|
2641
|
+
* strftime(format) -> String
|
2642
|
+
*
|
2643
|
+
* If no argument is provided, returns a string in ISO8601 format, just like
|
2644
|
+
* +to_s+. If an argument is provided, uses it as a format string and returns
|
2645
|
+
* a +String+ based on the format. The following formats parts are supported:
|
2646
|
+
*
|
2647
|
+
* %a :: The abbreviated day name (e.g. Fri)
|
2648
|
+
* %A :: The full day name (e.g. Friday)
|
2649
|
+
* %b, %h :: The abbreviated month name (e.g. Jan)
|
2650
|
+
* %B :: The full month name (e.g. January)
|
2651
|
+
* %c :: A full date and time representation (e.g. Fri Jan 02 13:29:39 2009)
|
2652
|
+
* %C :: The century of the year (e.g. 20)
|
2653
|
+
* %d :: The day of the month, with a leading zero if necessary (e.g. 02)
|
2654
|
+
* %e :: The day of the month, with a leading space if necessary (e.g. 2)
|
2655
|
+
* %F :: An ISO8601 date representation (e.g. 2009-01-02)
|
2656
|
+
* %g :: The last 2 digits of the commercial week year (e.g. 09)
|
2657
|
+
* %G :: The commercial week year (e.g. 2009)
|
2658
|
+
* %H :: The hour of the day in 24 hour format, with a leading zero if necessary (e.g. 13)
|
2659
|
+
* %I :: The hour of the day in 12 hour format (e.g. 01)
|
2660
|
+
* %j :: The day of the year (e.g. 002)
|
2661
|
+
* %k :: The hour of the day in 24 hour format, with a leading space if necessary (e.g. 13)
|
2662
|
+
* %l :: The hour of the day in 12 hour format, with a leading space if necessary (e.g. 13)
|
2663
|
+
* %L :: The number of milliseconds in the fractional second, with leading zeros if necessary (e.g. 079)
|
2664
|
+
* %m :: The month of the year (e.g. 01)
|
2665
|
+
* %M :: The minute of the hour (e.g. 29)
|
2666
|
+
* %n :: A newline (e.g. "\n")
|
2667
|
+
* %N :: The number of nanoseconds in the fractional second, with leading zeros if necessary (e.g. 079013023)
|
2668
|
+
* %p :: The meridian indicator, upcased (e.g. PM)
|
2669
|
+
* %P :: The meridian indicator, downcased (e.g. pm)
|
2670
|
+
* %Q :: The number of milliseconds since the unix epoch (e.g. 1230902979079)
|
2671
|
+
* %r :: A full time representation in 12 hour format (e.g. 1:29:39 PM)
|
2672
|
+
* %R :: An hour and minute representation in 24 hour format (e.g. 13:29)
|
2673
|
+
* %s :: The number of seconds since the unix epoch (e.g. 1230902979)
|
2674
|
+
* %S :: The second of the minute (e.g. 39)
|
2675
|
+
* %t :: A tab (e.g. "\t")
|
2676
|
+
* %T, %X :: A full time representation in 24 hour format (e.g. 13:29:39)
|
2677
|
+
* %u :: The commercial week day (e.g. 5)
|
2678
|
+
* %U :: The week number of the current year, with Sunday as the first day of the first week (e.g. 0)
|
2679
|
+
* %v :: A full date representation (e.g. 2-Jan-2009)
|
2680
|
+
* %V :: The commercial week (e.g. 01)
|
2681
|
+
* %w :: The day of the week, with Sunday as 0 and Saturday as 6 (e.g. 5)
|
2682
|
+
* %W :: The week number of the current year, with Monday as the first day of the first week (e.g. 0)
|
2683
|
+
* %x, %D :: A full date representation in month/day/year format (e.g. 01/02/09)
|
2684
|
+
* %y :: The last two digits of the year (e.g. 09)
|
2685
|
+
* %Y :: The year (e.g. 2009)
|
2686
|
+
* %z :: The offset from UTC, without a colon (e.g. +0000)
|
2687
|
+
* %Z :: The offset from UTC, with a colon (e.g. +00:00)
|
2688
|
+
* %+ :: A full date and time representation, including the offset (e.g. Fri Jan 2 13:29:39 +00:00 2009)
|
2689
|
+
*
|
2690
|
+
* All other formats (e.g. %f, %%) are handled by removing the leading percent sign. All other text is
|
2691
|
+
* passed through literally.
|
2692
|
+
*/
|
2693
|
+
static VALUE rhrd_strftime(int argc, VALUE *argv, VALUE self) {
|
2694
|
+
rhrd_t *d;
|
2695
|
+
rhrdt_t dt;
|
2696
|
+
VALUE r;
|
2697
|
+
|
2698
|
+
switch(argc) {
|
2699
|
+
case 0:
|
2700
|
+
return rhrd_to_s(self);
|
2701
|
+
case 1:
|
2702
|
+
r = rb_str_to_str(argv[0]);
|
2703
|
+
break;
|
2704
|
+
default:
|
2705
|
+
rb_raise(rb_eArgError, "wrong number of arguments: %i for 1", argc);
|
2706
|
+
break;
|
2707
|
+
}
|
2708
|
+
|
2709
|
+
Data_Get_Struct(self, rhrd_t, d);
|
2710
|
+
RHR_FILL_CIVIL(d)
|
2711
|
+
RHR_FILL_JD(d)
|
2712
|
+
memset(&dt, 0, sizeof(rhrdt_t));
|
2713
|
+
dt.jd = d->jd;
|
2714
|
+
dt.year = d->year;
|
2715
|
+
dt.month = d->month;
|
2716
|
+
dt.day = d->day;
|
2717
|
+
dt.flags = RHR_HAVE_CIVIL | RHR_HAVE_JD;
|
2718
|
+
return rhrd__strftime(&dt, RSTRING_PTR(r), RSTRING_LEN(r));
|
2719
|
+
}
|
2720
|
+
|
2721
|
+
/* call-seq:
|
2722
|
+
* to_s() -> String
|
2723
|
+
*
|
2724
|
+
* Returns the receiver as an ISO8601 formatted string.
|
2725
|
+
*
|
2726
|
+
* Date.civil(2009, 1, 2).to_s
|
2727
|
+
* # => "2009-01-02"
|
2728
|
+
*/
|
2729
|
+
static VALUE rhrd_to_s(VALUE self) {
|
2730
|
+
VALUE s;
|
2731
|
+
rhrd_t *d;
|
2732
|
+
int len;
|
2733
|
+
Data_Get_Struct(self, rhrd_t, d);
|
2734
|
+
RHR_FILL_CIVIL(d)
|
2735
|
+
|
2736
|
+
s = rb_str_buf_new(128);
|
2737
|
+
len = snprintf(RSTRING_PTR(s), 128, "%04li-%02hhi-%02hhi",
|
2738
|
+
d->year, d->month, d->day);
|
2739
|
+
if (len == -1 || len > 127) {
|
2740
|
+
rb_raise(rb_eNoMemError, "in Date#to_s (in snprintf)");
|
2741
|
+
}
|
2742
|
+
|
2743
|
+
RHR_RETURN_RESIZED_STR(s, len)
|
2744
|
+
}
|
2745
|
+
|
2746
|
+
/* call-seq:
|
2747
|
+
* upto(target){|date|} -> Date
|
2748
|
+
*
|
2749
|
+
* Equivalent to calling +step+ with the +target+ as the first argument.
|
2750
|
+
* Returns self.
|
2751
|
+
*
|
2752
|
+
* Date.civil(2009, 1, 1).upto(Date.civil(2009, 1, 2)) do |date|
|
2753
|
+
* puts date
|
2754
|
+
* end
|
2755
|
+
* # Output:
|
2756
|
+
* # 2009-01-01
|
2757
|
+
* # 2009-01-02
|
2758
|
+
*/
|
2759
|
+
static VALUE rhrd_upto(VALUE self, VALUE other) {
|
2760
|
+
VALUE argv[1];
|
2761
|
+
argv[0] = other;
|
2762
|
+
return rhrd_step(1, argv, self);
|
2763
|
+
}
|
2764
|
+
|
2765
|
+
/* call-seq:
|
2766
|
+
* wday() -> Integer
|
2767
|
+
*
|
2768
|
+
* Returns the day of the week as an +Integer+, where Sunday
|
2769
|
+
* is 0 and Saturday is 6. Example:
|
2770
|
+
*
|
2771
|
+
* Date.civil(2009, 1, 2).wday
|
2772
|
+
* # => 5
|
2773
|
+
*/
|
2774
|
+
static VALUE rhrd_wday(VALUE self) {
|
2775
|
+
rhrd_t *d;
|
2776
|
+
Data_Get_Struct(self, rhrd_t, d);
|
2777
|
+
RHR_FILL_JD(d)
|
2778
|
+
return LONG2NUM(rhrd__jd_to_wday(d->jd));
|
2779
|
+
}
|
2780
|
+
|
2781
|
+
/* call-seq:
|
2782
|
+
* yday() -> Integer
|
2783
|
+
*
|
2784
|
+
* Returns the day of the year as an +Integer+, where January
|
2785
|
+
* 1st is 1 and December 31 is 365 (or 366 if the year is a leap
|
2786
|
+
* year). Example:
|
2787
|
+
*
|
2788
|
+
* Date.civil(2009, 2, 2).yday
|
2789
|
+
* # => 33
|
2790
|
+
*/
|
2791
|
+
static VALUE rhrd_yday(VALUE self) {
|
2792
|
+
rhrd_t *d;
|
2793
|
+
Data_Get_Struct(self, rhrd_t, d);
|
2794
|
+
RHR_FILL_CIVIL(d)
|
2795
|
+
return LONG2NUM(rhrd__ordinal_day(d->year, d->month, d->day));
|
2796
|
+
}
|
2797
|
+
|
2798
|
+
/* call-seq:
|
2799
|
+
* year() -> Integer
|
2800
|
+
*
|
2801
|
+
* Returns the year as an +Integer+. Example:
|
2802
|
+
*
|
2803
|
+
* Date.civil(2009, 1, 2).year
|
2804
|
+
* # => 2009
|
2805
|
+
*/
|
2806
|
+
static VALUE rhrd_year(VALUE self) {
|
2807
|
+
rhrd_t *d;
|
2808
|
+
Data_Get_Struct(self, rhrd_t, d);
|
2809
|
+
RHR_FILL_CIVIL(d)
|
2810
|
+
return LONG2NUM(d->year);
|
2811
|
+
}
|
2812
|
+
|
2813
|
+
/* Ruby instance operator methods */
|
2814
|
+
|
2815
|
+
/* call-seq:
|
2816
|
+
* >>(n) -> Date
|
2817
|
+
*
|
2818
|
+
* Returns a +Date+ that is +n+ months after the receiver. +n+
|
2819
|
+
* can be negative, in which case it returns a +Date+ before
|
2820
|
+
* the receiver.
|
2821
|
+
*
|
2822
|
+
* Date.civil(2009, 1, 2) >> 2
|
2823
|
+
* # => #<Date 2009-01-02>
|
2824
|
+
* Date.civil(2009, 1, 2) >> -2
|
2825
|
+
* # => #<Date 2008-11-02>
|
2826
|
+
*/
|
2827
|
+
static VALUE rhrd_op_right_shift(VALUE self, VALUE other) {
|
2828
|
+
return rhrd__add_months(self, NUM2LONG(other));
|
2829
|
+
}
|
2830
|
+
|
2831
|
+
/* call-seq:
|
2832
|
+
* <<(n) -> Date
|
2833
|
+
*
|
2834
|
+
* Returns a +Date+ that is +n+ months before the receiver. +n+
|
2835
|
+
* can be negative, in which case it returns a +Date+ after
|
2836
|
+
* the receiver.
|
2837
|
+
*
|
2838
|
+
* Date.civil(2009, 1, 2) << 2
|
2839
|
+
* # => #<Date 2008-11-02>
|
2840
|
+
* Date.civil(2009, 1, 2) << -2
|
2841
|
+
* # => #<Date 2009-01-02>
|
2842
|
+
*/
|
2843
|
+
static VALUE rhrd_op_left_shift(VALUE self, VALUE other) {
|
2844
|
+
return rhrd__add_months(self, -NUM2LONG(other));
|
2845
|
+
}
|
2846
|
+
|
2847
|
+
/* call-seq:
|
2848
|
+
* +(n) -> Date
|
2849
|
+
*
|
2850
|
+
* Returns a +Date+ that is +n+ days after the receiver. +n+
|
2851
|
+
* can be negative, in which case it returns a +Date+ before
|
2852
|
+
* the receiver.
|
2853
|
+
*
|
2854
|
+
* Date.civil(2009, 1, 2) + 2
|
2855
|
+
* # => #<Date 2009-01-04>
|
2856
|
+
* Date.civil(2009, 1, 2) + -2
|
2857
|
+
* # => #<Date 2008-12-31>
|
2858
|
+
*/
|
2859
|
+
static VALUE rhrd_op_plus(VALUE self, VALUE other) {
|
2860
|
+
return rhrd__add_days(self, NUM2LONG(other));
|
2861
|
+
}
|
2862
|
+
|
2863
|
+
/* call-seq:
|
2864
|
+
* -(n) -> Date <br />
|
2865
|
+
* -(date) -> Integer <br />
|
2866
|
+
* -(datetime) -> Float
|
2867
|
+
*
|
2868
|
+
* If a +Numeric+ argument is given, it is treated as an +Integer+,
|
2869
|
+
* and the number of days it represents is substracted from the
|
2870
|
+
* receiver to return a new +Date+ object. +n+ can be negative, in
|
2871
|
+
* which case the +Date+ returned will be after the receiver.
|
2872
|
+
*
|
2873
|
+
* If a +Date+ argument is given, returns the number of days
|
2874
|
+
* between the current date and the argument as an +Integer+.
|
2875
|
+
*
|
2876
|
+
* If a +DateTime+ argument is given, returns the number of days
|
2877
|
+
* between the current date and the argument as a +Float+, and
|
2878
|
+
* considers the receiver to be in the same time zone as the
|
2879
|
+
* argument.
|
2880
|
+
*
|
2881
|
+
* Other types of arguments raise a +TypeError+.
|
2882
|
+
*
|
2883
|
+
* Date.civil(2009, 1, 2) - 2
|
2884
|
+
* # => #<Date 2008-12-31>
|
2885
|
+
* Date.civil(2009, 1, 2) - Date.civil(2009, 1, 1)
|
2886
|
+
* # => 1
|
2887
|
+
* Date.civil(2009, 1, 2) - DateTime.civil(2009, 1, 3, 12)
|
2888
|
+
* # => -1.5
|
2889
|
+
*/
|
2890
|
+
static VALUE rhrd_op_minus(VALUE self, VALUE other) {
|
2891
|
+
rhrd_t *d;
|
2892
|
+
rhrd_t *newd;
|
2893
|
+
rhrdt_t *newdt;
|
2894
|
+
Data_Get_Struct(self, rhrd_t, d);
|
2895
|
+
|
2896
|
+
if (RTEST(rb_obj_is_kind_of(other, rb_cNumeric))) {
|
2897
|
+
return rhrd__add_days(self, -NUM2LONG(other));
|
2898
|
+
}
|
2899
|
+
if (RTEST((rb_obj_is_kind_of(other, rhrdt_class)))) {
|
2900
|
+
Data_Get_Struct(other, rhrdt_t, newdt);
|
2901
|
+
RHR_FILL_JD(d)
|
2902
|
+
RHRDT_FILL_JD(newdt)
|
2903
|
+
RHRDT_FILL_NANOS(newdt)
|
2904
|
+
return rb_float_new(d->jd - (newdt->jd + newdt->nanos/RHR_NANOS_PER_DAYD));
|
2905
|
+
}
|
2906
|
+
if (RTEST((rb_obj_is_kind_of(other, rhrd_class)))) {
|
2907
|
+
Data_Get_Struct(other, rhrd_t, newd);
|
2908
|
+
RHR_FILL_JD(d)
|
2909
|
+
RHR_FILL_JD(newd)
|
2910
|
+
return LONG2NUM(rhrd__safe_add_long(d->jd, -newd->jd));
|
2911
|
+
}
|
2912
|
+
rb_raise(rb_eTypeError, "expected numeric or date");
|
2913
|
+
}
|
2914
|
+
|
2915
|
+
/* call-seq:
|
2916
|
+
* ===(other) -> true or false
|
2917
|
+
*
|
2918
|
+
* If +other+ is a +Date+, returns +true+ if +other+ is the
|
2919
|
+
* same date as the receiver, or +false+ otherwise.
|
2920
|
+
*
|
2921
|
+
* If +other+ is a +DateTime+, return +true+ if +other has the same
|
2922
|
+
* julian date as the receiver, or +false+ otherwise.
|
2923
|
+
*
|
2924
|
+
* If +other+ is a +Numeric+, convert it to an +Integer+ and return
|
2925
|
+
* +true+ if it is equal to the receiver's julian date, or +false+
|
2926
|
+
* otherwise.
|
2927
|
+
*/
|
2928
|
+
static VALUE rhrd_op_relationship(VALUE self, VALUE other) {
|
2929
|
+
rhrd_t *d, *o;
|
2930
|
+
rhrdt_t *odt;
|
2931
|
+
long diff = 1;
|
2932
|
+
Data_Get_Struct(self, rhrd_t, d);
|
2933
|
+
|
2934
|
+
if (RTEST(rb_obj_is_kind_of(other, rhrdt_class))) {
|
2935
|
+
Data_Get_Struct(other, rhrdt_t, odt);
|
2936
|
+
RHR_FILL_JD(d)
|
2937
|
+
RHRDT_FILL_JD(odt)
|
2938
|
+
diff = d->jd != odt->jd;
|
2939
|
+
} else if (RTEST(rb_obj_is_kind_of(other, rhrd_class))) {
|
2940
|
+
Data_Get_Struct(other, rhrd_t, o);
|
2941
|
+
diff = rhrd__spaceship(d, o);
|
2942
|
+
} else if (RTEST((rb_obj_is_kind_of(other, rb_cNumeric)))) {
|
2943
|
+
diff = NUM2LONG(other);
|
2944
|
+
RHR_FILL_JD(d)
|
2945
|
+
RHR_SPACE_SHIP(diff, d->jd, diff)
|
2946
|
+
}
|
2947
|
+
return diff == 0 ? Qtrue : Qfalse;
|
2948
|
+
}
|
2949
|
+
|
2950
|
+
/* call-seq:
|
2951
|
+
* <=>(other) -> -1, 0, 1, or nil
|
2952
|
+
*
|
2953
|
+
* If +other+ is a +Date+, returns -1 if +other+ is before the
|
2954
|
+
* the receiver chronologically, 0 if +other+ is the same date as the receiver,
|
2955
|
+
* or 1 if +other+ is after the receiver chronologically.
|
2956
|
+
*
|
2957
|
+
* If +other+ is a +DateTime+, return 0 if +other+ has the same
|
2958
|
+
* julian date as the receiver and no fractional part, -1 if +other+ has a julian date
|
2959
|
+
* less than the receiver's, and 1 if +other+ has a julian date
|
2960
|
+
* greater than the receiver's or a julian date the same as the
|
2961
|
+
* receiver's and a fractional part.
|
2962
|
+
*
|
2963
|
+
* If +other+ is a +Numeric+, convert it to an integer and compare
|
2964
|
+
* it to the receiver's julian date.
|
2965
|
+
*
|
2966
|
+
* For an unrecognized type, return +nil+.
|
2967
|
+
*/
|
2968
|
+
static VALUE rhrd_op_spaceship(VALUE self, VALUE other) {
|
2969
|
+
rhrd_t *d, *o;
|
2970
|
+
rhrdt_t *odt;
|
2971
|
+
long diff;
|
2972
|
+
Data_Get_Struct(self, rhrd_t, d);
|
2973
|
+
|
2974
|
+
if (RTEST(rb_obj_is_kind_of(other, rhrdt_class))) {
|
2975
|
+
Data_Get_Struct(other, rhrdt_t, odt);
|
2976
|
+
RHR_FILL_JD(d)
|
2977
|
+
RHRDT_FILL_JD(odt)
|
2978
|
+
RHR_SPACE_SHIP(diff, d->jd, odt->jd)
|
2979
|
+
if (diff == 0) {
|
2980
|
+
RHRDT_FILL_NANOS(odt)
|
2981
|
+
RHR_SPACE_SHIP(diff, 0, odt->nanos)
|
2982
|
+
}
|
2983
|
+
return LONG2NUM(diff);
|
2984
|
+
} else if (RTEST(rb_obj_is_kind_of(other, rhrd_class))) {
|
2985
|
+
Data_Get_Struct(other, rhrd_t, o);
|
2986
|
+
return LONG2NUM(rhrd__spaceship(d, o));
|
2987
|
+
} else if (RTEST((rb_obj_is_kind_of(other, rb_cNumeric)))) {
|
2988
|
+
diff = NUM2LONG(other);
|
2989
|
+
RHR_FILL_JD(d)
|
2990
|
+
RHR_SPACE_SHIP(diff, d->jd, diff)
|
2991
|
+
return LONG2NUM(diff);
|
2992
|
+
}
|
2993
|
+
return Qnil;
|
2994
|
+
}
|
2995
|
+
|
2996
|
+
#ifdef RUBY19
|
2997
|
+
|
2998
|
+
/* Ruby 1.9 helper methods */
|
2999
|
+
|
3000
|
+
/* Add n number of years to the given ruby Date object. n can
|
3001
|
+
* be negative to subtract years. Returns a new ruby Date
|
3002
|
+
* object */
|
3003
|
+
VALUE rhrd__add_years(VALUE self, long n) {
|
3004
|
+
rhrd_t *d;
|
3005
|
+
rhrd_t *newd;
|
3006
|
+
VALUE new;
|
3007
|
+
Data_Get_Struct(self, rhrd_t, d);
|
3008
|
+
|
3009
|
+
new = Data_Make_Struct(rhrd_class, rhrd_t, NULL, free, newd);
|
3010
|
+
RHR_FILL_CIVIL(d)
|
3011
|
+
newd->year = rhrd__safe_add_long(n, d->year);
|
3012
|
+
newd->month = d->month;
|
3013
|
+
if(d->month == 2 && d->day == 29) {
|
3014
|
+
newd->day = rhrd__leap_year(newd->year) ? 29 : 28;
|
3015
|
+
} else {
|
3016
|
+
newd->day = d->day;
|
3017
|
+
}
|
3018
|
+
|
3019
|
+
RHR_CHECK_CIVIL(newd)
|
3020
|
+
newd->flags = RHR_HAVE_CIVIL;
|
3021
|
+
return new;
|
3022
|
+
}
|
3023
|
+
|
3024
|
+
/* Return ruby true if the given date falls on the given
|
3025
|
+
* week day number, or ruby false otherwise. */
|
3026
|
+
VALUE rhrd__day_q(VALUE self, long day) {
|
3027
|
+
rhrd_t *d;
|
3028
|
+
Data_Get_Struct(self, rhrd_t, d);
|
3029
|
+
RHR_FILL_JD(d)
|
3030
|
+
return rhrd__jd_to_wday(d->jd) == day ? Qtrue : Qfalse;
|
3031
|
+
}
|
3032
|
+
|
3033
|
+
/* Ruby 1.9 class methods */
|
3034
|
+
|
3035
|
+
/* call-seq:
|
3036
|
+
* [ruby 1-9 only] <br />
|
3037
|
+
* httpdate() -> Date <br />
|
3038
|
+
* httpdate(str, sg=nil) -> Date
|
3039
|
+
*
|
3040
|
+
* If no argument is given, returns a +Date+ for julian day 0.
|
3041
|
+
* If an argument is given, it should be a string that is
|
3042
|
+
* parsed using +_httpdate+, returning a +Date+ or raising
|
3043
|
+
* an +ArgumentError+ if the string is not in a valid format
|
3044
|
+
* or the date it represents is not a valid date.
|
3045
|
+
* Ignores the 2nd argument.
|
3046
|
+
* Example:
|
3047
|
+
*
|
3048
|
+
* Date.httpdate("Fri, 02 Jan 2009 00:00:00 GMT")
|
3049
|
+
* # => #<Date 2009-01-02>
|
3050
|
+
*/
|
3051
|
+
static VALUE rhrd_s_httpdate(int argc, VALUE *argv, VALUE klass) {
|
3052
|
+
rhrd_t *d;
|
3053
|
+
VALUE rd;
|
3054
|
+
|
3055
|
+
switch(argc) {
|
3056
|
+
case 0:
|
3057
|
+
rd = Data_Make_Struct(klass, rhrd_t, NULL, free, d);
|
3058
|
+
d->flags = RHR_HAVE_JD;
|
3059
|
+
return rd;
|
3060
|
+
case 1:
|
3061
|
+
case 2:
|
3062
|
+
return rhrd__from_hash(rb_funcall(klass, rhrd_id__httpdate, 1, argv[0]));
|
3063
|
+
default:
|
3064
|
+
rb_raise(rb_eArgError, "wrong number of arguments (%i for 2)", argc);
|
3065
|
+
break;
|
3066
|
+
}
|
3067
|
+
}
|
3068
|
+
|
3069
|
+
/* call-seq:
|
3070
|
+
* [ruby 1-9 only] <br />
|
3071
|
+
* iso8601() -> Date <br />
|
3072
|
+
* iso8601(str, sg=nil) -> Date
|
3073
|
+
*
|
3074
|
+
* If no argument is given, returns a +Date+ for julian day 0.
|
3075
|
+
* If an argument is given, it should be a string that is
|
3076
|
+
* parsed using +_iso8601+, returning a +Date+ or raising
|
3077
|
+
* an +ArgumentError+ if the string is not in a valid format
|
3078
|
+
* or the date it represents is not a valid date.
|
3079
|
+
* Ignores the 2nd argument.
|
3080
|
+
* Example:
|
3081
|
+
*
|
3082
|
+
* Date.iso8601("2009-01-02")
|
3083
|
+
* # => #<Date 2009-01-02>
|
3084
|
+
*/
|
3085
|
+
static VALUE rhrd_s_iso8601(int argc, VALUE *argv, VALUE klass) {
|
3086
|
+
rhrd_t *d;
|
3087
|
+
VALUE rd;
|
3088
|
+
|
3089
|
+
switch(argc) {
|
3090
|
+
case 0:
|
3091
|
+
rd = Data_Make_Struct(klass, rhrd_t, NULL, free, d);
|
3092
|
+
d->flags = RHR_HAVE_JD;
|
3093
|
+
return rd;
|
3094
|
+
case 1:
|
3095
|
+
case 2:
|
3096
|
+
return rhrd__from_hash(rb_funcall(klass, rhrd_id__iso8601, 1, argv[0]));
|
3097
|
+
default:
|
3098
|
+
rb_raise(rb_eArgError, "wrong number of arguments (%i for 2)", argc);
|
3099
|
+
break;
|
3100
|
+
}
|
3101
|
+
}
|
3102
|
+
|
3103
|
+
/* call-seq:
|
3104
|
+
* [ruby 1-9 only] <br />
|
3105
|
+
* jisx0301() -> Date <br />
|
3106
|
+
* jisx0301(str, sg=nil) -> Date
|
3107
|
+
*
|
3108
|
+
* If no argument is given, returns a +Date+ for julian day 0.
|
3109
|
+
* If an argument is given, it should be a string that is
|
3110
|
+
* parsed using +_jisx0301+, returning a +Date+ or raising
|
3111
|
+
* an +ArgumentError+ if the string is not in a valid format
|
3112
|
+
* or the date it represents is not a valid date.
|
3113
|
+
* Ignores the 2nd argument.
|
3114
|
+
* Example:
|
3115
|
+
*
|
3116
|
+
* Date.iso8601("H21.01.02")
|
3117
|
+
* # => #<Date 2009-01-02>
|
3118
|
+
*/
|
3119
|
+
static VALUE rhrd_s_jisx0301(int argc, VALUE *argv, VALUE klass) {
|
3120
|
+
rhrd_t *d;
|
3121
|
+
VALUE rd;
|
3122
|
+
|
3123
|
+
switch(argc) {
|
3124
|
+
case 0:
|
3125
|
+
rd = Data_Make_Struct(klass, rhrd_t, NULL, free, d);
|
3126
|
+
d->flags = RHR_HAVE_JD;
|
3127
|
+
return rd;
|
3128
|
+
case 1:
|
3129
|
+
case 2:
|
3130
|
+
return rhrd__from_hash(rb_funcall(klass, rhrd_id__jisx0301, 1, argv[0]));
|
3131
|
+
default:
|
3132
|
+
rb_raise(rb_eArgError, "wrong number of arguments (%i for 2)", argc);
|
3133
|
+
break;
|
3134
|
+
}
|
3135
|
+
}
|
3136
|
+
|
3137
|
+
/* call-seq:
|
3138
|
+
* [ruby 1-9 only] <br />
|
3139
|
+
* rfc2822() -> Date <br />
|
3140
|
+
* rfc2822(str, sg=nil) -> Date
|
3141
|
+
*
|
3142
|
+
* If no argument is given, returns a +Date+ for julian day 0.
|
3143
|
+
* If an argument is given, it should be a string that is
|
3144
|
+
* parsed using +_rfc2822+, returning a +Date+ or raising
|
3145
|
+
* an +ArgumentError+ if the string is not in a valid format
|
3146
|
+
* or the date it represents is not a valid date.
|
3147
|
+
* Ignores the 2nd argument.
|
3148
|
+
* Example:
|
3149
|
+
*
|
3150
|
+
* Date.rfc2822("Fri, 2 Jan 2009 00:00:00 +0000")
|
3151
|
+
* # => #<Date 2009-01-02>
|
3152
|
+
*/
|
3153
|
+
static VALUE rhrd_s_rfc2822(int argc, VALUE *argv, VALUE klass) {
|
3154
|
+
rhrd_t *d;
|
3155
|
+
VALUE rd;
|
3156
|
+
|
3157
|
+
switch(argc) {
|
3158
|
+
case 0:
|
3159
|
+
rd = Data_Make_Struct(klass, rhrd_t, NULL, free, d);
|
3160
|
+
d->flags = RHR_HAVE_JD;
|
3161
|
+
return rd;
|
3162
|
+
case 1:
|
3163
|
+
case 2:
|
3164
|
+
return rhrd__from_hash(rb_funcall(klass, rhrd_id__rfc2822, 1, argv[0]));
|
3165
|
+
default:
|
3166
|
+
rb_raise(rb_eArgError, "wrong number of arguments (%i for 2)", argc);
|
3167
|
+
break;
|
3168
|
+
}
|
3169
|
+
}
|
3170
|
+
|
3171
|
+
/* call-seq:
|
3172
|
+
* [ruby 1-9 only] <br />
|
3173
|
+
* rfc3339() -> Date <br />
|
3174
|
+
* rfc3339(str, sg=nil) -> Date
|
3175
|
+
*
|
3176
|
+
* If no argument is given, returns a +Date+ for julian day 0.
|
3177
|
+
* If an argument is given, it should be a string that is
|
3178
|
+
* parsed using +_rfc3339+, returning a +Date+ or raising
|
3179
|
+
* an +ArgumentError+ if the string is not in a valid format
|
3180
|
+
* or the date it represents is not a valid date.
|
3181
|
+
* Ignores the 2nd argument.
|
3182
|
+
* Example:
|
3183
|
+
*
|
3184
|
+
* Date.rfc3339("2009-01-02T00:00:00+00:00")
|
3185
|
+
* # => #<Date 2009-01-02>
|
3186
|
+
*/
|
3187
|
+
static VALUE rhrd_s_rfc3339(int argc, VALUE *argv, VALUE klass) {
|
3188
|
+
rhrd_t *d;
|
3189
|
+
VALUE rd;
|
3190
|
+
|
3191
|
+
switch(argc) {
|
3192
|
+
case 0:
|
3193
|
+
rd = Data_Make_Struct(klass, rhrd_t, NULL, free, d);
|
3194
|
+
d->flags = RHR_HAVE_JD;
|
3195
|
+
return rd;
|
3196
|
+
case 1:
|
3197
|
+
case 2:
|
3198
|
+
return rhrd__from_hash(rb_funcall(klass, rhrd_id__rfc3339, 1, argv[0]));
|
3199
|
+
default:
|
3200
|
+
rb_raise(rb_eArgError, "wrong number of arguments (%i for 2)", argc);
|
3201
|
+
break;
|
3202
|
+
}
|
3203
|
+
}
|
3204
|
+
|
3205
|
+
/* call-seq:
|
3206
|
+
* [ruby 1-9 only] <br />
|
3207
|
+
* xmlschema() -> Date <br />
|
3208
|
+
* xmlschema(str, sg=nil) -> Date
|
3209
|
+
*
|
3210
|
+
* If no argument is given, returns a +Date+ for julian day 0.
|
3211
|
+
* If an argument is given, it should be a string that is
|
3212
|
+
* parsed using +_xmlschema+, returning a +Date+ or raising
|
3213
|
+
* an +ArgumentError+ if the string is not in a valid format
|
3214
|
+
* or the date it represents is not a valid date.
|
3215
|
+
* Ignores the 2nd argument.
|
3216
|
+
* Example:
|
3217
|
+
*
|
3218
|
+
* Date.xmlschema("2009-01-02")
|
3219
|
+
* # => #<Date 2009-01-02>
|
3220
|
+
*/
|
3221
|
+
static VALUE rhrd_s_xmlschema(int argc, VALUE *argv, VALUE klass) {
|
3222
|
+
rhrd_t *d;
|
3223
|
+
VALUE rd;
|
3224
|
+
|
3225
|
+
switch(argc) {
|
3226
|
+
case 0:
|
3227
|
+
rd = Data_Make_Struct(klass, rhrd_t, NULL, free, d);
|
3228
|
+
d->flags = RHR_HAVE_JD;
|
3229
|
+
return rd;
|
3230
|
+
case 1:
|
3231
|
+
case 2:
|
3232
|
+
return rhrd__from_hash(rb_funcall(klass, rhrd_id__xmlschema, 1, argv[0]));
|
3233
|
+
default:
|
3234
|
+
rb_raise(rb_eArgError, "wrong number of arguments (%i for 2)", argc);
|
3235
|
+
break;
|
3236
|
+
}
|
3237
|
+
}
|
3238
|
+
|
3239
|
+
/* Ruby 1.9 instance methods */
|
3240
|
+
|
3241
|
+
/* call-seq:
|
3242
|
+
* [ruby 1-9 only] <br />
|
3243
|
+
* httpdate() -> String
|
3244
|
+
*
|
3245
|
+
* Returns the receiver as a +String+ in HTTP format. Example:
|
3246
|
+
*
|
3247
|
+
* Date.civil(2009, 1, 2).httpdate
|
3248
|
+
* # => "Fri, 02 Jan 2009 00:00:00 GMT"
|
3249
|
+
*/
|
3250
|
+
static VALUE rhrd_httpdate(VALUE self) {
|
3251
|
+
VALUE s;
|
3252
|
+
rhrd_t *d;
|
3253
|
+
int len;
|
3254
|
+
Data_Get_Struct(self, rhrd_t, d);
|
3255
|
+
RHR_FILL_CIVIL(d)
|
3256
|
+
RHR_FILL_JD(d)
|
3257
|
+
|
3258
|
+
s = rb_str_buf_new(128);
|
3259
|
+
len = snprintf(RSTRING_PTR(s), 128, "%s, %02hhi %s %04li 00:00:00 GMT",
|
3260
|
+
rhrd__abbr_day_names[rhrd__jd_to_wday(d->jd)],
|
3261
|
+
d->day,
|
3262
|
+
rhrd__abbr_month_names[d->month],
|
3263
|
+
d->year);
|
3264
|
+
if (len == -1 || len > 127) {
|
3265
|
+
rb_raise(rb_eNoMemError, "in Date#httpdate (in snprintf)");
|
3266
|
+
}
|
3267
|
+
|
3268
|
+
RHR_RETURN_RESIZED_STR(s, len)
|
3269
|
+
}
|
3270
|
+
|
3271
|
+
/* call-seq:
|
3272
|
+
* [ruby 1-9 only] <br />
|
3273
|
+
* jisx0301() -> String
|
3274
|
+
*
|
3275
|
+
* Returns the receiver as a +String+ in JIS X 0301 format. Example:
|
3276
|
+
*
|
3277
|
+
* Date.civil(2009, 1, 2).jisx0301
|
3278
|
+
* # => "H21.01.02"
|
3279
|
+
*/
|
3280
|
+
static VALUE rhrd_jisx0301(VALUE self) {
|
3281
|
+
VALUE s;
|
3282
|
+
rhrd_t *d;
|
3283
|
+
int len;
|
3284
|
+
char c;
|
3285
|
+
long year;
|
3286
|
+
Data_Get_Struct(self, rhrd_t, d);
|
3287
|
+
RHR_FILL_CIVIL(d)
|
3288
|
+
RHR_FILL_JD(d)
|
3289
|
+
|
3290
|
+
s = rb_str_buf_new(128);
|
3291
|
+
if (d->jd < 2405160) {
|
3292
|
+
len = snprintf(RSTRING_PTR(s), 128, "%04li-%02hhi-%02hhi", d->year, d->month, d->day);
|
3293
|
+
} else {
|
3294
|
+
if (d->jd >= 2447535) {
|
3295
|
+
c = 'H';
|
3296
|
+
year = d->year - 1988;
|
3297
|
+
} else if (d->jd >= 2424875) {
|
3298
|
+
c = 'S';
|
3299
|
+
year = d->year - 1925;
|
3300
|
+
} else if (d->jd >= 2419614) {
|
3301
|
+
c = 'T';
|
3302
|
+
year = d->year - 1911;
|
3303
|
+
} else {
|
3304
|
+
c = 'M';
|
3305
|
+
year = d->year - 1867;
|
3306
|
+
}
|
3307
|
+
len = snprintf(RSTRING_PTR(s), 128, "%c%02li.%02hhi.%02hhi", c, year, d->month, d->day);
|
3308
|
+
}
|
3309
|
+
if (len == -1 || len > 127) {
|
3310
|
+
rb_raise(rb_eNoMemError, "in Date#jisx0301 (in snprintf)");
|
3311
|
+
}
|
3312
|
+
|
3313
|
+
RHR_RETURN_RESIZED_STR(s, len)
|
3314
|
+
}
|
3315
|
+
|
3316
|
+
/* call-seq:
|
3317
|
+
* [ruby 1-9 only] <br />
|
3318
|
+
* next_day(n=1) -> Date
|
3319
|
+
*
|
3320
|
+
* Returns a +Date+ +n+ days after the receiver. If +n+ is negative,
|
3321
|
+
* returns a +Date+ before the receiver.
|
3322
|
+
*
|
3323
|
+
* Date.civil(2009, 1, 2).next_day
|
3324
|
+
* # => #<Date 2009-01-03>
|
3325
|
+
* Date.civil(2009, 1, 2).next_day(2)
|
3326
|
+
* # => #<Date 2009-01-04>
|
3327
|
+
*/
|
3328
|
+
static VALUE rhrd_next_day(int argc, VALUE *argv, VALUE self) {
|
3329
|
+
long i;
|
3330
|
+
|
3331
|
+
switch(argc) {
|
3332
|
+
case 0:
|
3333
|
+
i = 1;
|
3334
|
+
break;
|
3335
|
+
case 1:
|
3336
|
+
i = NUM2LONG(argv[0]);
|
3337
|
+
break;
|
3338
|
+
default:
|
3339
|
+
rb_raise(rb_eArgError, "wrong number of arguments: %i for 1", argc);
|
3340
|
+
break;
|
3341
|
+
}
|
3342
|
+
|
3343
|
+
return rhrd__add_days(self, i);
|
3344
|
+
}
|
3345
|
+
|
3346
|
+
/* call-seq:
|
3347
|
+
* [ruby 1-9 only] <br />
|
3348
|
+
* next_month(n=1) -> Date
|
3349
|
+
*
|
3350
|
+
* Returns a +Date+ +n+ months after the receiver. If +n+ is negative,
|
3351
|
+
* returns a +Date+ before the receiver.
|
3352
|
+
*
|
3353
|
+
* Date.civil(2009, 1, 2).next_month
|
3354
|
+
* # => #<Date 2009-02-02>
|
3355
|
+
* Date.civil(2009, 1, 2).next_month(2)
|
3356
|
+
* # => #<Date 2009-03-02>
|
3357
|
+
*/
|
3358
|
+
static VALUE rhrd_next_month(int argc, VALUE *argv, VALUE self) {
|
3359
|
+
long i;
|
3360
|
+
|
3361
|
+
switch(argc) {
|
3362
|
+
case 0:
|
3363
|
+
i = 1;
|
3364
|
+
break;
|
3365
|
+
case 1:
|
3366
|
+
i = NUM2LONG(argv[0]);
|
3367
|
+
break;
|
3368
|
+
default:
|
3369
|
+
rb_raise(rb_eArgError, "wrong number of arguments: %i for 1", argc);
|
3370
|
+
break;
|
3371
|
+
}
|
3372
|
+
|
3373
|
+
return rhrd__add_months(self, i);
|
3374
|
+
}
|
3375
|
+
|
3376
|
+
/* call-seq:
|
3377
|
+
* [ruby 1-9 only] <br />
|
3378
|
+
* next_year(n=1) -> Date
|
3379
|
+
*
|
3380
|
+
* Returns a +Date+ +n+ years after the receiver. If +n+ is negative,
|
3381
|
+
* returns a +Date+ before the receiver.
|
3382
|
+
*
|
3383
|
+
* Date.civil(2009, 1, 2).next_year
|
3384
|
+
* # => #<Date 2010-01-02>
|
3385
|
+
* Date.civil(2009, 1, 2).next_year(2)
|
3386
|
+
* # => #<Date 2011-01-02>
|
3387
|
+
*/
|
3388
|
+
static VALUE rhrd_next_year(int argc, VALUE *argv, VALUE self) {
|
3389
|
+
long i;
|
3390
|
+
|
3391
|
+
switch(argc) {
|
3392
|
+
case 0:
|
3393
|
+
i = 1;
|
3394
|
+
break;
|
3395
|
+
case 1:
|
3396
|
+
i = NUM2LONG(argv[0]);
|
3397
|
+
break;
|
3398
|
+
default:
|
3399
|
+
rb_raise(rb_eArgError, "wrong number of arguments: %i for 1", argc);
|
3400
|
+
break;
|
3401
|
+
}
|
3402
|
+
|
3403
|
+
return rhrd__add_years(self, i);
|
3404
|
+
}
|
3405
|
+
|
3406
|
+
/* call-seq:
|
3407
|
+
* [ruby 1-9 only] <br />
|
3408
|
+
* prev_day(n=1) -> Date
|
3409
|
+
*
|
3410
|
+
* Returns a +Date+ +n+ days before the receiver. If +n+ is negative,
|
3411
|
+
* returns a +Date+ after the receiver.
|
3412
|
+
*
|
3413
|
+
* Date.civil(2009, 1, 2).prev_day
|
3414
|
+
* # => #<Date 2009-01-01>
|
3415
|
+
* Date.civil(2009, 1, 2).prev_day(2)
|
3416
|
+
* # => #<Date 2008-12-31>
|
3417
|
+
*/
|
3418
|
+
static VALUE rhrd_prev_day(int argc, VALUE *argv, VALUE self) {
|
3419
|
+
long i;
|
3420
|
+
|
3421
|
+
switch(argc) {
|
3422
|
+
case 0:
|
3423
|
+
i = -1;
|
3424
|
+
break;
|
3425
|
+
case 1:
|
3426
|
+
i = -NUM2LONG(argv[0]);
|
3427
|
+
break;
|
3428
|
+
default:
|
3429
|
+
rb_raise(rb_eArgError, "wrong number of arguments: %i for 1", argc);
|
3430
|
+
break;
|
3431
|
+
}
|
3432
|
+
|
3433
|
+
return rhrd__add_days(self, i);
|
3434
|
+
}
|
3435
|
+
|
3436
|
+
/* call-seq:
|
3437
|
+
* [ruby 1-9 only] <br />
|
3438
|
+
* prev_month(n=1) -> Date
|
3439
|
+
*
|
3440
|
+
* Returns a +Date+ +n+ months before the receiver. If +n+ is negative,
|
3441
|
+
* returns a +Date+ after the receiver.
|
3442
|
+
*
|
3443
|
+
* Date.civil(2009, 1, 2).prev_month
|
3444
|
+
* # => #<Date 2008-12-02>
|
3445
|
+
* Date.civil(2009, 1, 2).prev_month(2)
|
3446
|
+
* # => #<Date 2008-11-02>
|
3447
|
+
*/
|
3448
|
+
static VALUE rhrd_prev_month(int argc, VALUE *argv, VALUE self) {
|
3449
|
+
long i;
|
3450
|
+
|
3451
|
+
switch(argc) {
|
3452
|
+
case 0:
|
3453
|
+
i = -1;
|
3454
|
+
break;
|
3455
|
+
case 1:
|
3456
|
+
i = -NUM2LONG(argv[0]);
|
3457
|
+
break;
|
3458
|
+
default:
|
3459
|
+
rb_raise(rb_eArgError, "wrong number of arguments: %i for 1", argc);
|
3460
|
+
break;
|
3461
|
+
}
|
3462
|
+
|
3463
|
+
return rhrd__add_months(self, i);
|
3464
|
+
}
|
3465
|
+
|
3466
|
+
/* call-seq:
|
3467
|
+
* [ruby 1-9 only] <br />
|
3468
|
+
* prev_year(n=1) -> Date
|
3469
|
+
*
|
3470
|
+
* Returns a +Date+ +n+ years before the receiver. If +n+ is negative,
|
3471
|
+
* returns a +Date+ after the receiver.
|
3472
|
+
*
|
3473
|
+
* Date.civil(2009, 1, 2).prev_year
|
3474
|
+
* # => #<Date 2008-01-02>
|
3475
|
+
* Date.civil(2009, 1, 2).prev_year(2)
|
3476
|
+
* # => #<Date 2007-01-02>
|
3477
|
+
*/
|
3478
|
+
static VALUE rhrd_prev_year(int argc, VALUE *argv, VALUE self) {
|
3479
|
+
long i;
|
3480
|
+
|
3481
|
+
switch(argc) {
|
3482
|
+
case 0:
|
3483
|
+
i = -1;
|
3484
|
+
break;
|
3485
|
+
case 1:
|
3486
|
+
i = -NUM2LONG(argv[0]);
|
3487
|
+
break;
|
3488
|
+
default:
|
3489
|
+
rb_raise(rb_eArgError, "wrong number of arguments: %i for 1", argc);
|
3490
|
+
break;
|
3491
|
+
}
|
3492
|
+
|
3493
|
+
return rhrd__add_years(self, i);
|
3494
|
+
}
|
3495
|
+
|
3496
|
+
/* call-seq:
|
3497
|
+
* [ruby 1-9 only] <br />
|
3498
|
+
* rfc2822() -> String
|
3499
|
+
*
|
3500
|
+
* Returns the receiver as a +String+ in RFC2822 format. Example:
|
3501
|
+
*
|
3502
|
+
* Date.civil(2009, 1, 2).rfc2822
|
3503
|
+
* # => "Fri, 2 Jan 2009 00:00:00 +0000"
|
3504
|
+
*/
|
3505
|
+
static VALUE rhrd_rfc2822(VALUE self) {
|
3506
|
+
VALUE s;
|
3507
|
+
rhrd_t *d;
|
3508
|
+
int len;
|
3509
|
+
Data_Get_Struct(self, rhrd_t, d);
|
3510
|
+
RHR_FILL_CIVIL(d)
|
3511
|
+
RHR_FILL_JD(d)
|
3512
|
+
|
3513
|
+
s = rb_str_buf_new(128);
|
3514
|
+
len = snprintf(RSTRING_PTR(s), 128, "%s, %hhi %s %04li 00:00:00 +0000",
|
3515
|
+
rhrd__abbr_day_names[rhrd__jd_to_wday(d->jd)],
|
3516
|
+
d->day,
|
3517
|
+
rhrd__abbr_month_names[d->month],
|
3518
|
+
d->year);
|
3519
|
+
if (len == -1 || len > 127) {
|
3520
|
+
rb_raise(rb_eNoMemError, "in Date#rfc2822 (in snprintf)");
|
3521
|
+
}
|
3522
|
+
|
3523
|
+
RHR_RETURN_RESIZED_STR(s, len)
|
3524
|
+
}
|
3525
|
+
|
3526
|
+
/* call-seq:
|
3527
|
+
* [ruby 1-9 only] <br />
|
3528
|
+
* rfc3339() -> String
|
3529
|
+
*
|
3530
|
+
* Returns the receiver as a +String+ in RFC3339 format. Example:
|
3531
|
+
*
|
3532
|
+
* Date.civil(2009, 1, 2).rfc3339
|
3533
|
+
* # => "2009-01-02T00:00:00+00:00"
|
3534
|
+
*/
|
3535
|
+
static VALUE rhrd_rfc3339(VALUE self) {
|
3536
|
+
VALUE s;
|
3537
|
+
rhrd_t *d;
|
3538
|
+
int len;
|
3539
|
+
Data_Get_Struct(self, rhrd_t, d);
|
3540
|
+
RHR_FILL_CIVIL(d)
|
3541
|
+
|
3542
|
+
s = rb_str_buf_new(128);
|
3543
|
+
len = snprintf(RSTRING_PTR(s), 128, "%04li-%02hhi-%02hhiT00:00:00+00:00", d->year, d->month, d->day);
|
3544
|
+
if (len == -1 || len > 127) {
|
3545
|
+
rb_raise(rb_eNoMemError, "in Date#rfc3339 (in snprintf)");
|
3546
|
+
}
|
3547
|
+
|
3548
|
+
RHR_RETURN_RESIZED_STR(s, len)
|
3549
|
+
}
|
3550
|
+
|
3551
|
+
/* call-seq:
|
3552
|
+
* [ruby 1-9 only] <br />
|
3553
|
+
* to_datetime() -> DateTime
|
3554
|
+
*
|
3555
|
+
* Returns a +DateTime+ equal to the receiver.
|
3556
|
+
*
|
3557
|
+
* Date.civil(2009, 1, 2).to_datetime
|
3558
|
+
* # => #<DateTime 2009-01-02T00:00:00+00:00>
|
3559
|
+
*/
|
3560
|
+
static VALUE rhrd_to_datetime(VALUE self) {
|
3561
|
+
rhrd_t *d;
|
3562
|
+
rhrdt_t *dt;
|
3563
|
+
VALUE rdt = Data_Make_Struct(rhrdt_class, rhrdt_t, NULL, free, dt);
|
3564
|
+
Data_Get_Struct(self, rhrd_t, d);
|
3565
|
+
|
3566
|
+
if (RHR_HAS_CIVIL(d)) {
|
3567
|
+
dt->year = d->year;
|
3568
|
+
dt->month = d->month;
|
3569
|
+
dt->day = d->day;
|
3570
|
+
dt->flags |= RHR_HAVE_CIVIL;
|
3571
|
+
}
|
3572
|
+
if (RHR_HAS_JD(d)) {
|
3573
|
+
dt->jd = d->jd;
|
3574
|
+
dt->flags |= RHR_HAVE_JD;
|
3575
|
+
}
|
3576
|
+
|
3577
|
+
return rdt;
|
3578
|
+
}
|
3579
|
+
|
3580
|
+
/* call-seq:
|
3581
|
+
* [ruby 1-9 only] <br />
|
3582
|
+
* to_time() -> Time
|
3583
|
+
*
|
3584
|
+
* Returns a +Time+ in local time with the same year, month, and day
|
3585
|
+
* as the receiver.
|
3586
|
+
*
|
3587
|
+
* Date.civil(2009, 1, 2).to_time
|
3588
|
+
* # => 2009-01-02 00:00:00 -0800
|
3589
|
+
*/
|
3590
|
+
static VALUE rhrd_to_time(VALUE self) {
|
3591
|
+
rhrd_t *d;
|
3592
|
+
Data_Get_Struct(self, rhrd_t, d);
|
3593
|
+
RHR_FILL_CIVIL(d)
|
3594
|
+
return rb_funcall(rb_cTime, rhrd_id_local, 3, LONG2NUM(d->year), LONG2NUM(d->month), LONG2NUM(d->day));
|
3595
|
+
}
|
3596
|
+
|
3597
|
+
/* call-seq:
|
3598
|
+
* [ruby 1-9 only] <br />
|
3599
|
+
* to_date() -> Date
|
3600
|
+
*
|
3601
|
+
* Returns a +Date+ with the same year, month, and day
|
3602
|
+
* as the receiver in local time.
|
3603
|
+
*
|
3604
|
+
* Time.local(2009, 1, 2).to_date
|
3605
|
+
* # => #<Date 2009-01-02>
|
3606
|
+
*/
|
3607
|
+
static VALUE rhrd_time_to_date(VALUE self) {
|
3608
|
+
rhrd_t *d;
|
3609
|
+
VALUE rd;
|
3610
|
+
rd = Data_Make_Struct(rhrd_class, rhrd_t, NULL, free, d);
|
3611
|
+
d->jd = rhrd__unix_to_jd(NUM2LONG(rb_funcall(self, rhrd_id_to_i, 0)) + NUM2LONG(rb_funcall(self, rhrd_id_utc_offset, 0)));
|
3612
|
+
d->flags = RHR_HAVE_JD;
|
3613
|
+
RHR_CHECK_JD(d)
|
3614
|
+
return rd;
|
3615
|
+
}
|
3616
|
+
|
3617
|
+
/* call-seq:
|
3618
|
+
* [ruby 1-9 only] <br />
|
3619
|
+
* to_time() -> Time
|
3620
|
+
*
|
3621
|
+
* Returns a copy of the receiver in local time.
|
3622
|
+
*
|
3623
|
+
* Time.local(2009, 1, 2).to_time
|
3624
|
+
* # => 2009-01-02 00:00:00 -0800
|
3625
|
+
* Time.local(2009, 1, 2).getutc.to_time
|
3626
|
+
* # => 2009-01-02 00:00:00 -0800
|
3627
|
+
*/
|
3628
|
+
static VALUE rhrd_time_to_time(VALUE self) {
|
3629
|
+
return rb_funcall(self, rhrd_id_getlocal, 0);
|
3630
|
+
}
|
3631
|
+
|
3632
|
+
/* Ruby 1.9 *day? instance methods */
|
3633
|
+
|
3634
|
+
/* call-seq:
|
3635
|
+
* [ruby 1-9 only] <br />
|
3636
|
+
* sunday?() -> true or false
|
3637
|
+
*
|
3638
|
+
* Returns +true+ if the receiver is a Sunday, +false+ otherwise.
|
3639
|
+
*/
|
3640
|
+
static VALUE rhrd_sunday_q(VALUE self) {
|
3641
|
+
return rhrd__day_q(self, 0);
|
3642
|
+
}
|
3643
|
+
|
3644
|
+
/* call-seq:
|
3645
|
+
* [ruby 1-9 only] <br />
|
3646
|
+
* monday?() -> true or false
|
3647
|
+
*
|
3648
|
+
* Returns +true+ if the receiver is a Monday, +false+ otherwise.
|
3649
|
+
*/
|
3650
|
+
static VALUE rhrd_monday_q(VALUE self) {
|
3651
|
+
return rhrd__day_q(self, 1);
|
3652
|
+
}
|
3653
|
+
|
3654
|
+
/* call-seq:
|
3655
|
+
* [ruby 1-9 only] <br />
|
3656
|
+
* tuesday?() -> true or false
|
3657
|
+
*
|
3658
|
+
* Returns +true+ if the receiver is a Tuesday, +false+ otherwise.
|
3659
|
+
*/
|
3660
|
+
static VALUE rhrd_tuesday_q(VALUE self) {
|
3661
|
+
return rhrd__day_q(self, 2);
|
3662
|
+
}
|
3663
|
+
|
3664
|
+
/* call-seq:
|
3665
|
+
* [ruby 1-9 only] <br />
|
3666
|
+
* wednesday?() -> true or false
|
3667
|
+
*
|
3668
|
+
* Returns +true+ if the receiver is a Wednesday, +false+ otherwise.
|
3669
|
+
*/
|
3670
|
+
static VALUE rhrd_wednesday_q(VALUE self) {
|
3671
|
+
return rhrd__day_q(self, 3);
|
3672
|
+
}
|
3673
|
+
|
3674
|
+
/* call-seq:
|
3675
|
+
* [ruby 1-9 only] <br />
|
3676
|
+
* thursday?() -> true or false
|
3677
|
+
*
|
3678
|
+
* Returns +true+ if the receiver is a Thursday, +false+ otherwise.
|
3679
|
+
*/
|
3680
|
+
static VALUE rhrd_thursday_q(VALUE self) {
|
3681
|
+
return rhrd__day_q(self, 4);
|
3682
|
+
}
|
3683
|
+
|
3684
|
+
/* call-seq:
|
3685
|
+
* [ruby 1-9 only] <br />
|
3686
|
+
* friday?() -> true or false
|
3687
|
+
*
|
3688
|
+
* Returns +true+ if the receiver is a Friday, +false+ otherwise.
|
3689
|
+
*/
|
3690
|
+
static VALUE rhrd_friday_q(VALUE self) {
|
3691
|
+
return rhrd__day_q(self, 5);
|
3692
|
+
}
|
3693
|
+
|
3694
|
+
/* call-seq:
|
3695
|
+
* [ruby 1-9 only] <br />
|
3696
|
+
* saturday?() -> true or false
|
3697
|
+
*
|
3698
|
+
* Returns +true+ if the receiver is a Saturday, +false+ otherwise.
|
3699
|
+
*/
|
3700
|
+
static VALUE rhrd_saturday_q(VALUE self) {
|
3701
|
+
return rhrd__day_q(self, 6);
|
3702
|
+
}
|
3703
|
+
|
3704
|
+
#else
|
3705
|
+
|
3706
|
+
/* Ruby 1.8 class methods */
|
3707
|
+
|
3708
|
+
/* call-seq:
|
3709
|
+
* [ruby 1-8 only] <br />
|
3710
|
+
* ajd_to_amjd(ajd) -> Integer
|
3711
|
+
*
|
3712
|
+
* Converts the given astronomical julian date (+Integer+) into an
|
3713
|
+
* astronomical modified julian date.
|
3714
|
+
*/
|
3715
|
+
static VALUE rhrd_s_ajd_to_amjd(VALUE klass, VALUE ajd) {
|
3716
|
+
return LONG2NUM(rhrd__safe_add_long(-RHR_JD_MJD, NUM2LONG(ajd)));
|
3717
|
+
}
|
3718
|
+
|
3719
|
+
/* call-seq:
|
3720
|
+
* [ruby 1-8 only] <br />
|
3721
|
+
* ajd_to_jd(ajd) -> [jd, Float(1)/2]
|
3722
|
+
*
|
3723
|
+
* Converts the given astronomical julian date (+Integer+) into an
|
3724
|
+
* an array of two elements, where the first element is the julian
|
3725
|
+
* date +Integer+ and the second is a +Float+ with value 0.5.
|
3726
|
+
*/
|
3727
|
+
static VALUE rhrd_s_ajd_to_jd(int argc, VALUE *argv, VALUE klass) {
|
3728
|
+
switch(argc) {
|
3729
|
+
case 1:
|
3730
|
+
case 2:
|
3731
|
+
break;
|
3732
|
+
default:
|
3733
|
+
rb_raise(rb_eArgError, "wrong number of arguments: %i for 2", argc);
|
3734
|
+
break;
|
3735
|
+
}
|
3736
|
+
|
3737
|
+
return rb_ary_new3(2, argv[0], rb_float_new(0.5));
|
3738
|
+
}
|
3739
|
+
|
3740
|
+
/* call-seq:
|
3741
|
+
* [ruby 1-8 only] <br />
|
3742
|
+
* amjd_to_ajd(ajd) -> Integer
|
3743
|
+
*
|
3744
|
+
* Converts the given astronomical modified julian date (+Integer+) into an
|
3745
|
+
* astronomical julian date.
|
3746
|
+
*/
|
3747
|
+
static VALUE rhrd_s_amjd_to_ajd(VALUE klass, VALUE amjd) {
|
3748
|
+
return LONG2NUM(rhrd__safe_add_long(RHR_JD_MJD - 1, NUM2LONG(amjd)));
|
3749
|
+
}
|
3750
|
+
|
3751
|
+
/* call-seq:
|
3752
|
+
* [ruby 1-8 only] <br />
|
3753
|
+
* civil_to_jd(year, month, day, sg=nil) -> Integer
|
3754
|
+
*
|
3755
|
+
* Converts the given year, month, and day into a julian date +Integer+.
|
3756
|
+
* Ignores the 4th argument.
|
3757
|
+
*/
|
3758
|
+
static VALUE rhrd_s_civil_to_jd(int argc, VALUE *argv, VALUE klass) {
|
3759
|
+
rhrd_t d;
|
3760
|
+
memset(&d, 0, sizeof(rhrd_t));
|
3761
|
+
|
3762
|
+
switch(argc) {
|
3763
|
+
case 3:
|
3764
|
+
case 4:
|
3765
|
+
d.year = NUM2LONG(argv[0]);
|
3766
|
+
d.month = (unsigned char)NUM2LONG(argv[1]);
|
3767
|
+
d.day = (unsigned char)NUM2LONG(argv[2]);
|
3768
|
+
break;
|
3769
|
+
default:
|
3770
|
+
rb_raise(rb_eArgError, "wrong number of arguments: %i for 4", argc);
|
3771
|
+
break;
|
3772
|
+
}
|
3773
|
+
d.flags = RHR_HAVE_CIVIL;
|
3774
|
+
RHR_FILL_JD(&d)
|
3775
|
+
|
3776
|
+
return LONG2NUM(d.jd);
|
3777
|
+
}
|
3778
|
+
|
3779
|
+
/* call-seq:
|
3780
|
+
* [ruby 1-8 only] <br />
|
3781
|
+
* civil_to_jd(cwyear, cweek, cwday, sg=nil) -> Integer
|
3782
|
+
*
|
3783
|
+
* Converts the given cwyear, cweek, and cwday into a julian date +Integer+.
|
3784
|
+
* Ignores the 4th argument.
|
3785
|
+
*/
|
3786
|
+
static VALUE rhrd_s_commercial_to_jd(int argc, VALUE *argv, VALUE klass) {
|
3787
|
+
long jd;
|
3788
|
+
|
3789
|
+
switch(argc) {
|
3790
|
+
case 3:
|
3791
|
+
case 4:
|
3792
|
+
jd = rhrd__commercial_to_jd(NUM2LONG(argv[0]), NUM2LONG(argv[1]), NUM2LONG(argv[2]));
|
3793
|
+
break;
|
3794
|
+
default:
|
3795
|
+
rb_raise(rb_eArgError, "wrong number of arguments: %i for 4", argc);
|
3796
|
+
break;
|
3797
|
+
}
|
3798
|
+
|
3799
|
+
return LONG2NUM(jd);
|
3800
|
+
}
|
3801
|
+
|
3802
|
+
/* call-seq:
|
3803
|
+
* [ruby 1-8 only] <br />
|
3804
|
+
* day_fraction_to_time(float) -> [hour, minute, second, sec_fraction]
|
3805
|
+
*
|
3806
|
+
* Converts the given float (which should be in the range [0.0, 1.0))
|
3807
|
+
* into an array of 4 elements: +hour+ (+Integer+), +minute+ (+Integer+),
|
3808
|
+
* +second+ (+Integer+), and +sec_fraction+ (+Float+). Note that
|
3809
|
+
* +sec_fraction+ is the fraction of the second as a fraction of the day,
|
3810
|
+
* so it will be in the range [0.0, 1.0/86400.0).
|
3811
|
+
*/
|
3812
|
+
static VALUE rhrd_s_day_fraction_to_time(VALUE klass, VALUE rf) {
|
3813
|
+
double f;
|
3814
|
+
int h, m, s;
|
3815
|
+
|
3816
|
+
f = NUM2DBL(rf) * 24;
|
3817
|
+
h = floor(f);
|
3818
|
+
f = (f - h) * 60;
|
3819
|
+
m = floor(f);
|
3820
|
+
f = (f - m) * 60;
|
3821
|
+
s = floor(f);
|
3822
|
+
f = (f - s)/RHR_SECONDS_PER_DAY;
|
3823
|
+
return rb_ary_new3(4, LONG2NUM(h), LONG2NUM(m), LONG2NUM(s), rb_float_new(f));
|
3824
|
+
}
|
3825
|
+
|
3826
|
+
/* call-seq:
|
3827
|
+
* [ruby 1-8 only] <br />
|
3828
|
+
* gregorian?(jd, sg) -> true or false
|
3829
|
+
*
|
3830
|
+
* If +sg+ is +nil+ or +false+, returns +false+. If +sg+ is +Numeric+,
|
3831
|
+
* returns +true+ if +jd+ is greater than or equal to +sg+, and +false+
|
3832
|
+
* otherwise. If +sg+ is not +Numeric+, +nil+, or +false+, returns +true+.
|
3833
|
+
*/
|
3834
|
+
static VALUE rhrd_s_gregorian_q(VALUE klass, VALUE jd, VALUE sg) {
|
3835
|
+
if (RTEST((rb_obj_is_kind_of(sg, rb_cNumeric)))) {
|
3836
|
+
return rb_funcall(jd, rhrd_id_op_gte, 1, sg);
|
3837
|
+
} else {
|
3838
|
+
return RTEST(sg) ? Qtrue : Qfalse;
|
3839
|
+
}
|
3840
|
+
}
|
3841
|
+
|
3842
|
+
/* call-seq:
|
3843
|
+
* [ruby 1-8 only] <br />
|
3844
|
+
* jd_to_ajd(jd, rf, of=nil) -> Integer
|
3845
|
+
*
|
3846
|
+
* Returns +jd+. Ignores the 2nd and 3rd arguments.
|
3847
|
+
*/
|
3848
|
+
static VALUE rhrd_s_jd_to_ajd(int argc, VALUE *argv, VALUE klass) {
|
3849
|
+
switch(argc) {
|
3850
|
+
case 2:
|
3851
|
+
case 3:
|
3852
|
+
break;
|
3853
|
+
default:
|
3854
|
+
rb_raise(rb_eArgError, "wrong number of arguments: %i for 3", argc);
|
3855
|
+
break;
|
3856
|
+
}
|
3857
|
+
return argv[0];
|
3858
|
+
}
|
3859
|
+
|
3860
|
+
/* call-seq:
|
3861
|
+
* [ruby 1-8 only] <br />
|
3862
|
+
* jd_to_civil(jd, sg=nil) -> [year, month, day]
|
3863
|
+
*
|
3864
|
+
* Converts +jd+ to an array with 3 +Integer+ values: +year+, +month+,
|
3865
|
+
* and +day+. Ignores the 2nd argument.
|
3866
|
+
*/
|
3867
|
+
static VALUE rhrd_s_jd_to_civil(int argc, VALUE *argv, VALUE klass) {
|
3868
|
+
rhrd_t d;
|
3869
|
+
memset(&d, 0, sizeof(rhrd_t));
|
3870
|
+
|
3871
|
+
switch(argc) {
|
3872
|
+
case 1:
|
3873
|
+
case 2:
|
3874
|
+
d.jd = NUM2LONG(argv[0]);
|
3875
|
+
break;
|
3876
|
+
default:
|
3877
|
+
rb_raise(rb_eArgError, "wrong number of arguments: %i for 3", argc);
|
3878
|
+
break;
|
3879
|
+
}
|
3880
|
+
RHR_FILL_CIVIL(&d)
|
3881
|
+
return rb_ary_new3(3, LONG2NUM(d.year), LONG2NUM(d.month), LONG2NUM(d.day));
|
3882
|
+
}
|
3883
|
+
|
3884
|
+
/* call-seq:
|
3885
|
+
* [ruby 1-8 only] <br />
|
3886
|
+
* jd_to_commercial(jd, sg=nil) -> [cwyear, cweek, cwday]
|
3887
|
+
*
|
3888
|
+
* Converts +jd+ to an array with 3 +Integer+ values: +cwyear+, +cweek+,
|
3889
|
+
* and +cwday+. Ignores the 2nd argument.
|
3890
|
+
*/
|
3891
|
+
static VALUE rhrd_s_jd_to_commercial(int argc, VALUE *argv, VALUE klass) {
|
3892
|
+
rhrd_t d;
|
3893
|
+
memset(&d, 0, sizeof(rhrd_t));
|
3894
|
+
|
3895
|
+
switch(argc) {
|
3896
|
+
case 1:
|
3897
|
+
case 2:
|
3898
|
+
d.jd = NUM2LONG(argv[0]);
|
3899
|
+
break;
|
3900
|
+
default:
|
3901
|
+
rb_raise(rb_eArgError, "wrong number of arguments: %i for 3", argc);
|
3902
|
+
break;
|
3903
|
+
}
|
3904
|
+
rhrd__fill_commercial(&d);
|
3905
|
+
return rb_ary_new3(3, LONG2NUM(d.year), LONG2NUM(d.month), LONG2NUM(d.day));
|
3906
|
+
}
|
3907
|
+
|
3908
|
+
/* call-seq:
|
3909
|
+
* [ruby 1-8 only] <br />
|
3910
|
+
* jd_to_ld(jd) -> Integer
|
3911
|
+
*
|
3912
|
+
* Converts +jd+ to a Lilian Date (the number of days since the day of calendar
|
3913
|
+
* reform in Italy).
|
3914
|
+
*/
|
3915
|
+
static VALUE rhrd_s_jd_to_ld(VALUE klass, VALUE jd) {
|
3916
|
+
return LONG2NUM(rhrd__safe_add_long(-RHR_JD_LD, NUM2LONG(jd)));
|
3917
|
+
}
|
3918
|
+
|
3919
|
+
/* call-seq:
|
3920
|
+
* [ruby 1-8 only] <br />
|
3921
|
+
* jd_to_mjd(jd) -> Integer
|
3922
|
+
*
|
3923
|
+
* Converts +jd+ to a modified julian date +Integer+.
|
3924
|
+
*/
|
3925
|
+
static VALUE rhrd_s_jd_to_mjd(VALUE klass, VALUE jd) {
|
3926
|
+
return LONG2NUM(rhrd__safe_add_long(-RHR_JD_MJD, NUM2LONG(jd)));
|
3927
|
+
}
|
3928
|
+
|
3929
|
+
/* call-seq:
|
3930
|
+
* [ruby 1-8 only] <br />
|
3931
|
+
* jd_to_ordinal(jd, sg=nil) -> [year, yday]
|
3932
|
+
*
|
3933
|
+
* Converts +jd+ to an array with 2 +Integer+ values: +year+ and +yday+ (day of year).
|
3934
|
+
* Ignores the 2nd argument.
|
3935
|
+
*/
|
3936
|
+
static VALUE rhrd_s_jd_to_ordinal(int argc, VALUE *argv, VALUE klass) {
|
3937
|
+
rhrd_t d;
|
3938
|
+
memset(&d, 0, sizeof(rhrd_t));
|
3939
|
+
|
3940
|
+
switch(argc) {
|
3941
|
+
case 1:
|
3942
|
+
case 2:
|
3943
|
+
d.jd = NUM2LONG(argv[0]);
|
3944
|
+
break;
|
3945
|
+
default:
|
3946
|
+
rb_raise(rb_eArgError, "wrong number of arguments: %i for 3", argc);
|
3947
|
+
break;
|
3948
|
+
}
|
3949
|
+
RHR_FILL_CIVIL(&d)
|
3950
|
+
|
3951
|
+
return rb_ary_new3(2, LONG2NUM(d.year), LONG2NUM(rhrd__ordinal_day(d.year, d.month, d.day)));
|
3952
|
+
}
|
3953
|
+
|
3954
|
+
/* call-seq:
|
3955
|
+
* [ruby 1-8 only] <br />
|
3956
|
+
* jd_to_wday(jd) -> Integer
|
3957
|
+
*
|
3958
|
+
* Converts +jd+ to an +Integer+ day of the week, where 0 represents Sunday
|
3959
|
+
* and 6 represents Saturday.
|
3960
|
+
*/
|
3961
|
+
static VALUE rhrd_s_jd_to_wday(VALUE klass, VALUE jd) {
|
3962
|
+
return LONG2NUM(rhrd__jd_to_wday(NUM2LONG(jd)));
|
3963
|
+
}
|
3964
|
+
|
3965
|
+
/* call-seq:
|
3966
|
+
* [ruby 1-8 only] <br />
|
3967
|
+
* julian?(jd, sg) -> true or false
|
3968
|
+
*
|
3969
|
+
* If +sg+ is +nil+ or +false+, returns +true+. If +sg+ is +Numeric+,
|
3970
|
+
* returns +true+ if +jd+ is less than +sg+, and +false+
|
3971
|
+
* otherwise. If +sg+ is not +Numeric+, +nil+, or +false+, returns +false+.
|
3972
|
+
*/
|
3973
|
+
static VALUE rhrd_s_julian_q(VALUE klass, VALUE jd, VALUE sg) {
|
3974
|
+
if (RTEST((rb_obj_is_kind_of(sg, rb_cNumeric)))) {
|
3975
|
+
return rb_funcall(jd, rhrd_id_op_lt, 1, sg);
|
3976
|
+
} else {
|
3977
|
+
return RTEST(sg) ? Qfalse : Qtrue;
|
3978
|
+
}
|
3979
|
+
}
|
3980
|
+
|
3981
|
+
/* call-seq:
|
3982
|
+
* [ruby 1-8 only] <br />
|
3983
|
+
* ld_to_jd(ld) -> Integer
|
3984
|
+
*
|
3985
|
+
* Converts +ld+ (a Lilian Date) to a julian day +Integer+.
|
3986
|
+
*/
|
3987
|
+
static VALUE rhrd_s_ld_to_jd(VALUE klass, VALUE ld) {
|
3988
|
+
return LONG2NUM(rhrd__safe_add_long(RHR_JD_LD, NUM2LONG(ld)));
|
3989
|
+
}
|
3990
|
+
|
3991
|
+
/* call-seq:
|
3992
|
+
* [ruby 1-8 only] <br />
|
3993
|
+
* mjd_to_jd(mjd) -> Integer
|
3994
|
+
*
|
3995
|
+
* Converts a modified julian date number to a julian day +Integer+.
|
3996
|
+
*/
|
3997
|
+
static VALUE rhrd_s_mjd_to_jd(VALUE klass, VALUE mjd) {
|
3998
|
+
return LONG2NUM(rhrd__safe_add_long(RHR_JD_MJD, NUM2LONG(mjd)));
|
3999
|
+
}
|
4000
|
+
|
4001
|
+
/* call-seq:
|
4002
|
+
* [ruby 1-8 only] <br />
|
4003
|
+
* ordinal_to_jd(year, yday, sg=nil) -> Integer
|
4004
|
+
*
|
4005
|
+
* Converts the given +year+ and +yday+ (day of year) into a julian day +Integer+.
|
4006
|
+
* Ignores the 3rd argument.
|
4007
|
+
*/
|
4008
|
+
static VALUE rhrd_s_ordinal_to_jd(int argc, VALUE *argv, VALUE klass) {
|
4009
|
+
switch(argc) {
|
4010
|
+
case 2:
|
4011
|
+
case 3:
|
4012
|
+
return LONG2NUM(rhrd__ymd_to_jd(NUM2LONG(argv[0]), 1, NUM2LONG(argv[1])));
|
4013
|
+
break;
|
4014
|
+
default:
|
4015
|
+
rb_raise(rb_eArgError, "wrong number of arguments: %i for 3", argc);
|
4016
|
+
break;
|
4017
|
+
}
|
4018
|
+
}
|
4019
|
+
|
4020
|
+
/* call-seq:
|
4021
|
+
* [ruby 1-8 only] <br />
|
4022
|
+
* time_to_day_fraction(hour, minute, second) -> Float
|
4023
|
+
*
|
4024
|
+
* Converts the given +hour+, +minute+, and +second+ into a single +Float+ representing
|
4025
|
+
* the fraction of the day, such that 12 hours, 0 minutes, and 0 seconds would return
|
4026
|
+
* 0.5.
|
4027
|
+
*/
|
4028
|
+
static VALUE rhrd_s_time_to_day_fraction(VALUE klass, VALUE h, VALUE m, VALUE s) {
|
4029
|
+
return rb_float_new(NUM2DBL(h)/24.0 + NUM2DBL(m)/RHR_MINUTES_PER_DAYD + NUM2DBL(s)/RHR_SECONDS_PER_DAYD);
|
4030
|
+
}
|
4031
|
+
|
4032
|
+
/* call-seq:
|
4033
|
+
* [ruby 1-8 only] <br />
|
4034
|
+
* valid_time?(hour, minute, second) -> Float
|
4035
|
+
*
|
4036
|
+
* Checks that the hour, minute, and second are a valid time. This handles negative
|
4037
|
+
* values for all 3 arguments, so that -10 minutes is treated as 50 minutes. It returns
|
4038
|
+
* a +Float+ representing the fraction of the day for the given values.
|
4039
|
+
*/
|
4040
|
+
static VALUE rhrd_s_valid_time_q(VALUE klass, VALUE rh, VALUE rm, VALUE rs) {
|
4041
|
+
long h, m, s;
|
4042
|
+
h = NUM2LONG(rh);
|
4043
|
+
m = NUM2LONG(rm);
|
4044
|
+
s = NUM2LONG(rs);
|
4045
|
+
if (h < 0) {
|
4046
|
+
h += 24;
|
4047
|
+
}
|
4048
|
+
if (m < 0) {
|
4049
|
+
m += 60;
|
4050
|
+
}
|
4051
|
+
if (s < 0) {
|
4052
|
+
s += 60;
|
4053
|
+
}
|
4054
|
+
if (h < 0 || m < 0 || s < 0 || h > 24 || m > 59 || s > 59 || (h == 24 && m != 0 && s != 0)) {
|
4055
|
+
return Qnil;
|
4056
|
+
}
|
4057
|
+
return rb_float_new(h/24.0 + m/RHR_MINUTES_PER_DAYD + s/RHR_SECONDS_PER_DAYD);
|
4058
|
+
}
|
4059
|
+
|
4060
|
+
#endif
|
4061
|
+
|
4062
|
+
#include "datetime.c"
|
4063
|
+
|
4064
|
+
/* Ruby Library Initialization */
|
4065
|
+
|
4066
|
+
/* +Date+ is used to store a single date in the gregorian calendar.
|
4067
|
+
*
|
4068
|
+
* In general, +Date+ objects are created by calling one of the class
|
4069
|
+
* methods: +civil+, +parse+, +strptime+, +today+. Once created,
|
4070
|
+
* +Date+ objects are immutable. Operations that result in a separate
|
4071
|
+
* date (such as adding a number of days), always return a new +Date+
|
4072
|
+
* object.
|
4073
|
+
* */
|
4074
|
+
void Init_date_ext(void) {
|
4075
|
+
int i;
|
4076
|
+
|
4077
|
+
/* Setup static IDs and symbols */
|
4078
|
+
|
4079
|
+
rhrd_id_op_array = rb_intern("[]");
|
4080
|
+
rhrd_id_op_gte = rb_intern(">=");
|
4081
|
+
rhrd_id_op_lt = rb_intern("<");
|
4082
|
+
rhrd_id__parse = rb_intern("_parse");
|
4083
|
+
rhrd_id_cwday = rb_intern("cwday");
|
4084
|
+
rhrd_id_cweek = rb_intern("cweek");
|
4085
|
+
rhrd_id_cwyear = rb_intern("cwyear");
|
4086
|
+
rhrd_id_downcase = rb_intern("downcase");
|
4087
|
+
rhrd_id_getlocal = rb_intern("getlocal");
|
4088
|
+
rhrd_id_hash = rb_intern("hash");
|
4089
|
+
rhrd_id_length = rb_intern("length");
|
4090
|
+
rhrd_id_include_q = rb_intern("include?");
|
4091
|
+
rhrd_id_local = rb_intern("local");
|
4092
|
+
rhrd_id_localtime = rb_intern("localtime");
|
4093
|
+
rhrd_id_match = rb_intern("match");
|
4094
|
+
rhrd_id_now = rb_intern("now");
|
4095
|
+
rhrd_id_offset = rb_intern("offset");
|
4096
|
+
rhrd_id_slice = rb_intern("slice");
|
4097
|
+
rhrd_id_split = rb_intern("split");
|
4098
|
+
rhrd_id_sub_b = rb_intern("sub!");
|
4099
|
+
rhrd_id_to_i = rb_intern("to_i");
|
4100
|
+
#ifdef RUBY19
|
4101
|
+
rhrd_id_nsec = rb_intern("nsec");
|
4102
|
+
#else
|
4103
|
+
rhrd_id_usec = rb_intern("usec");
|
4104
|
+
#endif
|
4105
|
+
rhrd_id_utc = rb_intern("utc");
|
4106
|
+
rhrd_id_utc_offset = rb_intern("utc_offset");
|
4107
|
+
|
4108
|
+
#ifdef RUBY19
|
4109
|
+
rhrd_id__httpdate = rb_intern("_httpdate");
|
4110
|
+
rhrd_id__iso8601 = rb_intern("_iso8601");
|
4111
|
+
rhrd_id__jisx0301 = rb_intern("_jisx0301");
|
4112
|
+
rhrd_id__rfc2822 = rb_intern("_rfc2822");
|
4113
|
+
rhrd_id__rfc3339 = rb_intern("_rfc3339");
|
4114
|
+
rhrd_id__xmlschema = rb_intern("_xmlschema");
|
4115
|
+
#endif
|
4116
|
+
|
4117
|
+
rhrd_sym_cwday = ID2SYM(rb_intern("cwday"));
|
4118
|
+
rhrd_sym_cweek = ID2SYM(rb_intern("cweek"));
|
4119
|
+
rhrd_sym_cwyear = ID2SYM(rb_intern("cwyear"));
|
4120
|
+
rhrd_sym_hour = ID2SYM(rb_intern("hour"));
|
4121
|
+
#ifdef RUBY19
|
4122
|
+
rhrd_sym_leftover = ID2SYM(rb_intern("leftover"));
|
4123
|
+
#endif
|
4124
|
+
rhrd_sym_mday = ID2SYM(rb_intern("mday"));
|
4125
|
+
rhrd_sym_min = ID2SYM(rb_intern("min"));
|
4126
|
+
rhrd_sym_mon = ID2SYM(rb_intern("mon"));
|
4127
|
+
rhrd_sym_offset = ID2SYM(rb_intern("offset"));
|
4128
|
+
rhrd_sym_sec = ID2SYM(rb_intern("sec"));
|
4129
|
+
rhrd_sym_sec_fraction = ID2SYM(rb_intern("sec_fraction"));
|
4130
|
+
rhrd_sym_seconds = ID2SYM(rb_intern("seconds"));
|
4131
|
+
rhrd_sym_wday = ID2SYM(rb_intern("wday"));
|
4132
|
+
rhrd_sym_wnum0 = ID2SYM(rb_intern("wnum0"));
|
4133
|
+
rhrd_sym_wnum1 = ID2SYM(rb_intern("wnum1"));
|
4134
|
+
rhrd_sym_yday = ID2SYM(rb_intern("yday"));
|
4135
|
+
rhrd_sym_year = ID2SYM(rb_intern("year"));
|
4136
|
+
rhrd_sym_zone = ID2SYM(rb_intern("zone"));
|
4137
|
+
|
4138
|
+
/* Define classes*/
|
4139
|
+
|
4140
|
+
rhrd_class = rb_define_class("Date", rb_cObject);
|
4141
|
+
rb_undef_alloc_func(rhrd_class);
|
4142
|
+
rhrd_s_class = rb_singleton_class(rhrd_class);
|
4143
|
+
|
4144
|
+
/* Define methods for all ruby versions */
|
4145
|
+
|
4146
|
+
rb_define_method(rhrd_s_class, "_load", rhrd_s__load, 1);
|
4147
|
+
rb_define_method(rhrd_s_class, "_strptime", rhrd_s__strptime, -1);
|
4148
|
+
rb_define_method(rhrd_s_class, "civil", rhrd_s_civil, -1);
|
4149
|
+
rb_define_method(rhrd_s_class, "commercial", rhrd_s_commercial, -1);
|
4150
|
+
rb_define_method(rhrd_s_class, "gregorian_leap?", rhrd_s_gregorian_leap_q, 1);
|
4151
|
+
rb_define_method(rhrd_s_class, "jd", rhrd_s_jd, -1);
|
4152
|
+
rb_define_method(rhrd_s_class, "julian_leap?", rhrd_s_julian_leap_q, 1);
|
4153
|
+
rb_define_method(rhrd_s_class, "new!", rhrd_s_new_b, -1);
|
4154
|
+
rb_define_method(rhrd_s_class, "ordinal", rhrd_s_ordinal, -1);
|
4155
|
+
rb_define_method(rhrd_s_class, "parse", rhrd_s_parse, -1);
|
4156
|
+
rb_define_method(rhrd_s_class, "strptime", rhrd_s_strptime, -1);
|
4157
|
+
rb_define_method(rhrd_s_class, "today", rhrd_s_today, -1);
|
4158
|
+
rb_define_method(rhrd_s_class, "valid_civil?", rhrd_s_valid_civil_q, -1);
|
4159
|
+
rb_define_method(rhrd_s_class, "valid_commercial?", rhrd_s_valid_commercial_q, -1);
|
4160
|
+
rb_define_method(rhrd_s_class, "valid_jd?", rhrd_s_valid_jd_q, -1);
|
4161
|
+
rb_define_method(rhrd_s_class, "valid_ordinal?", rhrd_s_valid_ordinal_q, -1);
|
4162
|
+
|
4163
|
+
rb_define_alias(rhrd_s_class, "leap?", "gregorian_leap?");
|
4164
|
+
rb_define_alias(rhrd_s_class, "new", "civil");
|
4165
|
+
rb_define_alias(rhrd_s_class, "valid_date?", "valid_civil?");
|
4166
|
+
|
4167
|
+
rb_define_private_method(rhrd_s_class, "_ragel_parse", rhrd_s__ragel_parse, 1);
|
4168
|
+
|
4169
|
+
rb_define_method(rhrd_class, "_dump", rhrd__dump, 1);
|
4170
|
+
rb_define_method(rhrd_class, "asctime", rhrd_asctime, 0);
|
4171
|
+
rb_define_method(rhrd_class, "cwday", rhrd_cwday, 0);
|
4172
|
+
rb_define_method(rhrd_class, "cweek", rhrd_cweek, 0);
|
4173
|
+
rb_define_method(rhrd_class, "cwyear", rhrd_cwyear, 0);
|
4174
|
+
rb_define_method(rhrd_class, "day", rhrd_day, 0);
|
4175
|
+
rb_define_method(rhrd_class, "day_fraction", rhrd_day_fraction, 0);
|
4176
|
+
rb_define_method(rhrd_class, "downto", rhrd_downto, 1);
|
4177
|
+
rb_define_method(rhrd_class, "eql?", rhrd_eql_q, 1);
|
4178
|
+
rb_define_method(rhrd_class, "gregorian", rhrd_gregorian, 0);
|
4179
|
+
rb_define_method(rhrd_class, "gregorian?", rhrd_gregorian_q, 0);
|
4180
|
+
rb_define_method(rhrd_class, "hash", rhrd_hash, 0);
|
4181
|
+
rb_define_method(rhrd_class, "inspect", rhrd_inspect, 0);
|
4182
|
+
rb_define_method(rhrd_class, "jd", rhrd_jd, 0);
|
4183
|
+
rb_define_method(rhrd_class, "julian?", rhrd_julian_q, 0);
|
4184
|
+
rb_define_method(rhrd_class, "ld", rhrd_ld, 0);
|
4185
|
+
rb_define_method(rhrd_class, "leap?", rhrd_leap_q, 0);
|
4186
|
+
rb_define_method(rhrd_class, "mjd", rhrd_mjd, 0);
|
4187
|
+
rb_define_method(rhrd_class, "month", rhrd_month, 0);
|
4188
|
+
rb_define_method(rhrd_class, "next", rhrd_next, 0);
|
4189
|
+
rb_define_method(rhrd_class, "new_start", rhrd_new_start, -1);
|
4190
|
+
rb_define_method(rhrd_class, "start", rhrd_start, 0);
|
4191
|
+
rb_define_method(rhrd_class, "step", rhrd_step, -1);
|
4192
|
+
rb_define_method(rhrd_class, "strftime", rhrd_strftime, -1);
|
4193
|
+
rb_define_method(rhrd_class, "to_s", rhrd_to_s, 0);
|
4194
|
+
rb_define_method(rhrd_class, "upto", rhrd_upto, 1);
|
4195
|
+
rb_define_method(rhrd_class, "wday", rhrd_wday, 0);
|
4196
|
+
rb_define_method(rhrd_class, "yday", rhrd_yday, 0);
|
4197
|
+
rb_define_method(rhrd_class, "year", rhrd_year, 0);
|
4198
|
+
|
4199
|
+
rb_define_alias(rhrd_class, "ajd", "jd");
|
4200
|
+
rb_define_alias(rhrd_class, "amjd", "mjd");
|
4201
|
+
rb_define_alias(rhrd_class, "ctime", "asctime");
|
4202
|
+
rb_define_alias(rhrd_class, "england", "gregorian");
|
4203
|
+
rb_define_alias(rhrd_class, "italy", "gregorian");
|
4204
|
+
rb_define_alias(rhrd_class, "julian", "gregorian");
|
4205
|
+
rb_define_alias(rhrd_class, "mday", "day");
|
4206
|
+
rb_define_alias(rhrd_class, "mon", "month");
|
4207
|
+
rb_define_alias(rhrd_class, "succ", "next");
|
4208
|
+
|
4209
|
+
rb_define_method(rhrd_class, ">>", rhrd_op_right_shift, 1);
|
4210
|
+
rb_define_method(rhrd_class, "<<", rhrd_op_left_shift, 1);
|
4211
|
+
rb_define_method(rhrd_class, "+", rhrd_op_plus, 1);
|
4212
|
+
rb_define_method(rhrd_class, "-", rhrd_op_minus, 1);
|
4213
|
+
rb_define_method(rhrd_class, "===", rhrd_op_relationship, 1);
|
4214
|
+
rb_define_method(rhrd_class, "<=>", rhrd_op_spaceship, 1);
|
4215
|
+
|
4216
|
+
rb_funcall(rhrd_class, rb_intern("include"), 1, rb_mComparable);
|
4217
|
+
|
4218
|
+
/* Setup static constants */
|
4219
|
+
|
4220
|
+
rhrd_monthnames = rb_ary_new2(13);
|
4221
|
+
rhrd_abbr_monthnames = rb_ary_new2(13);
|
4222
|
+
rb_ary_push(rhrd_monthnames, Qnil);
|
4223
|
+
rb_ary_push(rhrd_abbr_monthnames, Qnil);
|
4224
|
+
for(i = 1; i < 13; i++) {
|
4225
|
+
rb_ary_push(rhrd_monthnames, rb_str_new2(rhrd__month_names[i]));
|
4226
|
+
rb_ary_push(rhrd_abbr_monthnames, rb_str_new2(rhrd__abbr_month_names[i]));
|
4227
|
+
}
|
4228
|
+
|
4229
|
+
rhrd_daynames = rb_ary_new2(7);
|
4230
|
+
rhrd_abbr_daynames = rb_ary_new2(7);
|
4231
|
+
for(i = 0; i < 7; i++) {
|
4232
|
+
rb_ary_push(rhrd_daynames, rb_str_new2(rhrd__day_names[i]));
|
4233
|
+
rb_ary_push(rhrd_abbr_daynames, rb_str_new2(rhrd__abbr_day_names[i]));
|
4234
|
+
}
|
4235
|
+
|
4236
|
+
rhrd_zones_hash = rb_hash_new();
|
4237
|
+
rb_hash_aset(rhrd_zones_hash, rb_str_new2("a"), LONG2NUM(3600));
|
4238
|
+
rb_hash_aset(rhrd_zones_hash, rb_str_new2("adt"), LONG2NUM(-10800));
|
4239
|
+
rb_hash_aset(rhrd_zones_hash, rb_str_new2("afghanistan"), LONG2NUM(16200));
|
4240
|
+
rb_hash_aset(rhrd_zones_hash, rb_str_new2("ahst"), LONG2NUM(-36000));
|
4241
|
+
rb_hash_aset(rhrd_zones_hash, rb_str_new2("akdt"), LONG2NUM(-28800));
|
4242
|
+
rb_hash_aset(rhrd_zones_hash, rb_str_new2("akst"), LONG2NUM(-32400));
|
4243
|
+
rb_hash_aset(rhrd_zones_hash, rb_str_new2("alaskan"), LONG2NUM(-32400));
|
4244
|
+
rb_hash_aset(rhrd_zones_hash, rb_str_new2("arab"), LONG2NUM(10800));
|
4245
|
+
rb_hash_aset(rhrd_zones_hash, rb_str_new2("arabian"), LONG2NUM(14400));
|
4246
|
+
rb_hash_aset(rhrd_zones_hash, rb_str_new2("arabic"), LONG2NUM(10800));
|
4247
|
+
rb_hash_aset(rhrd_zones_hash, rb_str_new2("art"), LONG2NUM(-10800));
|
4248
|
+
rb_hash_aset(rhrd_zones_hash, rb_str_new2("ast"), LONG2NUM(-14400));
|
4249
|
+
rb_hash_aset(rhrd_zones_hash, rb_str_new2("at"), LONG2NUM(-7200));
|
4250
|
+
rb_hash_aset(rhrd_zones_hash, rb_str_new2("atlantic"), LONG2NUM(-14400));
|
4251
|
+
rb_hash_aset(rhrd_zones_hash, rb_str_new2("aus central"), LONG2NUM(34200));
|
4252
|
+
rb_hash_aset(rhrd_zones_hash, rb_str_new2("aus eastern"), LONG2NUM(36000));
|
4253
|
+
rb_hash_aset(rhrd_zones_hash, rb_str_new2("azores"), LONG2NUM(-3600));
|
4254
|
+
rb_hash_aset(rhrd_zones_hash, rb_str_new2("b"), LONG2NUM(7200));
|
4255
|
+
rb_hash_aset(rhrd_zones_hash, rb_str_new2("brst"), LONG2NUM(-7200));
|
4256
|
+
rb_hash_aset(rhrd_zones_hash, rb_str_new2("brt"), LONG2NUM(-10800));
|
4257
|
+
rb_hash_aset(rhrd_zones_hash, rb_str_new2("bst"), LONG2NUM(3600));
|
4258
|
+
rb_hash_aset(rhrd_zones_hash, rb_str_new2("bt"), LONG2NUM(10800));
|
4259
|
+
rb_hash_aset(rhrd_zones_hash, rb_str_new2("c"), LONG2NUM(10800));
|
4260
|
+
rb_hash_aset(rhrd_zones_hash, rb_str_new2("canada central"), LONG2NUM(-21600));
|
4261
|
+
rb_hash_aset(rhrd_zones_hash, rb_str_new2("cape verde"), LONG2NUM(-3600));
|
4262
|
+
rb_hash_aset(rhrd_zones_hash, rb_str_new2("cat"), LONG2NUM(-36000));
|
4263
|
+
rb_hash_aset(rhrd_zones_hash, rb_str_new2("caucasus"), LONG2NUM(14400));
|
4264
|
+
rb_hash_aset(rhrd_zones_hash, rb_str_new2("cct"), LONG2NUM(28800));
|
4265
|
+
rb_hash_aset(rhrd_zones_hash, rb_str_new2("cdt"), LONG2NUM(-18000));
|
4266
|
+
rb_hash_aset(rhrd_zones_hash, rb_str_new2("cen. australia"), LONG2NUM(34200));
|
4267
|
+
rb_hash_aset(rhrd_zones_hash, rb_str_new2("central"), LONG2NUM(-21600));
|
4268
|
+
rb_hash_aset(rhrd_zones_hash, rb_str_new2("central america"), LONG2NUM(-21600));
|
4269
|
+
rb_hash_aset(rhrd_zones_hash, rb_str_new2("central asia"), LONG2NUM(21600));
|
4270
|
+
rb_hash_aset(rhrd_zones_hash, rb_str_new2("central europe"), LONG2NUM(3600));
|
4271
|
+
rb_hash_aset(rhrd_zones_hash, rb_str_new2("central european"), LONG2NUM(3600));
|
4272
|
+
rb_hash_aset(rhrd_zones_hash, rb_str_new2("central pacific"), LONG2NUM(39600));
|
4273
|
+
rb_hash_aset(rhrd_zones_hash, rb_str_new2("cest"), LONG2NUM(7200));
|
4274
|
+
rb_hash_aset(rhrd_zones_hash, rb_str_new2("cet"), LONG2NUM(3600));
|
4275
|
+
rb_hash_aset(rhrd_zones_hash, rb_str_new2("china"), LONG2NUM(28800));
|
4276
|
+
rb_hash_aset(rhrd_zones_hash, rb_str_new2("clst"), LONG2NUM(-10800));
|
4277
|
+
rb_hash_aset(rhrd_zones_hash, rb_str_new2("clt"), LONG2NUM(-14400));
|
4278
|
+
rb_hash_aset(rhrd_zones_hash, rb_str_new2("cst"), LONG2NUM(-21600));
|
4279
|
+
rb_hash_aset(rhrd_zones_hash, rb_str_new2("d"), LONG2NUM(14400));
|
4280
|
+
rb_hash_aset(rhrd_zones_hash, rb_str_new2("dateline"), LONG2NUM(-43200));
|
4281
|
+
rb_hash_aset(rhrd_zones_hash, rb_str_new2("e"), LONG2NUM(18000));
|
4282
|
+
rb_hash_aset(rhrd_zones_hash, rb_str_new2("e. africa"), LONG2NUM(10800));
|
4283
|
+
rb_hash_aset(rhrd_zones_hash, rb_str_new2("e. australia"), LONG2NUM(36000));
|
4284
|
+
rb_hash_aset(rhrd_zones_hash, rb_str_new2("e. europe"), LONG2NUM(7200));
|
4285
|
+
rb_hash_aset(rhrd_zones_hash, rb_str_new2("e. south america"), LONG2NUM(-10800));
|
4286
|
+
rb_hash_aset(rhrd_zones_hash, rb_str_new2("eadt"), LONG2NUM(39600));
|
4287
|
+
rb_hash_aset(rhrd_zones_hash, rb_str_new2("east"), LONG2NUM(36000));
|
4288
|
+
rb_hash_aset(rhrd_zones_hash, rb_str_new2("eastern"), LONG2NUM(-18000));
|
4289
|
+
rb_hash_aset(rhrd_zones_hash, rb_str_new2("eat"), LONG2NUM(10800));
|
4290
|
+
rb_hash_aset(rhrd_zones_hash, rb_str_new2("edt"), LONG2NUM(-14400));
|
4291
|
+
rb_hash_aset(rhrd_zones_hash, rb_str_new2("eest"), LONG2NUM(10800));
|
4292
|
+
rb_hash_aset(rhrd_zones_hash, rb_str_new2("eet"), LONG2NUM(7200));
|
4293
|
+
rb_hash_aset(rhrd_zones_hash, rb_str_new2("egypt"), LONG2NUM(7200));
|
4294
|
+
rb_hash_aset(rhrd_zones_hash, rb_str_new2("ekaterinburg"), LONG2NUM(18000));
|
4295
|
+
rb_hash_aset(rhrd_zones_hash, rb_str_new2("est"), LONG2NUM(-18000));
|
4296
|
+
rb_hash_aset(rhrd_zones_hash, rb_str_new2("f"), LONG2NUM(21600));
|
4297
|
+
rb_hash_aset(rhrd_zones_hash, rb_str_new2("fiji"), LONG2NUM(43200));
|
4298
|
+
rb_hash_aset(rhrd_zones_hash, rb_str_new2("fle"), LONG2NUM(7200));
|
4299
|
+
rb_hash_aset(rhrd_zones_hash, rb_str_new2("fst"), LONG2NUM(7200));
|
4300
|
+
rb_hash_aset(rhrd_zones_hash, rb_str_new2("fwt"), LONG2NUM(3600));
|
4301
|
+
rb_hash_aset(rhrd_zones_hash, rb_str_new2("g"), LONG2NUM(25200));
|
4302
|
+
rb_hash_aset(rhrd_zones_hash, rb_str_new2("gmt"), LONG2NUM(0));
|
4303
|
+
rb_hash_aset(rhrd_zones_hash, rb_str_new2("greenland"), LONG2NUM(-10800));
|
4304
|
+
rb_hash_aset(rhrd_zones_hash, rb_str_new2("greenwich"), LONG2NUM(0));
|
4305
|
+
rb_hash_aset(rhrd_zones_hash, rb_str_new2("gst"), LONG2NUM(36000));
|
4306
|
+
rb_hash_aset(rhrd_zones_hash, rb_str_new2("gtb"), LONG2NUM(7200));
|
4307
|
+
rb_hash_aset(rhrd_zones_hash, rb_str_new2("h"), LONG2NUM(28800));
|
4308
|
+
rb_hash_aset(rhrd_zones_hash, rb_str_new2("hadt"), LONG2NUM(-32400));
|
4309
|
+
rb_hash_aset(rhrd_zones_hash, rb_str_new2("hast"), LONG2NUM(-36000));
|
4310
|
+
rb_hash_aset(rhrd_zones_hash, rb_str_new2("hawaiian"), LONG2NUM(-36000));
|
4311
|
+
rb_hash_aset(rhrd_zones_hash, rb_str_new2("hdt"), LONG2NUM(-32400));
|
4312
|
+
rb_hash_aset(rhrd_zones_hash, rb_str_new2("hst"), LONG2NUM(-36000));
|
4313
|
+
rb_hash_aset(rhrd_zones_hash, rb_str_new2("i"), LONG2NUM(32400));
|
4314
|
+
rb_hash_aset(rhrd_zones_hash, rb_str_new2("idle"), LONG2NUM(43200));
|
4315
|
+
rb_hash_aset(rhrd_zones_hash, rb_str_new2("idlw"), LONG2NUM(-43200));
|
4316
|
+
rb_hash_aset(rhrd_zones_hash, rb_str_new2("india"), LONG2NUM(19800));
|
4317
|
+
rb_hash_aset(rhrd_zones_hash, rb_str_new2("iran"), LONG2NUM(12600));
|
4318
|
+
rb_hash_aset(rhrd_zones_hash, rb_str_new2("ist"), LONG2NUM(19800));
|
4319
|
+
rb_hash_aset(rhrd_zones_hash, rb_str_new2("jerusalem"), LONG2NUM(7200));
|
4320
|
+
rb_hash_aset(rhrd_zones_hash, rb_str_new2("jst"), LONG2NUM(32400));
|
4321
|
+
rb_hash_aset(rhrd_zones_hash, rb_str_new2("k"), LONG2NUM(36000));
|
4322
|
+
rb_hash_aset(rhrd_zones_hash, rb_str_new2("korea"), LONG2NUM(32400));
|
4323
|
+
rb_hash_aset(rhrd_zones_hash, rb_str_new2("kst"), LONG2NUM(32400));
|
4324
|
+
rb_hash_aset(rhrd_zones_hash, rb_str_new2("l"), LONG2NUM(39600));
|
4325
|
+
rb_hash_aset(rhrd_zones_hash, rb_str_new2("m"), LONG2NUM(43200));
|
4326
|
+
rb_hash_aset(rhrd_zones_hash, rb_str_new2("malay peninsula"), LONG2NUM(28800));
|
4327
|
+
rb_hash_aset(rhrd_zones_hash, rb_str_new2("mdt"), LONG2NUM(-21600));
|
4328
|
+
rb_hash_aset(rhrd_zones_hash, rb_str_new2("mest"), LONG2NUM(7200));
|
4329
|
+
rb_hash_aset(rhrd_zones_hash, rb_str_new2("mesz"), LONG2NUM(7200));
|
4330
|
+
rb_hash_aset(rhrd_zones_hash, rb_str_new2("met"), LONG2NUM(3600));
|
4331
|
+
rb_hash_aset(rhrd_zones_hash, rb_str_new2("mewt"), LONG2NUM(3600));
|
4332
|
+
rb_hash_aset(rhrd_zones_hash, rb_str_new2("mexico"), LONG2NUM(-21600));
|
4333
|
+
rb_hash_aset(rhrd_zones_hash, rb_str_new2("mez"), LONG2NUM(3600));
|
4334
|
+
rb_hash_aset(rhrd_zones_hash, rb_str_new2("mid-atlantic"), LONG2NUM(-7200));
|
4335
|
+
rb_hash_aset(rhrd_zones_hash, rb_str_new2("mountain"), LONG2NUM(-25200));
|
4336
|
+
rb_hash_aset(rhrd_zones_hash, rb_str_new2("msd"), LONG2NUM(14400));
|
4337
|
+
rb_hash_aset(rhrd_zones_hash, rb_str_new2("msk"), LONG2NUM(10800));
|
4338
|
+
rb_hash_aset(rhrd_zones_hash, rb_str_new2("mst"), LONG2NUM(-25200));
|
4339
|
+
rb_hash_aset(rhrd_zones_hash, rb_str_new2("myanmar"), LONG2NUM(23400));
|
4340
|
+
rb_hash_aset(rhrd_zones_hash, rb_str_new2("n"), LONG2NUM(-3600));
|
4341
|
+
rb_hash_aset(rhrd_zones_hash, rb_str_new2("n. central asia"), LONG2NUM(21600));
|
4342
|
+
rb_hash_aset(rhrd_zones_hash, rb_str_new2("ndt"), LONG2NUM(-9000));
|
4343
|
+
rb_hash_aset(rhrd_zones_hash, rb_str_new2("nepal"), LONG2NUM(20700));
|
4344
|
+
rb_hash_aset(rhrd_zones_hash, rb_str_new2("new zealand"), LONG2NUM(43200));
|
4345
|
+
rb_hash_aset(rhrd_zones_hash, rb_str_new2("newfoundland"), LONG2NUM(-12600));
|
4346
|
+
rb_hash_aset(rhrd_zones_hash, rb_str_new2("north asia"), LONG2NUM(25200));
|
4347
|
+
rb_hash_aset(rhrd_zones_hash, rb_str_new2("north asia east"), LONG2NUM(28800));
|
4348
|
+
rb_hash_aset(rhrd_zones_hash, rb_str_new2("nst"), LONG2NUM(-12600));
|
4349
|
+
rb_hash_aset(rhrd_zones_hash, rb_str_new2("nt"), LONG2NUM(-39600));
|
4350
|
+
rb_hash_aset(rhrd_zones_hash, rb_str_new2("nzdt"), LONG2NUM(46800));
|
4351
|
+
rb_hash_aset(rhrd_zones_hash, rb_str_new2("nzst"), LONG2NUM(43200));
|
4352
|
+
rb_hash_aset(rhrd_zones_hash, rb_str_new2("nzt"), LONG2NUM(43200));
|
4353
|
+
rb_hash_aset(rhrd_zones_hash, rb_str_new2("o"), LONG2NUM(-7200));
|
4354
|
+
rb_hash_aset(rhrd_zones_hash, rb_str_new2("p"), LONG2NUM(-10800));
|
4355
|
+
rb_hash_aset(rhrd_zones_hash, rb_str_new2("pacific"), LONG2NUM(-28800));
|
4356
|
+
rb_hash_aset(rhrd_zones_hash, rb_str_new2("pacific sa"), LONG2NUM(-14400));
|
4357
|
+
rb_hash_aset(rhrd_zones_hash, rb_str_new2("pdt"), LONG2NUM(-25200));
|
4358
|
+
rb_hash_aset(rhrd_zones_hash, rb_str_new2("pst"), LONG2NUM(-28800));
|
4359
|
+
rb_hash_aset(rhrd_zones_hash, rb_str_new2("q"), LONG2NUM(-14400));
|
4360
|
+
rb_hash_aset(rhrd_zones_hash, rb_str_new2("r"), LONG2NUM(-18000));
|
4361
|
+
rb_hash_aset(rhrd_zones_hash, rb_str_new2("romance"), LONG2NUM(3600));
|
4362
|
+
rb_hash_aset(rhrd_zones_hash, rb_str_new2("russian"), LONG2NUM(10800));
|
4363
|
+
rb_hash_aset(rhrd_zones_hash, rb_str_new2("s"), LONG2NUM(-21600));
|
4364
|
+
rb_hash_aset(rhrd_zones_hash, rb_str_new2("sa eastern"), LONG2NUM(-10800));
|
4365
|
+
rb_hash_aset(rhrd_zones_hash, rb_str_new2("sa pacific"), LONG2NUM(-18000));
|
4366
|
+
rb_hash_aset(rhrd_zones_hash, rb_str_new2("sa western"), LONG2NUM(-14400));
|
4367
|
+
rb_hash_aset(rhrd_zones_hash, rb_str_new2("samoa"), LONG2NUM(-39600));
|
4368
|
+
rb_hash_aset(rhrd_zones_hash, rb_str_new2("sast"), LONG2NUM(7200));
|
4369
|
+
rb_hash_aset(rhrd_zones_hash, rb_str_new2("se asia"), LONG2NUM(25200));
|
4370
|
+
rb_hash_aset(rhrd_zones_hash, rb_str_new2("sgt"), LONG2NUM(28800));
|
4371
|
+
rb_hash_aset(rhrd_zones_hash, rb_str_new2("south africa"), LONG2NUM(7200));
|
4372
|
+
rb_hash_aset(rhrd_zones_hash, rb_str_new2("sri lanka"), LONG2NUM(21600));
|
4373
|
+
rb_hash_aset(rhrd_zones_hash, rb_str_new2("sst"), LONG2NUM(7200));
|
4374
|
+
rb_hash_aset(rhrd_zones_hash, rb_str_new2("swt"), LONG2NUM(3600));
|
4375
|
+
rb_hash_aset(rhrd_zones_hash, rb_str_new2("t"), LONG2NUM(-25200));
|
4376
|
+
rb_hash_aset(rhrd_zones_hash, rb_str_new2("taipei"), LONG2NUM(28800));
|
4377
|
+
rb_hash_aset(rhrd_zones_hash, rb_str_new2("tasmania"), LONG2NUM(36000));
|
4378
|
+
rb_hash_aset(rhrd_zones_hash, rb_str_new2("tokyo"), LONG2NUM(32400));
|
4379
|
+
rb_hash_aset(rhrd_zones_hash, rb_str_new2("tonga"), LONG2NUM(46800));
|
4380
|
+
rb_hash_aset(rhrd_zones_hash, rb_str_new2("u"), LONG2NUM(-28800));
|
4381
|
+
rb_hash_aset(rhrd_zones_hash, rb_str_new2("us eastern"), LONG2NUM(-18000));
|
4382
|
+
rb_hash_aset(rhrd_zones_hash, rb_str_new2("us mountain"), LONG2NUM(-25200));
|
4383
|
+
rb_hash_aset(rhrd_zones_hash, rb_str_new2("ut"), LONG2NUM(0));
|
4384
|
+
rb_hash_aset(rhrd_zones_hash, rb_str_new2("utc"), LONG2NUM(0));
|
4385
|
+
rb_hash_aset(rhrd_zones_hash, rb_str_new2("v"), LONG2NUM(-32400));
|
4386
|
+
rb_hash_aset(rhrd_zones_hash, rb_str_new2("vladivostok"), LONG2NUM(36000));
|
4387
|
+
rb_hash_aset(rhrd_zones_hash, rb_str_new2("w"), LONG2NUM(-36000));
|
4388
|
+
rb_hash_aset(rhrd_zones_hash, rb_str_new2("w. australia"), LONG2NUM(28800));
|
4389
|
+
rb_hash_aset(rhrd_zones_hash, rb_str_new2("w. central africa"), LONG2NUM(3600));
|
4390
|
+
rb_hash_aset(rhrd_zones_hash, rb_str_new2("w. europe"), LONG2NUM(3600));
|
4391
|
+
rb_hash_aset(rhrd_zones_hash, rb_str_new2("wadt"), LONG2NUM(28800));
|
4392
|
+
rb_hash_aset(rhrd_zones_hash, rb_str_new2("wast"), LONG2NUM(25200));
|
4393
|
+
rb_hash_aset(rhrd_zones_hash, rb_str_new2("wat"), LONG2NUM(3600));
|
4394
|
+
rb_hash_aset(rhrd_zones_hash, rb_str_new2("west"), LONG2NUM(3600));
|
4395
|
+
rb_hash_aset(rhrd_zones_hash, rb_str_new2("west asia"), LONG2NUM(18000));
|
4396
|
+
rb_hash_aset(rhrd_zones_hash, rb_str_new2("west pacific"), LONG2NUM(36000));
|
4397
|
+
rb_hash_aset(rhrd_zones_hash, rb_str_new2("wet"), LONG2NUM(0));
|
4398
|
+
rb_hash_aset(rhrd_zones_hash, rb_str_new2("x"), LONG2NUM(-39600));
|
4399
|
+
rb_hash_aset(rhrd_zones_hash, rb_str_new2("y"), LONG2NUM(-43200));
|
4400
|
+
rb_hash_aset(rhrd_zones_hash, rb_str_new2("yakutsk"), LONG2NUM(32400));
|
4401
|
+
rb_hash_aset(rhrd_zones_hash, rb_str_new2("ydt"), LONG2NUM(-28800));
|
4402
|
+
rb_hash_aset(rhrd_zones_hash, rb_str_new2("yst"), LONG2NUM(-32400));
|
4403
|
+
rb_hash_aset(rhrd_zones_hash, rb_str_new2("z"), LONG2NUM(0));
|
4404
|
+
rb_hash_aset(rhrd_zones_hash, rb_str_new2("zp4"), LONG2NUM(14400));
|
4405
|
+
rb_hash_aset(rhrd_zones_hash, rb_str_new2("zp5"), LONG2NUM(18000));
|
4406
|
+
rb_hash_aset(rhrd_zones_hash, rb_str_new2("zp6"), LONG2NUM(21600));
|
4407
|
+
|
4408
|
+
rhrd_start_num = LONG2NUM(RHR_JD_MIN - 1);
|
4409
|
+
rhrd_empty_string = rb_str_new("", 0);
|
4410
|
+
rhrd_string_colon = rb_str_new(":", 1);
|
4411
|
+
|
4412
|
+
/* Define some static regexps. The 1 for the options makes
|
4413
|
+
* it case insensitive, as I don't want to deal with including
|
4414
|
+
* the ruby regex header just to get it. */
|
4415
|
+
rhrd_zone_re = rb_reg_new(rhrd__zone_re_str, strlen(rhrd__zone_re_str), 1);
|
4416
|
+
rhrd_zone_dst_re = rb_reg_new(rhrd__zone_dst_re_str, strlen(rhrd__zone_dst_re_str), 1);
|
4417
|
+
rhrd_zone_sign_re = rb_reg_new(rhrd__zone_sign_re_str, strlen(rhrd__zone_sign_re_str), 1);
|
4418
|
+
rhrd_re_comma_period = rb_reg_new("[,.]", 4, 0);
|
4419
|
+
|
4420
|
+
/* Register global variables with Garbage collector, so users
|
4421
|
+
* who remove constants can't crash the interpreter. */
|
4422
|
+
|
4423
|
+
rb_global_variable(&rhrd_zones_hash);
|
4424
|
+
rb_global_variable(&rhrd_monthnames);
|
4425
|
+
rb_global_variable(&rhrd_abbr_monthnames);
|
4426
|
+
rb_global_variable(&rhrd_daynames);
|
4427
|
+
rb_global_variable(&rhrd_abbr_daynames);
|
4428
|
+
rb_global_variable(&rhrd_start_num);
|
4429
|
+
rb_global_variable(&rhrd_empty_string);
|
4430
|
+
rb_global_variable(&rhrd_string_colon);
|
4431
|
+
rb_global_variable(&rhrd_zone_re);
|
4432
|
+
rb_global_variable(&rhrd_zone_dst_re);
|
4433
|
+
rb_global_variable(&rhrd_zone_sign_re);
|
4434
|
+
rb_global_variable(&rhrd_re_comma_period);
|
4435
|
+
|
4436
|
+
/* Define constants accessible from ruby */
|
4437
|
+
|
4438
|
+
/* The julian day number for the day of calendar reform in Italy */
|
4439
|
+
rb_define_const(rhrd_class, "ITALY", LONG2NUM(RHR_JD_ITALY));
|
4440
|
+
/* The julian day number for the day of calendar reform in England */
|
4441
|
+
rb_define_const(rhrd_class, "ENGLAND", LONG2NUM(RHR_JD_ENGLAND));
|
4442
|
+
/* An integer lower than the lowest supported julian day number */
|
4443
|
+
rb_define_const(rhrd_class, "GREGORIAN", rhrd_start_num);
|
4444
|
+
/* An integer higher than the highest supported julian day number */
|
4445
|
+
rb_define_const(rhrd_class, "JULIAN", LONG2NUM(RHR_JD_MAX + 1));
|
4446
|
+
|
4447
|
+
/* A hash mapping lowercase time zone names to offsets
|
4448
|
+
* in seconds<br />ZONES['pst'] => -28800 */
|
4449
|
+
rb_define_const(rhrd_class, "ZONES", rhrd_zones_hash);
|
4450
|
+
/* An array of month names<br />MONTHNAMES[1] => 'January' */
|
4451
|
+
rb_define_const(rhrd_class, "MONTHNAMES", rhrd_monthnames);
|
4452
|
+
/* An array of abbreviated month names<br />ABBR_MONTHNAMES[1] => 'Jan' */
|
4453
|
+
rb_define_const(rhrd_class, "ABBR_MONTHNAMES", rhrd_abbr_monthnames);
|
4454
|
+
/* An array of day names<br />DAYNAMES[0] => 'Sunday' */
|
4455
|
+
rb_define_const(rhrd_class, "DAYNAMES", rhrd_daynames);
|
4456
|
+
/* An array of abbreviated day names<br />ABBR_DAYNAMES[0] => 'Sun' */
|
4457
|
+
rb_define_const(rhrd_class, "ABBR_DAYNAMES", rhrd_abbr_daynames);
|
4458
|
+
|
4459
|
+
#ifdef RUBY19
|
4460
|
+
|
4461
|
+
/* Define ruby 1.9 only methods */
|
4462
|
+
|
4463
|
+
rb_define_method(rhrd_s_class, "httpdate", rhrd_s_httpdate, -1);
|
4464
|
+
rb_define_method(rhrd_s_class, "iso8601", rhrd_s_iso8601, -1);
|
4465
|
+
rb_define_method(rhrd_s_class, "jisx0301", rhrd_s_jisx0301, -1);
|
4466
|
+
rb_define_method(rhrd_s_class, "rfc2822", rhrd_s_rfc2822, -1);
|
4467
|
+
rb_define_method(rhrd_s_class, "rfc3339", rhrd_s_rfc3339, -1);
|
4468
|
+
rb_define_method(rhrd_s_class, "xmlschema", rhrd_s_xmlschema, -1);
|
4469
|
+
|
4470
|
+
rb_define_alias(rhrd_s_class, "rfc822", "rfc2822");
|
4471
|
+
|
4472
|
+
rb_define_method(rhrd_class, "httpdate", rhrd_httpdate, 0);
|
4473
|
+
rb_define_method(rhrd_class, "jisx0301", rhrd_jisx0301, 0);
|
4474
|
+
rb_define_method(rhrd_class, "next_day", rhrd_next_day, -1);
|
4475
|
+
rb_define_method(rhrd_class, "next_month", rhrd_next_month, -1);
|
4476
|
+
rb_define_method(rhrd_class, "next_year", rhrd_next_year, -1);
|
4477
|
+
rb_define_method(rhrd_class, "prev_day", rhrd_prev_day, -1);
|
4478
|
+
rb_define_method(rhrd_class, "prev_month", rhrd_prev_month, -1);
|
4479
|
+
rb_define_method(rhrd_class, "prev_year", rhrd_prev_year, -1);
|
4480
|
+
rb_define_method(rhrd_class, "rfc2822", rhrd_rfc2822, 0);
|
4481
|
+
rb_define_method(rhrd_class, "rfc3339", rhrd_rfc3339, 0);
|
4482
|
+
rb_define_method(rhrd_class, "to_datetime", rhrd_to_datetime, 0);
|
4483
|
+
rb_define_method(rhrd_class, "to_time", rhrd_to_time, 0);
|
4484
|
+
|
4485
|
+
rb_define_alias(rhrd_class, "to_date", "gregorian");
|
4486
|
+
rb_define_alias(rhrd_class, "iso8601", "to_s");
|
4487
|
+
rb_define_alias(rhrd_class, "rfc822", "rfc2822");
|
4488
|
+
rb_define_alias(rhrd_class, "xmlschema", "to_s");
|
4489
|
+
|
4490
|
+
rb_define_method(rhrd_class, "sunday?", rhrd_sunday_q, 0);
|
4491
|
+
rb_define_method(rhrd_class, "monday?", rhrd_monday_q, 0);
|
4492
|
+
rb_define_method(rhrd_class, "tuesday?", rhrd_tuesday_q, 0);
|
4493
|
+
rb_define_method(rhrd_class, "wednesday?", rhrd_wednesday_q, 0);
|
4494
|
+
rb_define_method(rhrd_class, "thursday?", rhrd_thursday_q, 0);
|
4495
|
+
rb_define_method(rhrd_class, "friday?", rhrd_friday_q, 0);
|
4496
|
+
rb_define_method(rhrd_class, "saturday?", rhrd_saturday_q, 0);
|
4497
|
+
|
4498
|
+
rb_define_private_method(rhrd_s_class, "zone_to_diff", rhrd_s_zone_to_diff, 1);
|
4499
|
+
|
4500
|
+
rb_define_method(rb_cTime, "to_date", rhrd_time_to_date, 0);
|
4501
|
+
rb_define_method(rb_cTime, "to_time", rhrd_time_to_time, 0);
|
4502
|
+
#else
|
4503
|
+
|
4504
|
+
/* Define ruby 1.8 only methods */
|
4505
|
+
|
4506
|
+
rb_define_method(rhrd_s_class, "ajd_to_amjd", rhrd_s_ajd_to_amjd, 1);
|
4507
|
+
rb_define_method(rhrd_s_class, "ajd_to_jd", rhrd_s_ajd_to_jd, -1);
|
4508
|
+
rb_define_method(rhrd_s_class, "amjd_to_ajd", rhrd_s_amjd_to_ajd, 1);
|
4509
|
+
rb_define_method(rhrd_s_class, "civil_to_jd", rhrd_s_civil_to_jd, -1);
|
4510
|
+
rb_define_method(rhrd_s_class, "commercial_to_jd", rhrd_s_commercial_to_jd, -1);
|
4511
|
+
rb_define_method(rhrd_s_class, "day_fraction_to_time", rhrd_s_day_fraction_to_time, 1);
|
4512
|
+
rb_define_method(rhrd_s_class, "gregorian?", rhrd_s_gregorian_q, 2);
|
4513
|
+
rb_define_method(rhrd_s_class, "jd_to_ajd", rhrd_s_jd_to_ajd, -1);
|
4514
|
+
rb_define_method(rhrd_s_class, "jd_to_civil", rhrd_s_jd_to_civil, -1);
|
4515
|
+
rb_define_method(rhrd_s_class, "jd_to_commercial", rhrd_s_jd_to_commercial, -1);
|
4516
|
+
rb_define_method(rhrd_s_class, "jd_to_ld", rhrd_s_jd_to_ld, 1);
|
4517
|
+
rb_define_method(rhrd_s_class, "jd_to_mjd", rhrd_s_jd_to_mjd, 1);
|
4518
|
+
rb_define_method(rhrd_s_class, "jd_to_ordinal", rhrd_s_jd_to_ordinal, -1);
|
4519
|
+
rb_define_method(rhrd_s_class, "jd_to_wday", rhrd_s_jd_to_wday, 1);
|
4520
|
+
rb_define_method(rhrd_s_class, "julian?", rhrd_s_julian_q, 2);
|
4521
|
+
rb_define_method(rhrd_s_class, "ld_to_jd", rhrd_s_ld_to_jd, 1);
|
4522
|
+
rb_define_method(rhrd_s_class, "mjd_to_jd", rhrd_s_mjd_to_jd, 1);
|
4523
|
+
rb_define_method(rhrd_s_class, "ordinal_to_jd", rhrd_s_ordinal_to_jd, -1);
|
4524
|
+
rb_define_method(rhrd_s_class, "time_to_day_fraction", rhrd_s_time_to_day_fraction, 3);
|
4525
|
+
rb_define_method(rhrd_s_class, "valid_time?", rhrd_s_valid_time_q, 3);
|
4526
|
+
rb_define_method(rhrd_s_class, "zone_to_diff", rhrd_s_zone_to_diff, 1);
|
4527
|
+
|
4528
|
+
rb_define_alias(rhrd_s_class, "exist?", "valid_civil?");
|
4529
|
+
rb_define_alias(rhrd_s_class, "exist1?", "valid_jd?");
|
4530
|
+
rb_define_alias(rhrd_s_class, "exist2?", "valid_ordinal?");
|
4531
|
+
rb_define_alias(rhrd_s_class, "exist3?", "valid_civil?");
|
4532
|
+
rb_define_alias(rhrd_s_class, "existw?", "valid_commercial?");
|
4533
|
+
rb_define_alias(rhrd_s_class, "new0", "new!");
|
4534
|
+
rb_define_alias(rhrd_s_class, "new1", "jd");
|
4535
|
+
rb_define_alias(rhrd_s_class, "new2", "ordinal");
|
4536
|
+
rb_define_alias(rhrd_s_class, "new3", "civil");
|
4537
|
+
rb_define_alias(rhrd_s_class, "neww", "commercial");
|
4538
|
+
rb_define_alias(rhrd_s_class, "ns?", "gregorian?");
|
4539
|
+
rb_define_alias(rhrd_s_class, "os?", "julian?");
|
4540
|
+
|
4541
|
+
rb_define_alias(rhrd_class, "newsg", "new_start");
|
4542
|
+
rb_define_alias(rhrd_class, "ns?", "gregorian?");
|
4543
|
+
rb_define_alias(rhrd_class, "os?", "julian?");
|
4544
|
+
rb_define_alias(rhrd_class, "sg", "start");
|
4545
|
+
#endif
|
4546
|
+
|
4547
|
+
Init_datetime();
|
4548
|
+
}
|