icu4r 0.1.3.2006.01.26

Sign up to get free protection for your applications and to get access to all the features.
data/calendar.c ADDED
@@ -0,0 +1,576 @@
1
+ #include <unicode/ucal.h>
2
+ #include <unicode/uenum.h>
3
+ #include <unicode/udat.h>
4
+ #include "icu_common.h"
5
+ extern VALUE rb_cUString;
6
+ extern VALUE icu_ustr_new(UChar * ptr, long len);
7
+ extern VALUE icu_ustr_new_set(UChar * ptr, long len, long capa);
8
+ static VALUE s_calendar_fields;
9
+ extern VALUE rb_cUCalendar;
10
+ #define UCALENDAR(obj) ((UCalendar *)DATA_PTR(obj))
11
+ /**
12
+ * Document-class: UCalendar
13
+ *
14
+ * The UCalendar class provides methods for converting between a specific instant in
15
+ * time and a set of calendar fields such as YEAR, MONTH, DAY_OF_MONTH, HOUR, and so on,
16
+ * and for manipulating the calendar fields, such as getting the date of the next week.
17
+ * An instant in time can be represented by a millisecond value that is an offset from the
18
+ * Epoch, January 1, 1970 00:00:00.000 GMT (Gregorian).
19
+ *
20
+ * Also timezone info and methods are provided.
21
+ *
22
+ * NOTE: months are zero-based.
23
+ */
24
+
25
+ /**
26
+ * call-seq:
27
+ * UCalendar.time_zones
28
+ *
29
+ * Returns array with all time zones (as UString values).
30
+ */
31
+ VALUE icu4r_cal_all_tz (VALUE obj)
32
+ {
33
+ UErrorCode status = U_ZERO_ERROR;
34
+ UEnumeration * zones ;
35
+ VALUE ret ;
36
+ UChar * name;
37
+ int32_t len;
38
+ zones = ucal_openTimeZones (&status);
39
+ ICU_RAISE(status);
40
+ ret = rb_ary_new();
41
+ while( (name = (UChar*)uenum_unext(zones, &len, &status))) {
42
+ rb_ary_push(ret, icu_ustr_new(name, len));
43
+ }
44
+ uenum_close(zones);
45
+ return ret;
46
+ }
47
+
48
+
49
+ /**
50
+ * call-seq:
51
+ * UCalendar.tz_for_country(country)
52
+ *
53
+ * Returns array with all time zones associated with the given country.
54
+ * Note: <code>country</code> must be value of type String.
55
+ * Returned array content is UString's
56
+ *
57
+ * UCalendar.tz_for_country("GB") # => [ "Europe/Belfast", "Europe/London", "GB", "GB-Eire"]
58
+ *
59
+ */
60
+ VALUE icu4r_cal_country_tz (VALUE obj, VALUE ctry)
61
+ {
62
+ UErrorCode status = U_ZERO_ERROR;
63
+ UEnumeration * zones ;
64
+ VALUE ret ;
65
+ UChar * name;
66
+ int32_t len;
67
+ Check_Type(ctry, T_STRING);
68
+ zones = ucal_openCountryTimeZones (RSTRING(ctry)->ptr, &status) ;
69
+ ICU_RAISE(status);
70
+ ret = rb_ary_new();
71
+ while( (name = (UChar*)uenum_unext(zones, &len, &status))) {
72
+ rb_ary_push(ret, icu_ustr_new(name, len));
73
+ }
74
+ uenum_close(zones);
75
+ return ret;
76
+ }
77
+
78
+ /**
79
+ * call-seq:
80
+ * UCalendar.default_tz => ustring
81
+ *
82
+ * Returns the default time zone (UString).
83
+ *
84
+ * UCalendar.default_tz # "EET"
85
+ *
86
+ */
87
+ VALUE icu4r_cal_get_default_tz(VALUE obj)
88
+ {
89
+ UErrorCode status = U_ZERO_ERROR;
90
+ UChar * buf ;
91
+ long capa = 0;
92
+ capa = ucal_getDefaultTimeZone (buf, capa, &status);
93
+ if( U_BUFFER_OVERFLOW_ERROR == status) {
94
+ buf = ALLOC_N(UChar, capa+1);
95
+ status = U_ZERO_ERROR;
96
+ capa = ucal_getDefaultTimeZone (buf, capa, &status);
97
+ return icu_ustr_new_set(buf, capa, capa+1);
98
+ }
99
+ ICU_RAISE(status);
100
+ return Qnil;
101
+ }
102
+
103
+ /**
104
+ * call-seq:
105
+ * UCalendar.default_tz = ustring
106
+ *
107
+ * Set the default time zone.
108
+ *
109
+ * UCalendar.default_tz="GMT+00".u
110
+ * UCalendar.default_tz="Europe/Paris".u
111
+ */
112
+ VALUE icu4r_cal_set_default_tz(VALUE obj, VALUE tz)
113
+ {
114
+ UErrorCode status = U_ZERO_ERROR;
115
+ Check_Class(tz, rb_cUString);
116
+ ucal_setDefaultTimeZone (ICU_PTR(tz), &status);
117
+ ICU_RAISE(status);
118
+ return tz;
119
+ }
120
+ /**
121
+ * call-seq:
122
+ * UCalendar.dst_savings(zone_id)
123
+ *
124
+ * Return the amount of time in milliseconds that the clock is advanced
125
+ * during daylight savings time for the given time zone, or zero if the time
126
+ * zone does not observe daylight savings time.
127
+ *
128
+ * UCalendar.dst_savings("GMT+00".u) # => 3600000
129
+ *
130
+ */
131
+ VALUE icu4r_cal_dst_savings(VALUE obj, VALUE zone)
132
+ {
133
+ UErrorCode status = U_ZERO_ERROR;
134
+ int32_t dst;
135
+ Check_Class(zone, rb_cUString);
136
+ dst = ucal_getDSTSavings (ICU_PTR(zone), &status);
137
+ ICU_RAISE(status);
138
+ return INT2FIX(dst);
139
+ }
140
+
141
+ /**
142
+ * call-seq:
143
+ * UCalendar.now
144
+ *
145
+ * Get the current date and time. in millis
146
+ *
147
+ * UCalendar.now # => 1137934561000.0
148
+ *
149
+ */
150
+ VALUE icu4r_cal_now(VALUE obj){
151
+ return rb_float_new(ucal_getNow());
152
+ }
153
+ //-----------------
154
+
155
+ void icu4r_cal_free(UCalendar * cal){
156
+ ucal_close(cal);
157
+ }
158
+
159
+ /**
160
+ * call-seq:
161
+ * UCalendar.new(zone_id = nil, locale = nil, traditional = false)
162
+ *
163
+ * Creates new instance of UCalendar, for given time zone id (UString),
164
+ * locale (Ruby String), and kind , by default gregorian.
165
+ * New instance has current time.
166
+ *
167
+ */
168
+ VALUE icu4r_cal_init (int argc, VALUE * argv, VALUE self)
169
+ {
170
+ VALUE zone, loc, cal_type;
171
+ UChar * zone_id = NULL;
172
+ char * locale = NULL;
173
+ UCalendarType c_type = UCAL_GREGORIAN;
174
+ int32_t n, zone_len =0 , locale_len =0;
175
+ UCalendar * calendar;
176
+ VALUE ret;
177
+ UErrorCode status = U_ZERO_ERROR;
178
+ n = rb_scan_args(argc, argv, "03", &zone, &loc, &cal_type);
179
+ if( n >= 1) {
180
+ Check_Class(zone, rb_cUString);
181
+ zone_id = ICU_PTR(zone);
182
+ zone_len = ICU_LEN(zone);
183
+ }
184
+ if( n >= 2) {
185
+ Check_Type(loc, T_STRING);
186
+ locale = RSTRING(loc)->ptr;
187
+ locale_len = RSTRING(loc)->len;
188
+ }
189
+ if( n >= 3) {
190
+ if( Qtrue == cal_type ) {
191
+ c_type = UCAL_TRADITIONAL;
192
+ }
193
+ }
194
+ calendar = ucal_open(zone_id, zone_len, locale, c_type, &status);
195
+ ICU_RAISE(status);
196
+ ret = Data_Wrap_Struct(self, 0, icu4r_cal_free, calendar);
197
+ return ret;
198
+ }
199
+
200
+ int icu4r_get_cal_field_int(VALUE field)
201
+ {
202
+ VALUE field_const;
203
+ field_const = rb_hash_aref(s_calendar_fields, field);
204
+ if(field_const == Qnil)
205
+ rb_raise(rb_eArgError, "no such field %s", rb_obj_as_string(field));
206
+ return NUM2INT(field_const);
207
+ }
208
+
209
+ /**
210
+ * call-seq:
211
+ * calendar.add(field, int_amount)
212
+ *
213
+ * Add a specified signed amount to a particular field in a UCalendar.
214
+ *
215
+ * c.add(:week_of_year, 2)
216
+ */
217
+ VALUE icu4r_cal_add(VALUE obj, VALUE field, VALUE amount)
218
+ {
219
+ UErrorCode status = U_ZERO_ERROR;
220
+ int date_field;
221
+ Check_Type(field, T_SYMBOL);
222
+ Check_Type(amount, T_FIXNUM);
223
+ date_field = icu4r_get_cal_field_int(field);
224
+ ucal_add(UCALENDAR(obj), date_field, FIX2INT(amount) , &status);
225
+ ICU_RAISE(status);
226
+ return Qnil;
227
+ }
228
+
229
+ /**
230
+ * call-seq:
231
+ * calendar.roll(field, int_amount)
232
+ *
233
+ * Adds a signed amount to the specified calendar field without changing larger fields.
234
+ * A negative roll amount means to subtract from field without changing larger fields.
235
+ * If the specified amount is 0, this method performs nothing.
236
+ *
237
+ * Example: Consider a GregorianCalendar originally set to August 31, 1999. Calling roll(:month, 8)
238
+ * sets the calendar to April 30, 1999. Using a Gregorian Calendar, the :day_of_month field cannot
239
+ * be 31 in the month April. :day_of_month is set to the closest possible value, 30. The :year field
240
+ * maintains the value of 1999 because it is a larger field than :month.
241
+ */
242
+ VALUE icu4r_cal_roll(VALUE obj, VALUE field, VALUE amount)
243
+ {
244
+ UErrorCode status = U_ZERO_ERROR;
245
+ int date_field;
246
+ Check_Type(field, T_SYMBOL);
247
+ Check_Type(amount, T_FIXNUM);
248
+ date_field = icu4r_get_cal_field_int(field);
249
+ ucal_roll(UCALENDAR(obj), date_field, FIX2INT(amount) , &status);
250
+ ICU_RAISE(status);
251
+ return Qnil;
252
+ }
253
+ /**
254
+ * call-seq:
255
+ * calendar[field]
256
+ *
257
+ * Get the current value of a field from a UCalendar.
258
+ *
259
+ */
260
+ VALUE icu4r_cal_aref(VALUE obj, VALUE field)
261
+ {
262
+ UErrorCode status = U_ZERO_ERROR;
263
+ int date_field;
264
+ int32_t value;
265
+ Check_Type(field, T_SYMBOL);
266
+ date_field = icu4r_get_cal_field_int(field);
267
+ value = ucal_get(UCALENDAR(obj), date_field, &status);
268
+ ICU_RAISE(status);
269
+ return INT2FIX(value);
270
+ }
271
+
272
+ /**
273
+ * call-seq:
274
+ * calendar[field]=int_value
275
+ *
276
+ * Set the value of a field in a UCalendar.
277
+ */
278
+ VALUE icu4r_cal_aset(VALUE obj, VALUE field, VALUE amount)
279
+ {
280
+ int date_field, ret;
281
+ UErrorCode status = U_ZERO_ERROR;
282
+ Check_Type(field, T_SYMBOL);
283
+ Check_Type(amount, T_FIXNUM);
284
+ date_field = icu4r_get_cal_field_int(field);
285
+ ucal_set(UCALENDAR(obj), date_field, FIX2INT(amount) );
286
+ ret = ucal_get(UCALENDAR(obj), date_field, &status);
287
+
288
+ return INT2FIX(ret);
289
+ }
290
+ /**
291
+ * call-seq:
292
+ * calendar.millis
293
+ *
294
+ * return this calendar value in milliseconds.
295
+ */
296
+ VALUE icu4r_cal_millis(VALUE obj)
297
+ {
298
+ UErrorCode status = U_ZERO_ERROR;
299
+ double millis;
300
+ millis = ucal_getMillis(UCALENDAR(obj), &status);
301
+ ICU_RAISE(status);
302
+ return rb_float_new(millis);
303
+ }
304
+ /**
305
+ * call-seq:
306
+ * calendar.millis = new_value
307
+ *
308
+ * Sets calendar's value in milliseconds.
309
+ */
310
+ VALUE icu4r_cal_set_millis(VALUE obj,VALUE milli)
311
+ {
312
+ UErrorCode status = U_ZERO_ERROR;
313
+ Check_Type(milli, T_FLOAT);
314
+ ucal_setMillis(UCALENDAR(obj), rb_num2dbl(milli), &status);
315
+ ICU_RAISE(status);
316
+ return Qnil;
317
+ }
318
+
319
+ /**
320
+ * call-seq:
321
+ * calendar.set_date(year, month, date)
322
+ *
323
+ * Set a UCalendar's current date.
324
+ */
325
+ VALUE icu4r_cal_set_date(VALUE obj,VALUE year, VALUE mon, VALUE date)
326
+ {
327
+ UErrorCode status = U_ZERO_ERROR;
328
+ Check_Type(year, T_FIXNUM);
329
+ Check_Type(mon, T_FIXNUM);
330
+ Check_Type(date, T_FIXNUM);
331
+ ucal_setDate(UCALENDAR(obj), FIX2INT(year), FIX2INT(mon), FIX2INT(date), &status);
332
+ ICU_RAISE(status);
333
+ return Qnil;
334
+ }
335
+ /**
336
+ * call-seq:
337
+ * calendar.set_date_time(year, month, date, hour, minute, second)
338
+ *
339
+ * Set a UCalendar's current date and time.
340
+ */
341
+ VALUE icu4r_cal_set_date_time(VALUE obj,VALUE year, VALUE mon, VALUE date, VALUE hour, VALUE min, VALUE sec)
342
+ {
343
+ UErrorCode status = U_ZERO_ERROR;
344
+ Check_Type(year, T_FIXNUM);
345
+ Check_Type(mon, T_FIXNUM);
346
+ Check_Type(date, T_FIXNUM);
347
+ Check_Type(hour, T_FIXNUM);
348
+ Check_Type(min, T_FIXNUM);
349
+ Check_Type(sec, T_FIXNUM);
350
+
351
+ ucal_setDateTime(UCALENDAR(obj),
352
+ FIX2INT(year), FIX2INT(mon), FIX2INT(date),
353
+ FIX2INT(hour), FIX2INT(min), FIX2INT(sec),
354
+ &status);
355
+ ICU_RAISE(status);
356
+ return Qnil;
357
+ }
358
+
359
+ /**
360
+ * call-seq:
361
+ * calendar.time_zone = zone_id
362
+ *
363
+ * Set the TimeZone used by a UCalendar.
364
+ */
365
+ VALUE icu4r_cal_set_tz(VALUE obj, VALUE zone)
366
+ {
367
+ UErrorCode status = U_ZERO_ERROR;
368
+ Check_Class(zone, rb_cUString);
369
+ ucal_setTimeZone(UCALENDAR(obj), ICU_PTR(zone), ICU_LEN(zone), &status);
370
+ ICU_RAISE(status);
371
+ return Qnil;
372
+
373
+ }
374
+
375
+ /**
376
+ * call-seq:
377
+ * calendar.in_daylight_time?
378
+ *
379
+ * Determine if a UCalendar is currently in daylight savings time.
380
+ *
381
+ * Daylight savings time is not used in all parts of the world
382
+ */
383
+ VALUE icu4r_cal_in_daylight(VALUE obj)
384
+ {
385
+ UErrorCode status = U_ZERO_ERROR;
386
+ int32_t answer;
387
+ answer = ucal_inDaylightTime(UCALENDAR(obj), &status);
388
+ ICU_RAISE(status);
389
+ return answer ? Qtrue : Qfalse;
390
+ }
391
+
392
+ /**
393
+ * call-seq:
394
+ * calendar.time_zone
395
+ *
396
+ * Returns the TimeZone used by a UCalendar.
397
+ */
398
+ VALUE icu4r_cal_get_tz (int argc, VALUE * argv, VALUE obj)
399
+ {
400
+ UErrorCode status = U_ZERO_ERROR;
401
+ UChar * buf = NULL;
402
+ long capa = 0;
403
+ char *locale = NULL;
404
+ VALUE loc;
405
+ if( rb_scan_args(argc, argv, "01", &loc) == 1){
406
+ Check_Type(loc, T_STRING);
407
+ locale = RSTRING(loc)->ptr;
408
+ }
409
+
410
+ capa = ucal_getTimeZoneDisplayName(UCALENDAR(obj), UCAL_STANDARD, locale, buf, capa, &status);
411
+ if( U_BUFFER_OVERFLOW_ERROR == status) {
412
+ buf = ALLOC_N(UChar, capa+1);
413
+ status = U_ZERO_ERROR;
414
+ capa = ucal_getTimeZoneDisplayName(UCALENDAR(obj), UCAL_STANDARD, locale, buf, capa, &status);
415
+ return icu_ustr_new_set(buf, capa, capa+1);
416
+ }
417
+ ICU_RAISE(status);
418
+ return Qnil;
419
+
420
+ }
421
+ /** call-seq:
422
+ * calendar.format(pattern = nil , locale = nil)
423
+ *
424
+ * Formats this calendar time using given pattern and locale. Returns UString or nil on failure
425
+ */
426
+ VALUE icu4r_cal_format(int argc, VALUE * argv, VALUE obj)
427
+ {
428
+ UErrorCode status = U_ZERO_ERROR;
429
+ UDateFormat * format;
430
+ UDate time_to_format;
431
+ UChar * buf = NULL, * pattern = NULL;
432
+ long capa = 0, pattern_len = 0;
433
+ char *locale = NULL;
434
+ VALUE loc, pat, ret = Qnil;
435
+ int n ;
436
+
437
+
438
+
439
+ n = rb_scan_args(argc, argv, "02", &pat, &loc);
440
+ if( n == 2) {
441
+ Check_Type(loc, T_STRING);
442
+ locale = RSTRING(loc)->ptr;
443
+ }
444
+ if (n >= 1 && pat != Qnil) {
445
+ Check_Class(pat, rb_cUString);
446
+ pattern = ICU_PTR(pat);
447
+ pattern_len = ICU_LEN(pat);
448
+ }
449
+
450
+ format = udat_open(UDAT_FULL, UDAT_FULL, locale, NULL, 0, NULL, 0, &status);
451
+ if( pattern ) {
452
+ udat_applyPattern(format, 0, pattern, pattern_len);
453
+ }
454
+ ICU_RAISE(status);
455
+ udat_setCalendar(format, UCALENDAR(obj));
456
+ time_to_format = ucal_getMillis(UCALENDAR(obj), &status);
457
+
458
+ capa = udat_format(format, time_to_format, buf, capa, NULL, &status);
459
+ if( U_BUFFER_OVERFLOW_ERROR == status) {
460
+ buf = ALLOC_N(UChar, capa+1);
461
+ status = U_ZERO_ERROR;
462
+ capa = udat_format(format, time_to_format, buf, capa, NULL, &status);
463
+ ret = icu_ustr_new_set(buf, capa, capa+1);
464
+ }
465
+ udat_close(format);
466
+ ICU_RAISE(status);
467
+ return ret;
468
+ }
469
+
470
+ /**
471
+ * Document-method: clone
472
+ *
473
+ * call-seq:
474
+ * cal.clone => UCalendar
475
+ *
476
+ * Create and return a copy of this calendar.
477
+ */
478
+ extern VALUE icu4r_cal_clone(VALUE obj);
479
+ /**
480
+ * Document-method: eql?
481
+ *
482
+ * call-seq:
483
+ * cal.eql?(other)
484
+ *
485
+ * Compares the equality of two UCalendar objects.
486
+ *
487
+ * This comparison is very exacting; two UCalendar objects must be in exactly the
488
+ * same state to be considered equal.
489
+ */
490
+ extern VALUE icu4r_cal_equal(VALUE obj, VALUE other);
491
+
492
+ /**
493
+ * Document-method: >
494
+ *
495
+ * call-seq:
496
+ * cal > when
497
+ *
498
+ * True if the current time of this UCalendar is after the time of UCalendar +when+; false otherwise.
499
+ */
500
+ extern VALUE icu4r_cal_after(VALUE obj, VALUE other);
501
+ /**
502
+ * Document-method: <
503
+ *
504
+ * call-seq:
505
+ * cal < when
506
+ *
507
+ * True if the current time of this UCalendar is before the time of UCalendar +when+; false otherwise.
508
+ */
509
+ extern VALUE icu4r_cal_before(VALUE obj, VALUE other);
510
+ /**
511
+ * Document-method: ==
512
+ *
513
+ * call-seq:
514
+ * cal == when
515
+ *
516
+ * True if the current time of this UCalendar is equal to the time of UCalendar +when+; false otherwise.
517
+ */
518
+ extern VALUE icu4r_cal_time_equals(VALUE obj, VALUE other);
519
+
520
+ void initialize_calendar(void) {
521
+
522
+ rb_cUCalendar = rb_define_class("UCalendar", rb_cObject);
523
+ s_calendar_fields = rb_hash_new();
524
+ /* Valid symbols to use as field reference in UCalendar#[], UCalendar#[]=, UCalendar#add are:
525
+ :era , :year , :month , :week_of_year , :week_of_month , :date , :day_of_year , :day_of_week, :day_of_week_in_month,
526
+ :am_pm , :hour , :hour_of_day , :minute , :second , :millisecond , :zone_offset , :dst_offset:
527
+ */
528
+ rb_define_const(rb_cUCalendar, "UCALENDAR_FIELDS", s_calendar_fields);
529
+ rb_hash_aset(s_calendar_fields, ID2SYM(rb_intern("era")), INT2NUM(UCAL_ERA ));
530
+ rb_hash_aset(s_calendar_fields, ID2SYM(rb_intern("year")), INT2NUM(UCAL_YEAR ));
531
+ rb_hash_aset(s_calendar_fields, ID2SYM(rb_intern("month")), INT2NUM(UCAL_MONTH));
532
+ rb_hash_aset(s_calendar_fields, ID2SYM(rb_intern("week_of_year")), INT2NUM(UCAL_WEEK_OF_YEAR ));
533
+ rb_hash_aset(s_calendar_fields, ID2SYM(rb_intern("week_of_month")), INT2NUM(UCAL_WEEK_OF_MONTH));
534
+ rb_hash_aset(s_calendar_fields, ID2SYM(rb_intern("date")), INT2NUM(UCAL_DATE));
535
+ rb_hash_aset(s_calendar_fields, ID2SYM(rb_intern("day_of_year")), INT2NUM(UCAL_DAY_OF_YEAR));
536
+ rb_hash_aset(s_calendar_fields, ID2SYM(rb_intern("day_of_week")), INT2NUM(UCAL_DAY_OF_WEEK));
537
+ rb_hash_aset(s_calendar_fields, ID2SYM(rb_intern("day_of_week_in_month")), INT2NUM(UCAL_DAY_OF_WEEK_IN_MONTH));
538
+ rb_hash_aset(s_calendar_fields, ID2SYM(rb_intern("am_pm")), INT2NUM(UCAL_AM_PM));
539
+ rb_hash_aset(s_calendar_fields, ID2SYM(rb_intern("hour")), INT2NUM(UCAL_HOUR));
540
+ rb_hash_aset(s_calendar_fields, ID2SYM(rb_intern("hour_of_day")), INT2NUM(UCAL_HOUR_OF_DAY));
541
+ rb_hash_aset(s_calendar_fields, ID2SYM(rb_intern("minute")), INT2NUM(UCAL_MINUTE ));
542
+ rb_hash_aset(s_calendar_fields, ID2SYM(rb_intern("second")), INT2NUM(UCAL_SECOND));
543
+ rb_hash_aset(s_calendar_fields, ID2SYM(rb_intern("millisecond")), INT2NUM(UCAL_MILLISECOND ));
544
+ rb_hash_aset(s_calendar_fields, ID2SYM(rb_intern("zone_offset")), INT2NUM(UCAL_ZONE_OFFSET));
545
+ rb_hash_aset(s_calendar_fields, ID2SYM(rb_intern("dst_offset")), INT2NUM(UCAL_DST_OFFSET));
546
+
547
+
548
+ rb_define_singleton_method(rb_cUCalendar, "now", icu4r_cal_now, 0);
549
+
550
+ rb_define_singleton_method(rb_cUCalendar, "default_tz=", icu4r_cal_set_default_tz, 1);
551
+ rb_define_singleton_method(rb_cUCalendar, "default_tz", icu4r_cal_get_default_tz, 0);
552
+ rb_define_singleton_method(rb_cUCalendar, "time_zones", icu4r_cal_all_tz, 0);
553
+ rb_define_singleton_method(rb_cUCalendar, "tz_for_country", icu4r_cal_country_tz, 1);
554
+ rb_define_singleton_method(rb_cUCalendar, "dst_savings", icu4r_cal_dst_savings, 1);
555
+
556
+ rb_define_singleton_method(rb_cUCalendar, "new", icu4r_cal_init, -1);
557
+ rb_define_method(rb_cUCalendar, "add", icu4r_cal_add, 2);
558
+ rb_define_method(rb_cUCalendar, "roll", icu4r_cal_roll, 2);
559
+ rb_define_method(rb_cUCalendar, "[]", icu4r_cal_aref, 1);
560
+ rb_define_method(rb_cUCalendar, "[]=", icu4r_cal_aset, 2);
561
+ rb_define_method(rb_cUCalendar, "millis=", icu4r_cal_set_millis, 1);
562
+ rb_define_method(rb_cUCalendar, "millis", icu4r_cal_millis,0);
563
+ rb_define_method(rb_cUCalendar, "set_date", icu4r_cal_set_date,3);
564
+ rb_define_method(rb_cUCalendar, "set_date_time", icu4r_cal_set_date_time,6);
565
+ rb_define_method(rb_cUCalendar, "time_zone=", icu4r_cal_set_tz,1);
566
+ rb_define_method(rb_cUCalendar, "time_zone", icu4r_cal_get_tz,-1);
567
+ rb_define_method(rb_cUCalendar, "in_daylight_time?", icu4r_cal_in_daylight,0);
568
+ rb_define_method(rb_cUCalendar, "format", icu4r_cal_format,-1);
569
+
570
+ rb_define_method(rb_cUCalendar, "clone", icu4r_cal_clone,0);
571
+ rb_define_method(rb_cUCalendar, "eql?", icu4r_cal_equal,1);
572
+ rb_define_method(rb_cUCalendar, "<", icu4r_cal_before,1);
573
+ rb_define_method(rb_cUCalendar, ">", icu4r_cal_after,1);
574
+ rb_define_method(rb_cUCalendar, "==", icu4r_cal_time_equals, 1);
575
+
576
+ }
data/docs/FORMATTING ADDED
@@ -0,0 +1,131 @@
1
+ === Locale-sensitive Message Formatting
2
+
3
+ Basic pattern rules are:
4
+
5
+ messageFormatPattern := string ( "{" messageFormatElement "}" string )*
6
+
7
+ messageFormatElement := argument { "," elementFormat }
8
+
9
+ elementFormat := "time" { "," datetimeStyle }
10
+ | "date" { "," datetimeStyle }
11
+ | "number" { "," numberStyle }
12
+ | "spellout"
13
+ | "ordinal"
14
+ | "duration"
15
+ | "choice" "," choiceStyle
16
+
17
+ datetimeStyle := "short"
18
+ | "medium"
19
+ | "long"
20
+ | "full"
21
+ | dateFormatPattern
22
+
23
+ numberStyle := "currency"
24
+ | "percent"
25
+ | "integer"
26
+ | numberFormatPattern
27
+
28
+ choiceStyle := choiceFormatPattern
29
+
30
+ === numberFormatPattern
31
+
32
+ pattern := subpattern{;subpattern}
33
+ subpattern := {prefix}integer{.fraction}{suffix}
34
+
35
+ prefix := '\\u0000'..'\\uFFFD' - specialCharacters
36
+ suffix := '\\u0000'..'\\uFFFD' - specialCharacters
37
+ integer := '#'* '0'* '0'
38
+ fraction := '0'* '#'*
39
+
40
+ Notation:
41
+ X* 0 or more instances of X
42
+ (X | Y) either X or Y.
43
+ X..Y any character from X up to Y, inclusive.
44
+ S - T characters in S, except those in T
45
+
46
+ The first subpattern is for positive numbers. The second (optional)
47
+ subpattern is used for negative numbers. (In both cases, ',' can
48
+ occur inside the integer portion--it is just too messy to indicate
49
+ in BNF.) For the second subpattern, only the PREFIX and SUFFIX are
50
+ noted; other attributes are taken only from the first subpattern.
51
+
52
+ Here are the special characters used in the parts of the
53
+ subpattern, with notes on their usage.
54
+
55
+ Symbol Meaning
56
+ 0 a digit, showing up a zero if it is zero
57
+ # a digit, supressed if zero
58
+ . placeholder for decimal separator
59
+ , placeholder for grouping separator.
60
+ E separates mantissa and exponent for exponential formats.
61
+ ; separates formats.
62
+ - default negative prefix.
63
+ % multiply by 100 and show as percentage
64
+ \u2030 multiply by 1000 and show as per mille
65
+ \u00A4 currency sign; replaced by currency symbol; if doubled, replaced by international currency symbol.
66
+ If present in a pattern, the monetary decimal separator
67
+ is used instead of the decimal separator.
68
+ X any other characters can be used in the prefix or suffix
69
+ ' used to quote special characters in a prefix or suffix.
70
+
71
+ === dateFormatPattern
72
+
73
+ Symbol Meaning Presentation Example
74
+ ------ ------- ------------ -------
75
+ G era designator (Text) AD
76
+ y year (Number) 1996
77
+ Y year/week of year (Number) 1996
78
+ M month in year (Text & Number) July & 07
79
+ d day in month (Number) 10
80
+ h hour in am/pm (1~12) (Number) 12
81
+ H hour in day (0~23) (Number) 0
82
+ m minute in hour (Number) 30
83
+ s second in minute (Number) 55
84
+ S millisecond (Number) 978
85
+ E day of week (Text) Tuesday
86
+ e day of week/local (1~7) (Number) 2
87
+ D day of year (Number) 189
88
+ F day of week in month (Number) 2 (2nd Wed in July)
89
+ w week in year (Number) 27
90
+ W week in month (Number) 2
91
+ a am/pm marker (Text) PM
92
+ k hour in day (1~24) (Number) 24
93
+ K hour in am/pm (0~11) (Number) 0
94
+ z time zone (Text) Pacific Standard Time
95
+ ' escape for text
96
+ '' single quote '
97
+
98
+
99
+ === choiceFormatPattern
100
+ In most cases, the preferred way to define a ChoiceFormat is with a pattern. Here is an example of a ChoiceFormat pattern:
101
+
102
+ 0≤are no files|1≤is one file|1<are many files
103
+
104
+ or equivalently,
105
+
106
+ 0#are no files|1#is one file|1<are many files
107
+
108
+ The pattern consists of a number or range specifiers separated by vertical bars '|' (U+007C). There is no vertical bar after the last range. Each range specifier is of the form:
109
+
110
+ Number is a floating point number that can be parsed by a default
111
+ NumberFormat for the US locale. It gives the lower limit of this range.
112
+ The lower limit is either inclusive or exclusive, depending on the separator.
113
+ The upper limit is given by the lower limit of the next range. The Unicode infinity
114
+ sign ∞ (U+221E) is recognized for positive infinity. It may be preceded by '-' (U+002D)
115
+ to indicate negative infinity.
116
+
117
+ String is the format string for this range, with special characters enclosed in single
118
+ quotes ('The # sign'). Single quotes themselves are indicated by two single quotes in a
119
+ row ('o''clock').
120
+
121
+ Separator is one of the following single characters:
122
+ * '≤' (U+2264) or '#' (U+0023) indicates that the lower limit given by
123
+ Number is inclusive. (The two characters are equivalent to ChoiceFormat.)
124
+ This means that the limit value Number belongs to this range. Another way of
125
+ saying this is that the corresponding closure is FALSE.
126
+
127
+ * '<' (U+003C) indicates that the lower limit given by Number is exclusive.
128
+ This means that the value Number belongs to the prior range. Another way of saying
129
+ this is that the corresponding closure is TRUE.
130
+
131
+ See ICU docs for more info and examples.