home_run 0.9.0-x86-mswin32
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/CHANGELOG +3 -0
- data/LICENSE +19 -0
- data/README.rdoc +314 -0
- data/Rakefile +135 -0
- data/bench/cpu_bench.rb +279 -0
- data/bench/dt_garbage_bench.rb +11 -0
- data/bench/dt_mem_bench.rb +14 -0
- data/bench/garbage_bench.rb +11 -0
- data/bench/mem_bench.rb +14 -0
- data/bin/home_run +91 -0
- data/default.mspec +12 -0
- data/ext/1.8/date_ext.so +0 -0
- data/ext/1.9/date_ext.so +0 -0
- data/ext/date.rb +7 -0
- data/ext/date/format.rb +842 -0
- data/ext/date_ext.c +4548 -0
- data/ext/date_parser.c +367 -0
- data/ext/date_parser.rl +134 -0
- data/ext/datetime.c +2804 -0
- data/ext/extconf.rb +6 -0
- data/spec/date/accessor_spec.rb +176 -0
- data/spec/date/add_month_spec.rb +26 -0
- data/spec/date/add_spec.rb +23 -0
- data/spec/date/boat_spec.rb +38 -0
- data/spec/date/civil_spec.rb +147 -0
- data/spec/date/commercial_spec.rb +153 -0
- data/spec/date/constants_spec.rb +44 -0
- data/spec/date/conversions_spec.rb +246 -0
- data/spec/date/day_spec.rb +73 -0
- data/spec/date/downto_spec.rb +17 -0
- data/spec/date/eql_spec.rb +16 -0
- data/spec/date/format_spec.rb +52 -0
- data/spec/date/gregorian_spec.rb +52 -0
- data/spec/date/hash_spec.rb +11 -0
- data/spec/date/julian_spec.rb +129 -0
- data/spec/date/leap_spec.rb +19 -0
- data/spec/date/minus_month_spec.rb +25 -0
- data/spec/date/minus_spec.rb +51 -0
- data/spec/date/next_prev_spec.rb +108 -0
- data/spec/date/ordinal_spec.rb +83 -0
- data/spec/date/parse_spec.rb +442 -0
- data/spec/date/parsing_spec.rb +77 -0
- data/spec/date/relationship_spec.rb +28 -0
- data/spec/date/step_spec.rb +109 -0
- data/spec/date/strftime_spec.rb +223 -0
- data/spec/date/strptime_spec.rb +201 -0
- data/spec/date/succ_spec.rb +20 -0
- data/spec/date/today_spec.rb +15 -0
- data/spec/date/upto_spec.rb +17 -0
- data/spec/datetime/accessor_spec.rb +218 -0
- data/spec/datetime/add_month_spec.rb +26 -0
- data/spec/datetime/add_spec.rb +36 -0
- data/spec/datetime/boat_spec.rb +43 -0
- data/spec/datetime/constructor_spec.rb +142 -0
- data/spec/datetime/conversions_spec.rb +54 -0
- data/spec/datetime/day_spec.rb +73 -0
- data/spec/datetime/downto_spec.rb +39 -0
- data/spec/datetime/eql_spec.rb +17 -0
- data/spec/datetime/format_spec.rb +59 -0
- data/spec/datetime/hash_spec.rb +11 -0
- data/spec/datetime/leap_spec.rb +19 -0
- data/spec/datetime/minus_month_spec.rb +25 -0
- data/spec/datetime/minus_spec.rb +77 -0
- data/spec/datetime/next_prev_spec.rb +138 -0
- data/spec/datetime/now_spec.rb +18 -0
- data/spec/datetime/parse_spec.rb +390 -0
- data/spec/datetime/parsing_spec.rb +77 -0
- data/spec/datetime/relationship_spec.rb +28 -0
- data/spec/datetime/step_spec.rb +155 -0
- data/spec/datetime/strftime_spec.rb +118 -0
- data/spec/datetime/strptime_spec.rb +117 -0
- data/spec/datetime/succ_spec.rb +24 -0
- data/spec/datetime/upto_spec.rb +39 -0
- data/spec/spec_helper.rb +59 -0
- metadata +154 -0
data/ext/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
|
+
}
|