when_exe 0.4.0 → 0.4.1

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.
@@ -390,8 +390,8 @@ module When
390
390
  ],
391
391
  [self,
392
392
  "period:[前燕]",
393
- ["[燕元=]0.11.26", "@F" , "name=[慕容儁];348-11-26^Chinese0239"], # 景昭帝 甲辰 3085-6
394
- ["[元璽]1" , "" , " 352-11-13"], # 戊辰 3131-27
393
+ # ["[燕元=]0.11.26", "@F" , "name=[慕容儁];348-11-26^Chinese0239"], # 景昭帝 甲辰 3085-6 (即位記事のみ)
394
+ ["[元璽]1" , "" , "name=[慕容儁];352-11-13^Chinese0239"], # 戊辰 3131-27
395
395
  ["[光寿]1" , "" , " 357-02-23"], # 癸丑 3161-3
396
396
  ["[建熙]1" , "@A" , "name=[慕容暐];360-01-15", "370-11="] # 幽帝 戊子 3179-1
397
397
  ],
@@ -578,8 +578,9 @@ module When
578
578
  ["[河清]1" , "" , " 562-04-06"], # 乙巳
579
579
  ["[天統=ja:%%<天統_(北斉)>]1" , "@A" ,"name=[後主=ja:%%<後主_(北斉)>];565-04-24"], # 丙子
580
580
  ["[武平=ja:%%<武平_(北斉)>]1" , "" , " 570-01-01"], # 乙酉
581
- ["[隆化]1" , "" , " 576-12-14"], # 戊午
582
- ["[承光=ja:%%<承光_(北斉)>]1" ,"@A", "name=[幼主=ja:%%<幼主_(北斉)>];577-01-01", "577-02="] # 乙亥
581
+ ["[隆化]1" , "" , " 576-12-13", "577-01-01"], # 丁巳 5361
582
+ ["[徳昌=ja:%%<徳昌_(北斉)>]1" , "" ,"name=[安徳王=ja:%%<高延宗>];576-12-14", "576-12-17="], # 戊午, 辛酉 5362
583
+ ["[承光=ja:%%<承光_(北斉)>]1" ,"@A", "name=[幼主=ja:%%<幼主_(北斉)>];577-01-01", "577-03="] # 乙亥
583
584
  ],
584
585
  [self,
585
586
  "period:[西魏]",
@@ -591,7 +592,7 @@ module When
591
592
  "period:[北周]",
592
593
  ["[<孝閔帝>=ja:%%<孝閔帝>]1.12.30", "@F" , "name=[孝閔帝];556-12-30^Chinese0523"], # 庚子 北周が西魏に代わる
593
594
  ["[<明帝>=ja:%%<明帝_(北周)>]1.09.28","@A" ,"name=[明帝=ja:%%<明帝_(北周)>];557-09-28"], # 甲子
594
- ["[武成=ja:%%<武成_(北周)>]1" , "" , " 559-09-21"], # 乙亥
595
+ ["[武成=ja:%%<武成_(北周)>]1" , "" , " 559-08-14"], # 乙亥 or 己亥 5190-30
595
596
  ["[保定=ja:%%<保定_(北周)>]1" , "@A" ,"name=[武帝=ja:%%<武帝_(北周)>];561-01-01"], # 戊申
596
597
  ["[天和=ja:%%<天和_(北周)>]1" , "" , " 566-01-05"], # 癸未 本年から天和暦を使用
597
598
  ["[建徳=ja:%%<建徳_(北周)>]1" , "" , " 572-03-15"], # 丁巳
@@ -1,829 +1,831 @@
1
- # -*- coding: utf-8 -*-
2
- =begin
3
- Copyright (C) 2011-2014 Takashi SUGA
4
-
5
- You may use and/or modify this file according to the license described in the LICENSE.txt file included in this archive.
6
- =end
7
-
8
- module When
9
-
10
- class BasicTypes::M17n
11
-
12
- Christian = [self, [
13
- "locale:[=en:, ja=ja:, alias]",
14
- "names:[Christian=]",
15
- "[Julian=en:Julian_calendar, ユリウス暦 ]",
16
- "[Gregorian=en:Gregorian_calendar, グレゴリオ暦 ]",
17
- "[RevisedJulian=en:Revised_Julian_calendar, 修正ユリウス暦]",
18
- "[Swedish=en:Swedish_calendar, スウェーデン暦]",
19
- "[Civil in the West=en:Civil_calendar, 西暦, *alias:Civil]"
20
- ]]
21
- end
22
-
23
- class TM::CalendarEra
24
- # Anno Mundi Era
25
- Byzantine = [self, [
26
- "locale:[=en:, ja=ja:, alias]",
27
- "period:[Byzantine=en:Byzantine_calendar, ビザンティン暦=ja:%%<世界創造紀元>]",
28
- ["[AM=en:Anno_Mundi, 世界創造紀元, alias:Anno_Mundi]6497*9.1",
29
- '@CE', "989*09-01^Julian?border=0*9-1&note=Roman", "1453-5-29"]
30
- ]]
31
- end
32
-
33
- module CalendarTypes
34
-
35
- #
36
- # Christian Base Calendar
37
- #
38
- class Christian < When::TM::Calendar
39
-
40
- # デフォルトの改暦日付(ユリウス通日)
41
- #
42
- # @private
43
- DefaultReformDate = 2299161 # 1582-10-15
44
-
45
- # @private
46
- #
47
- # ::Date オブジェクトに対応する暦法名
48
- # (require 'Date' されていることの保証は呼び出し側)
49
- #
50
- def self._default_start(date)
51
- case date.start
52
- when ::Date::JULIAN ; 'Julian'
53
- when ::Date::GREGORIAN ; 'Gregorian'
54
- else ; "Civil?reform_jdn=#{date.start}"
55
- end
56
- end
57
-
58
- # 年月日 -> 通日
59
- #
60
- # @see When::CalendarTypes::TableBased#_coordinates_to_number
61
- #
62
- def _coordinates_to_number(y,m,d)
63
- m = (+m + 10) % 12
64
- y = +y + 4716 - m / 10
65
- a = (1461*y.to_i ).div(4)
66
- b = ( 153*m.to_i + 2).div(5)
67
- return a + b + (+d) - 1401
68
- end
69
-
70
- # 通日 - > 年月日
71
- #
72
- # @see When::CalendarTypes::TableBased#_number_to_coordinates
73
- #
74
- def _number_to_coordinates(jdn)
75
- j = jdn.to_i + 1401
76
- y, t = (4*j + 3).divmod(1461)
77
- t = t.div(4)
78
- m, d = (5*t + 2).divmod(153)
79
- d = d.div(5)
80
- m = (m+2) % 12
81
- y = y - 4716 + (13-m) / 12
82
- return [y,m,d]
83
- end
84
-
85
- # 暦要素数
86
- #
87
- # @see When::CalendarTypes::TableBased#_length
88
- #
89
- def _length(date)
90
- yy, mm = date
91
- return super unless(mm)
92
- return ((yy % 4) == 0) ? 29 : 28 if (mm == 1)
93
- return (((((mm + 10) % 12) % 5) % 2) == 0) ? 31 : 30
94
- end
95
-
96
- # 復活祭の遅延日数
97
- #
98
- # @private
99
- def _easter_delay(year)
100
- 0
101
- end
102
-
103
- private
104
-
105
- def _normalize(args=[], options={})
106
- raise TypeError, "#{self.class} is abstract class" unless @label
107
- @note = When.CalendarNote(@note || 'Christian')
108
- @diff_to_CE ||= 0
109
- super
110
- end
111
- end
112
-
113
- #
114
- # Julian Calendar
115
- #
116
- class Julian < Christian
117
-
118
- # 太陰方程式
119
- #
120
- # @param [Numeric] year 西暦の年数
121
- # @return [Integer] 0 (ユリウス暦では補正なし)
122
- #
123
- def _lunar_equation(year)
124
- 0
125
- end
126
-
127
- # @private
128
- #
129
- # 対応する ::Date の start 属性
130
- def _default_start
131
- ::Date::JULIAN
132
- end
133
-
134
- private
135
-
136
- def _normalize(args=[], options={})
137
- @label ||= 'Christian::Julian'
138
- super
139
- end
140
- end
141
-
142
- #
143
- # Swedish Calendar
144
- #
145
- class Swedish < Julian
146
-
147
- # デフォルトの改暦日付(ユリウス通日)
148
- #
149
- # @private
150
- DefaultReformDate = 2361390 # 1753-03-01
151
-
152
- # @private
153
- # Julian - 17000229 17120229
154
- SwedishCalendarRange = 2342042...2346425
155
-
156
- # @private
157
- ExtraDate = [1712,1,29]
158
-
159
- # @private
160
- Length = {
161
- [1700, nil] => 365,
162
- [1700, 1] => 28,
163
- [1712, nil] => 367,
164
- [1712, 1] => 30
165
- }
166
-
167
- # Ref: http://www.ortelius.de/kalender/east_en.php
168
- # @private
169
- EasterDelay = {
170
- 1741 => -7,
171
- 1742 => -35,
172
- 1744 => -7,
173
- 1745 => -7,
174
- 1747 => -28,
175
- 1748 => -7,
176
- 1750 => -28,
177
- 1751 => -7,
178
- 1752 => -7,
179
- 1802 => +7,
180
- 1805 => +7,
181
- 1818 => +7
182
- }
183
-
184
- # 年月日 -> 通日
185
- #
186
- # @see When::CalendarTypes::TableBased#_coordinates_to_number
187
- #
188
- def _coordinates_to_number(y,m,d)
189
- jdn = super
190
- return SwedishCalendarRange.last if [+y, m, d] == ExtraDate
191
- SwedishCalendarRange.include?(jdn-1) ? jdn-1 : jdn
192
- end
193
-
194
- # 通日 - > 年月日
195
- #
196
- # @see When::CalendarTypes::TableBased#_number_to_coordinates
197
- #
198
- def _number_to_coordinates(jdn)
199
- return ExtraDate.dup if jdn == SwedishCalendarRange.last
200
- super(SwedishCalendarRange.include?(jdn) ? jdn+1 : jdn)
201
- end
202
-
203
- # 暦要素数
204
- #
205
- # @see When::CalendarTypes::TableBased#_length
206
- #
207
- def _length(date)
208
- y, m = date
209
- Length[[+y,m]] || super
210
- end
211
-
212
- # 復活祭の遅延日数
213
- #
214
- # @private
215
- def _easter_delay(year)
216
- EasterDelay[year] || 0
217
- end
218
-
219
- private
220
-
221
- def _normalize(args=[], options={})
222
- @label ||= 'Christian::Swedish'
223
- super
224
- end
225
- end
226
-
227
- #
228
- # Variation of Christian Calendar
229
- #
230
- class ReformVariation < Christian
231
-
232
- # 年月日 -> 通日
233
- #
234
- # @see When::CalendarTypes::TableBased#_coordinates_to_number
235
- #
236
- def _coordinates_to_number(y,m,d)
237
- super - _diff_from_century(((m < 2) ? +y-1 : +y).to_i.div(100))
238
- end
239
-
240
- # 通日 - > 年月日
241
- #
242
- # @see When::CalendarTypes::TableBased#_number_to_coordinates
243
- #
244
- def _number_to_coordinates(jdn)
245
- super(jdn + _diff_from_century(_century_from_jdn(jdn)))
246
- end
247
-
248
- # 暦要素数
249
- #
250
- # @see When::CalendarTypes::TableBased#_length
251
- #
252
- def _length(date)
253
- yy, mm = date
254
- return super unless mm == 1 # 2月でなければユリウス暦と同じ
255
- cc, yy = yy.divmod(100)
256
- return super unless yy == 0 # 100で割り切れない年はユリウス暦と同じ
257
- 29 - (_diff_from_century(cc) - _diff_from_century(cc-1))
258
- end
259
-
260
- # 太陰方程式
261
- #
262
- # @param [Numeric] year 西暦の年数
263
- # @return [Integer] 19年7閏のペースに対する満月の日付の補正量
264
- # @note 太陽暦日の補正も、本メソッドで行う
265
- #
266
- def _lunar_equation(year)
267
- h = +year.div(100)
268
- (8*(h+11)).div(25) - (_diff_from_century(h) + 5)
269
- end
270
- end
271
-
272
- #
273
- # Gregorian Calendar
274
- #
275
- class Gregorian < ReformVariation
276
-
277
- # 百年代 - > ユリウス暦とグレゴリオ暦の差
278
- #
279
- # @param [Integer] century 百年代
280
- #
281
- # @return [Integer] ユリウス暦とグレゴリオ暦の差
282
- #
283
- def _diff_from_century(century)
284
- (3*(century-3)).div(4)+1
285
- end
286
-
287
- # 通日 - > 百年代
288
- #
289
- # @param [Integer] jdn 通日
290
- #
291
- # @return [Integer] 百年代
292
- #
293
- def _century_from_jdn(jdn)
294
- (4 * jdn - 6884477).div(146097)
295
- end
296
-
297
- private
298
-
299
- def _normalize(args=[], options={})
300
- @label ||= 'Christian::Gregorian'
301
- super
302
- end
303
- end
304
-
305
- #
306
- # Revised Julian Calendar
307
- #
308
- class RevisedJulian < ReformVariation
309
-
310
- # デフォルトの改暦日付(ユリウス通日)
311
- #
312
- # @private
313
- DefaultReformDate = 2423707 # 1923-10-14
314
-
315
- # 百年代 - > ユリウス暦と修正ユリウス暦の差
316
- #
317
- # @param [Integer] century 百年代
318
- #
319
- # @return [Integer] ユリウス暦と修正ユリウス暦の差
320
- #
321
- def _diff_from_century(century)
322
- (7*(century-1)).div(9)-1
323
- end
324
-
325
- # 通日 - > 百年代
326
- #
327
- # @param [Integer] jdn 通日
328
- #
329
- # @return [Integer] 百年代
330
- #
331
- def _century_from_jdn(jdn)
332
- (9 * jdn - 15490078).div(328718)
333
- end
334
-
335
- private
336
-
337
- def _normalize(args=[], options={})
338
- @label ||= 'Christian::RevisedJulian'
339
- # @diff ||= [-2, -1, -1, 0, 1, 2, 2, 3, 4, 5] # 1~10世紀の各世紀のユリウス暦と差の日数
340
- super
341
- end
342
- end
343
-
344
- #
345
- # Civil Calendar
346
- #
347
- class Civil < Gregorian
348
-
349
- #
350
- # 改暦日付
351
- #
352
- # @return [Integer]
353
- #
354
- attr_reader :reform_jdn
355
-
356
- # @private
357
- #
358
- # 対応する ::Date の start 属性
359
- alias :_default_start :reform_jdn
360
-
361
- #
362
- # 年初の最初の定義の年
363
- #
364
- # @return [Integer] 年初の最初の定義の年
365
- # @return nil
366
- #
367
- def first_year_of_border
368
- return nil unless @border.kind_of?(When::Coordinates::MultiBorder)
369
- year = @border.borders[-1][:key]
370
- year.kind_of?(Integer) ? year : nil
371
- end
372
-
373
- # 年月日 -> 通日
374
- #
375
- # @see When::CalendarTypes::TableBased#_coordinates_to_number
376
- #
377
- def _coordinates_to_number(y,m,d)
378
- skip, limit = @the_length[[y,m]]
379
- d += skip if skip && d >= limit
380
- jdn = @new._coordinates_to_number(y,m,d)
381
- jdn >= @reform_jdn ? jdn : @old._coordinates_to_number(y + @origin_of_MSC - @old.origin_of_MSC, m, d)
382
- end
383
-
384
- # 通日 - > 年月日
385
- #
386
- # @see When::CalendarTypes::TableBased#_number_to_coordinates
387
- #
388
- def _number_to_coordinates(jdn)
389
- if jdn >= @reform_jdn
390
- date = @new._number_to_coordinates(jdn)
391
- else
392
- date = @old._number_to_coordinates(jdn)
393
- date[0] -= @origin_of_MSC - @old.origin_of_MSC
394
- end
395
- skip, limit = @the_length[date[0..-2]]
396
- date[2] -= skip if skip && date[2] >= limit
397
- date
398
- end
399
-
400
- # 暦要素数
401
- #
402
- # @see When::CalendarTypes::TableBased#_length
403
- #
404
- def _length(date)
405
- return @the_length[date][2] if @the_length[date]
406
- yy, mm = date
407
- (yy > @reform_date[0]) ||
408
- (yy == @reform_date[0] && (!mm || mm >= @reform_date[1])) ?
409
- @new._length(date) :
410
- @old._length([yy + @origin_of_MSC - @old.origin_of_MSC, mm])
411
- end
412
-
413
- # 太陰方程式
414
- #
415
- # @param [Numeric] year 西暦の年数
416
- # @return [Integer] 19年7閏のペースに対する満月の日付の補正量
417
- # @note 太陽暦日の補正も、本メソッドで行う
418
- #
419
- def _lunar_equation(year)
420
- year >= @the_easter ? @new._lunar_equation(year) : @old._lunar_equation(year)
421
- end
422
-
423
- # 復活祭の遅延日数
424
- #
425
- # @private
426
- def _easter_delay(year)
427
- @old._easter_delay(year)
428
- end
429
-
430
- private
431
-
432
- # オブジェクトの正規化
433
- #
434
- # @old = 改暦前の暦法(デフォルトはユリウス暦)
435
- # @new = 改暦後の暦法(デフォルトはグレゴリオ暦)
436
- # @reform_date = 改暦日付(月日は 1 オリジンで指定し、0 オリジンに直して保持)
437
- # @reform_jdn = 改暦日付のユリウス通日
438
- # @reform = reform_date reform_jdn を内容で判別し、どちらかに反映する
439
- # @the_easter = 新暦法の復活祭計算の適用を始める年
440
- # @the_length = 通常と異なる日付となる年月の情報({[年,月]=>[スキップした日数, スキップし始める日, 月の日数]})
441
- #
442
- def _normalize(args=[], options={})
443
- @label ||= 'Christian::Civil'
444
-
445
- # 前後の暦法
446
- @old = When.Calendar(@old || 'Julian')
447
- @new = When.Calendar(@new || 'Gregorian')
448
- @indices ||= @old.indices
449
-
450
- # 改暦日付 (0 オリジン)
451
- @reform = When::Coordinates::Pair._en_pair_date_time(@reform) if @reform.kind_of?(String)
452
- case @reform.length
453
- when 0 ;
454
- when 1 ; @reform_jdn = @reform[0]
455
- else ; @reform_date = @reform
456
- end if @reform.kind_of?(Array)
457
-
458
- if @reform_date
459
- @reform_date = When::Coordinates::Pair._en_pair_date_time(@reform_date) if @reform_date.kind_of?(String)
460
- @reform_date = @reform_date.map {|c| c.to_i}
461
- (1..2).each {|i| @reform_date[i] = @reform_date[i] ? @reform_date[i] - 1 : 0 }
462
- @reform_jdn = @new._coordinates_to_number(*@reform_date)
463
- else
464
- @reform_jdn ||= [@old.class::DefaultReformDate, @new.class::DefaultReformDate].max
465
- @reform_jdn = @reform_jdn.to_i
466
- @reform_date = @new._number_to_coordinates(@reform_jdn)
467
- end
468
- last_date = @old._number_to_coordinates(@reform_jdn-1)
469
-
470
- # 復活祭との前後関係
471
- @the_easter = @reform_jdn > When.CalendarNote('Christian').easter(@reform_date[0], @new) ? @reform_date[0]+1 : @reform_date[0]
472
-
473
- # 月の日数
474
- this_month = @reform_date[0..1]
475
- new_length = @new._length(this_month)
476
- @the_length = {}
477
- if @reform_date[1] == last_date[1] # 同一月内に閉じた改暦
478
- skipped_length = @reform_date[2] - last_date[2] - 1
479
- @the_length[this_month] = [skipped_length, last_date[2]+1, new_length-skipped_length]
480
- else
481
- last_month = [(@reform_date[1] > last_date[1] ? @reform_date[0] : @reform_date[0]-1), last_date[1]]
482
- @the_length[this_month] = [@reform_date[2], 0, new_length - @reform_date[2]]
483
- @the_length[last_month] = [false, false, last_date[2]+1]
484
- end
485
-
486
- super
487
- end
488
-
489
- #
490
- # 整数のindex化
491
- #
492
- def _to_index(date)
493
- digit = date[-1] - @base[date.length-1]
494
- skip, limit = @the_length[date[0..-2]]
495
- skip && digit >= limit ? digit-skip : digit
496
- end
497
-
498
- #
499
- # indexの整数化
500
- #
501
- def _from_index(date)
502
- digit = date[-1]
503
- skip, limit = @the_length[date[0..-2]]
504
- (skip && digit >= limit ? digit+skip : digit)+@base[date.length-1]
505
- end
506
- end
507
- end
508
-
509
- module Coordinates
510
-
511
- #
512
- # 日時要素の境界 - 復活祭
513
- #
514
- class Easter < Border
515
-
516
- # 境界の取得
517
- #
518
- # @param [Array<Numeric>] date 境界を計算する年
519
- # @param [When::TM::ReferenceSystem] frame 使用する暦法
520
- #
521
- # @return [Array<Numeric>] その年の境界
522
- #
523
- def border(date=[], frame=When::Gregorian)
524
- frame._encode(frame._number_to_coordinates(frame.note.easter(date[0], frame)), false)
525
- end
526
-
527
- private
528
-
529
- # 要素の正規化
530
- def _normalize(args=[], options={})
531
- @border = [0,0,0]
532
- end
533
- end
534
- end
535
-
536
- #
537
- # キリスト教の暦注(クリスマスと復活祭)
538
- #
539
- class CalendarNote::Christian < CalendarNote
540
-
541
- Notes = [When::BasicTypes::M17n, [
542
- "locale:[=en:, ja=ja:, alias]",
543
- "names:[Christian]",
544
-
545
- # 年の暦注 ----------------------------
546
- [When::BasicTypes::M17n,
547
- "names:[year]"
548
- ],
549
-
550
- # 月の暦注 ----------------------------
551
- [When::BasicTypes::M17n,
552
- "names:[month]",
553
- [When::BasicTypes::M17n,
554
- "names:[Month]"
555
- ]
556
- ],
557
-
558
- # 日の暦注 ----------------------------
559
- [When::BasicTypes::M17n,
560
- "names:[day]",
561
- [When::BasicTypes::M17n, "names:[Week, 七曜]" ],
562
- [When::BasicTypes::M17n, "names:[Easter, 復活祭]" ],
563
- [When::BasicTypes::M17n, "names:[Christmas, クリスマス]"],
564
- [When::BasicTypes::M17n, "names:[Fixed_feast=, 固定祝日=]" ],
565
- [When::BasicTypes::M17n, "names:[Moveable_feast, 移動祝日]" ]
566
- ]
567
- ]]
568
-
569
- # 固定祝日
570
- Fixed_feasts = {
571
- [ 1, 6] => "Epiphany",
572
- [ 3, 1] => "St.David's Day",
573
- [ 3, 17] => "St.Patrick's Day",
574
- [ 3, 25] => "Annunciation-Lady Day",
575
- [ 4, 23] => "St.George's Day",
576
- [ 6, 24] => "Midsummer Day",
577
- [ 9, 14] => "Holy Cross Day",
578
- [ 9, 29] => "Michaelmas Day",
579
- [11, 30] => "St.Andrew's Day",
580
- [12, 13] => "St.Lucia's Day",
581
- [12, 21] => "St.Thomas's Day",
582
- # [12, 25] => "Christmas Day"
583
- }
584
-
585
- # 移動祝日 (日付と曜日による)
586
- moveable_feasts = {}
587
- [[[ 9, 15, 2], "III Quatember"],
588
- [[11, 27, 6], "Advent Sunday"],
589
- [[12, 14, 2], "IV Quatember" ]].each do |pair|
590
- date, name = pair
591
- 7.times do
592
- moveable_feasts[date.dup] = name
593
- date[1] += 1
594
- if date[1] > 30
595
- date[0] += 1
596
- date[1] = 1
597
- end
598
- end
599
- end
600
-
601
- # 移動祝日
602
- Moveable_feasts = {
603
- # 復活祭からの日数による
604
- -63 => "Septuagesima Sunday",
605
- -56 => "Sexagesima Sunday",
606
- -49 => "Quinquagesima Sunday",
607
- -46 => "Ash Wednesday",
608
- -42 => "Quadragesima Sunday",
609
- -40 => "I Quatember",
610
- -35 => "Reminizer Sunday",
611
- -28 => "Oculi Sunday",
612
- -21 => "Laetare Sunday",
613
- -14 => "Judica Sunday",
614
- -7 => "Palmarum",
615
- -2 => "Good Friday",
616
- # 0 => "Easter Day",
617
- 7 => "Low Sunday",
618
- 35 => "Rogation Sunday",
619
- 39 => "Ascension Day",
620
- 49 => "Whitsunday",
621
- 53 => "II Quatember",
622
- 56 => "Trinity Sunday",
623
- 60 => "Corpus Christi",
624
- }.update(moveable_feasts)
625
-
626
- #
627
- # 暦法によってイベントの動作を変えるか否か
628
- #
629
- CalendarDepend = true
630
-
631
- # 週日補正フラグ
632
- # @return [Integer]
633
- attr_reader :w
634
-
635
- # 最も遅い満月の3月0日からの日数
636
- # @return [Integer]
637
- attr_reader :d
638
-
639
- # クリスマスの3月0日からの日数
640
- # @return [Integer]
641
- attr_reader :x
642
-
643
- # 平年数
644
- # @return [Integer]
645
- attr_reader :n
646
-
647
- # 置閏周期
648
- # @return [Integer]
649
- attr_reader :s
650
-
651
- # 月の位相の補正
652
- # @return [Integer]
653
- attr_reader :c
654
-
655
- # ガード
656
- # @return [Integer]
657
- attr_reader :g
658
-
659
- # ベース
660
- # @return [Integer]
661
- attr_reader :b
662
-
663
- # 満月補正フラグ
664
- # @return [Integer]
665
- attr_reader :f
666
-
667
- # 七曜
668
- #
669
- # @param [When::TM::TemporalPosition] date
670
- # @param [When::TM::CalDate] base (not used)
671
- #
672
- # @return [When::Coordinates::Residue] 七曜
673
- #
674
- def week(date, base=nil)
675
- When.Residue('Week')[date.to_i % 7]
676
- end
677
-
678
- # クリスマス
679
- #
680
- # @param [Numeric] date 西暦の年数
681
- # @param [When::TM::TemporalPosition] date
682
- # @param [When::TM::ReferenceSystem] frame 使用する暦法(デフォルトは When::Gregorian)
683
- #
684
- # @return [Integer] クリスマスのユリウス通日(dateが西暦の年数の場合)
685
- # @return [When::TM::CalDate] クリスマスのWhen::TM::CalDate(yearがWhen::TM::TemporalPositionの場合)
686
- #
687
- def christmas(date, frame=nil)
688
- _event(date, 'christmas', frame) do |year, frame|
689
- @x - 1 + frame._coordinates_to_number(year, 2, 0)
690
- end
691
- end
692
-
693
- # 復活祭
694
- #
695
- # @param [Numeric] date 西暦の年数
696
- # @param [When::TM::TemporalPosition] date
697
- # @param [When::TM::ReferenceSystem] frame 使用する暦法(デフォルトは When::Gregorian)
698
- #
699
- # @return [Integer] 復活祭のユリウス通日(dateが西暦の年数の場合)
700
- # @return [When::TM::CalDate] 復活祭のWhen::TM::CalDate(yearがWhen::TM::TemporalPositionの場合)
701
- #
702
- def easter(date, frame=nil)
703
- _event(date, 'easter', frame) do |year, frame|
704
- golden = (year+@b) % @s + 1
705
- m = (frame._lunar_equation(year) + 11*golden + @c) % 30
706
- if @f == 0
707
- m += 1 if m==0 || m==1 && golden>=@n
708
- else
709
- m += (golden-1) / @f
710
- m -= 30 if m>=@n
711
- end
712
- result = frame._coordinates_to_number(year, 2, 0) + @d - 1 - m
713
- result += @g - (result-@w) % 7 if @w<7
714
- result + frame._easter_delay(year)
715
- end
716
- end
717
-
718
- # イベントの標準的な間隔を返す
719
- # @private
720
- def _delta(parameter=nil)
721
- return When::P1Y
722
- end
723
-
724
- # @private
725
- alias :christmas_delta :_delta
726
-
727
- # @private
728
- alias :easter_delta :_delta
729
-
730
- # 固定祝日
731
- #
732
- # @param [When::TM::TemporalPosition] date
733
- # @param [When::TM::ReferenceSystem] frame 使用する暦法(デフォルトは When::Gregorian)
734
- #
735
- # @return [String] 祝日の名称
736
- # @return [nil] 祝日に該当しない
737
- #
738
- def fixed_feast(date, frame=nil)
739
- date = When.Calendar(frame||'Gregorian') ^ date unless date.frame.kind_of?(When::CalendarTypes::Christian)
740
- Fixed_feasts[date.cal_date[-2..-1]]
741
- end
742
-
743
- # 移動祝日
744
- #
745
- # @param [When::TM::TemporalPosition] date
746
- # @param [When::TM::ReferenceSystem] frame 使用する暦法(デフォルトは When::Gregorian)
747
- #
748
- # @return [String] 祝日の名称
749
- # @return [nil] 祝日に該当しない
750
- #
751
- def moveable_feast(date, frame=nil)
752
- result = Moveable_feasts[date.to_i - easter(date, frame).to_i]
753
- return result if result
754
- date = When.Calendar(frame||'Gregorian') ^ date unless date.frame.kind_of?(When::CalendarTypes::Christian)
755
- Moveable_feasts[date.cal_date[-2..-1] + [date.to_i % 7]]
756
- end
757
-
758
- private
759
-
760
- # オブジェクトの正規化
761
- # w - 週日補正フラグ(デフォルト 6)
762
- # d - 最も遅い満月 (デフォルト 3月0日から 50日)
763
- # x - クリスマス (デフォルト 3月0日から300日)
764
- # n - 平年数 (デフォルト 12)
765
- # s - 置閏周期 (デフォルト 19)
766
- # c - 月の位相の補正(デフォルト 3)
767
- # g - ガード (デフォルト 7)
768
- # b - ベース (デフォルト 0)
769
- # f - 満月補正フラグ(デフォルト 0)
770
- def _normalize(args=[], options={})
771
- w, d, x, n, s, c, g, b, f = args
772
- @w = (w || @w || 6).to_i
773
- @d = (d || @d || 50).to_i
774
- @x = (x || @x || 300).to_i
775
- @n = (n || @n || 12).to_i
776
- @s = (s || @s || 19).to_i
777
- @c = (c || @c || 3).to_i
778
- @g = (g || @g || 7).to_i
779
- @b = (b || @b || 0).to_i
780
- @f = (f || @f || 0).to_i
781
- @event = 'easter'
782
- @prime ||= [['Month'], ['Week']]
783
- super
784
- end
785
-
786
- #
787
- # 任意の暦をグレゴリオorユリウス暦日に変換
788
- #
789
- def _to_date_for_note(date)
790
- return When.Calendar(When::CalendarTypes::Christian._default_start(date)) ^ date if ::Object.const_defined?(:Date) &&
791
- ::Date.method_defined?(:+) && date.kind_of?(::Date)
792
- return When::Gregorian ^ date if date.kind_of?(::Time)
793
- return date if date.frame.kind_of?(When::CalendarTypes::Christian)
794
- When.Calendar(date.frame.iri =~ /Coptic/ || date.to_i < 2299161 ? 'Julian' : 'Gregorian') ^ date
795
- end
796
-
797
- # 当該年のイベントの日付
798
- # date : 西暦の年数 or When::TM::(Temporal)Position
799
- # event : イベント名 (String)
800
- # frame : 暦法(デフォルトは When:Gregorian)
801
- #
802
- # @return [Integer] イベントのユリウス通日(dateが西暦の年数の場合)
803
- # @return [When::TM::CalDate] イベントのWhen::TM::CalDate(yearがWhen::TM::(Temporal)Positionの場合)
804
- #
805
- def _event(date, event, frame=nil)
806
- case date
807
- when Numeric
808
- year = date * 1
809
- when When::TimeValue
810
- options = date._attr
811
- options[:precision] = When::DAY
812
- options[:events] = [event]
813
- if frame
814
- frame = When.Calendar(frame)
815
- date = frame.jul_trans(date, options)
816
- else
817
- frame = date.frame
818
- end
819
- year = date.most_significant_coordinate * 1
820
- else
821
- raise TypeError, "Irregal date type: #{date.class}"
822
- end
823
- frame ||= When::Gregorian
824
- result = yield(year, frame)
825
- return result if date.kind_of?(Numeric)
826
- return frame.jul_trans(result, options)
827
- end
828
- end
829
- end
1
+ # -*- coding: utf-8 -*-
2
+ =begin
3
+ Copyright (C) 2011-2015 Takashi SUGA
4
+
5
+ You may use and/or modify this file according to the license described in the LICENSE.txt file included in this archive.
6
+ =end
7
+
8
+ module When
9
+
10
+ class BasicTypes::M17n
11
+
12
+ Christian = [self, [
13
+ "locale:[=en:, ja=ja:, alias]",
14
+ "names:[Christian=]",
15
+ "[Julian=en:Julian_calendar, ユリウス暦 ]",
16
+ "[Gregorian=en:Gregorian_calendar, グレゴリオ暦 ]",
17
+ "[RevisedJulian=en:Revised_Julian_calendar, 修正ユリウス暦]",
18
+ "[Swedish=en:Swedish_calendar, スウェーデン暦]",
19
+ "[Civil in the West=en:Civil_calendar, 西暦, *alias:Civil]"
20
+ ]]
21
+ end
22
+
23
+ class TM::CalendarEra
24
+ # Anno Mundi Era
25
+ Byzantine = [self, [
26
+ "locale:[=en:, ja=ja:, alias]",
27
+ "period:[Byzantine=en:Byzantine_calendar, ビザンティン暦=ja:%%<世界創造紀元>]",
28
+ ["[AM=en:Anno_Mundi, 世界創造紀元, alias:Anno_Mundi]6497*9.1",
29
+ '@CE', "989*09-01^Julian?border=0*9-1&note=Roman", "1453-5-29"]
30
+ ]]
31
+ end
32
+
33
+ module CalendarTypes
34
+
35
+ #
36
+ # Christian Base Calendar
37
+ #
38
+ class Christian < When::TM::Calendar
39
+
40
+ # デフォルトの改暦日付(ユリウス通日)
41
+ #
42
+ # @private
43
+ DefaultReformDate = 2299161 # 1582-10-15
44
+
45
+ # @private
46
+ #
47
+ # ::Date オブジェクトに対応する暦法名
48
+ # (require 'Date' されていることの保証は呼び出し側)
49
+ #
50
+ def self._default_start(date)
51
+ case date.start
52
+ when ::Date::JULIAN ; return 'Julian'
53
+ when ::Date::GREGORIAN ; return 'Gregorian'
54
+ end
55
+ start = date.start
56
+ start = start.to_i if start == start.to_i
57
+ "Civil?reform_jdn=#{start}"
58
+ end
59
+
60
+ # 年月日 -> 通日
61
+ #
62
+ # @see When::CalendarTypes::TableBased#_coordinates_to_number
63
+ #
64
+ def _coordinates_to_number(y,m,d)
65
+ m = (+m + 10) % 12
66
+ y = +y + 4716 - m / 10
67
+ a = (1461*y.to_i ).div(4)
68
+ b = ( 153*m.to_i + 2).div(5)
69
+ return a + b + (+d) - 1401
70
+ end
71
+
72
+ # 通日 - > 年月日
73
+ #
74
+ # @see When::CalendarTypes::TableBased#_number_to_coordinates
75
+ #
76
+ def _number_to_coordinates(jdn)
77
+ j = jdn.to_i + 1401
78
+ y, t = (4*j + 3).divmod(1461)
79
+ t = t.div(4)
80
+ m, d = (5*t + 2).divmod(153)
81
+ d = d.div(5)
82
+ m = (m+2) % 12
83
+ y = y - 4716 + (13-m) / 12
84
+ return [y,m,d]
85
+ end
86
+
87
+ # 暦要素数
88
+ #
89
+ # @see When::CalendarTypes::TableBased#_length
90
+ #
91
+ def _length(date)
92
+ yy, mm = date
93
+ return super unless(mm)
94
+ return ((yy % 4) == 0) ? 29 : 28 if (mm == 1)
95
+ return (((((mm + 10) % 12) % 5) % 2) == 0) ? 31 : 30
96
+ end
97
+
98
+ # 復活祭の遅延日数
99
+ #
100
+ # @private
101
+ def _easter_delay(year)
102
+ 0
103
+ end
104
+
105
+ private
106
+
107
+ def _normalize(args=[], options={})
108
+ raise TypeError, "#{self.class} is abstract class" unless @label
109
+ @note = When.CalendarNote(@note || 'Christian')
110
+ @diff_to_CE ||= 0
111
+ super
112
+ end
113
+ end
114
+
115
+ #
116
+ # Julian Calendar
117
+ #
118
+ class Julian < Christian
119
+
120
+ # 太陰方程式
121
+ #
122
+ # @param [Numeric] year 西暦の年数
123
+ # @return [Integer] 0 (ユリウス暦では補正なし)
124
+ #
125
+ def _lunar_equation(year)
126
+ 0
127
+ end
128
+
129
+ # @private
130
+ #
131
+ # 対応する ::Date の start 属性
132
+ def _default_start
133
+ ::Date::JULIAN
134
+ end
135
+
136
+ private
137
+
138
+ def _normalize(args=[], options={})
139
+ @label ||= 'Christian::Julian'
140
+ super
141
+ end
142
+ end
143
+
144
+ #
145
+ # Swedish Calendar
146
+ #
147
+ class Swedish < Julian
148
+
149
+ # デフォルトの改暦日付(ユリウス通日)
150
+ #
151
+ # @private
152
+ DefaultReformDate = 2361390 # 1753-03-01
153
+
154
+ # @private
155
+ # Julian - 17000229 17120229
156
+ SwedishCalendarRange = 2342042...2346425
157
+
158
+ # @private
159
+ ExtraDate = [1712,1,29]
160
+
161
+ # @private
162
+ Length = {
163
+ [1700, nil] => 365,
164
+ [1700, 1] => 28,
165
+ [1712, nil] => 367,
166
+ [1712, 1] => 30
167
+ }
168
+
169
+ # Ref: http://www.ortelius.de/kalender/east_en.php
170
+ # @private
171
+ EasterDelay = {
172
+ 1741 => -7,
173
+ 1742 => -35,
174
+ 1744 => -7,
175
+ 1745 => -7,
176
+ 1747 => -28,
177
+ 1748 => -7,
178
+ 1750 => -28,
179
+ 1751 => -7,
180
+ 1752 => -7,
181
+ 1802 => +7,
182
+ 1805 => +7,
183
+ 1818 => +7
184
+ }
185
+
186
+ # 年月日 -> 通日
187
+ #
188
+ # @see When::CalendarTypes::TableBased#_coordinates_to_number
189
+ #
190
+ def _coordinates_to_number(y,m,d)
191
+ jdn = super
192
+ return SwedishCalendarRange.last if [+y, m, d] == ExtraDate
193
+ SwedishCalendarRange.include?(jdn-1) ? jdn-1 : jdn
194
+ end
195
+
196
+ # 通日 - > 年月日
197
+ #
198
+ # @see When::CalendarTypes::TableBased#_number_to_coordinates
199
+ #
200
+ def _number_to_coordinates(jdn)
201
+ return ExtraDate.dup if jdn == SwedishCalendarRange.last
202
+ super(SwedishCalendarRange.include?(jdn) ? jdn+1 : jdn)
203
+ end
204
+
205
+ # 暦要素数
206
+ #
207
+ # @see When::CalendarTypes::TableBased#_length
208
+ #
209
+ def _length(date)
210
+ y, m = date
211
+ Length[[+y,m]] || super
212
+ end
213
+
214
+ # 復活祭の遅延日数
215
+ #
216
+ # @private
217
+ def _easter_delay(year)
218
+ EasterDelay[year] || 0
219
+ end
220
+
221
+ private
222
+
223
+ def _normalize(args=[], options={})
224
+ @label ||= 'Christian::Swedish'
225
+ super
226
+ end
227
+ end
228
+
229
+ #
230
+ # Variation of Christian Calendar
231
+ #
232
+ class ReformVariation < Christian
233
+
234
+ # 年月日 -> 通日
235
+ #
236
+ # @see When::CalendarTypes::TableBased#_coordinates_to_number
237
+ #
238
+ def _coordinates_to_number(y,m,d)
239
+ super - _diff_from_century(((m < 2) ? +y-1 : +y).to_i.div(100))
240
+ end
241
+
242
+ # 通日 - > 年月日
243
+ #
244
+ # @see When::CalendarTypes::TableBased#_number_to_coordinates
245
+ #
246
+ def _number_to_coordinates(jdn)
247
+ super(jdn + _diff_from_century(_century_from_jdn(jdn)))
248
+ end
249
+
250
+ # 暦要素数
251
+ #
252
+ # @see When::CalendarTypes::TableBased#_length
253
+ #
254
+ def _length(date)
255
+ yy, mm = date
256
+ return super unless mm == 1 # 2月でなければユリウス暦と同じ
257
+ cc, yy = yy.divmod(100)
258
+ return super unless yy == 0 # 100で割り切れない年はユリウス暦と同じ
259
+ 29 - (_diff_from_century(cc) - _diff_from_century(cc-1))
260
+ end
261
+
262
+ # 太陰方程式
263
+ #
264
+ # @param [Numeric] year 西暦の年数
265
+ # @return [Integer] 19年7閏のペースに対する満月の日付の補正量
266
+ # @note 太陽暦日の補正も、本メソッドで行う
267
+ #
268
+ def _lunar_equation(year)
269
+ h = +year.div(100)
270
+ (8*(h+11)).div(25) - (_diff_from_century(h) + 5)
271
+ end
272
+ end
273
+
274
+ #
275
+ # Gregorian Calendar
276
+ #
277
+ class Gregorian < ReformVariation
278
+
279
+ # 百年代 - > ユリウス暦とグレゴリオ暦の差
280
+ #
281
+ # @param [Integer] century 百年代
282
+ #
283
+ # @return [Integer] ユリウス暦とグレゴリオ暦の差
284
+ #
285
+ def _diff_from_century(century)
286
+ (3*(century-3)).div(4)+1
287
+ end
288
+
289
+ # 通日 - > 百年代
290
+ #
291
+ # @param [Integer] jdn 通日
292
+ #
293
+ # @return [Integer] 百年代
294
+ #
295
+ def _century_from_jdn(jdn)
296
+ (4 * jdn - 6884477).div(146097)
297
+ end
298
+
299
+ private
300
+
301
+ def _normalize(args=[], options={})
302
+ @label ||= 'Christian::Gregorian'
303
+ super
304
+ end
305
+ end
306
+
307
+ #
308
+ # Revised Julian Calendar
309
+ #
310
+ class RevisedJulian < ReformVariation
311
+
312
+ # デフォルトの改暦日付(ユリウス通日)
313
+ #
314
+ # @private
315
+ DefaultReformDate = 2423707 # 1923-10-14
316
+
317
+ # 百年代 - > ユリウス暦と修正ユリウス暦の差
318
+ #
319
+ # @param [Integer] century 百年代
320
+ #
321
+ # @return [Integer] ユリウス暦と修正ユリウス暦の差
322
+ #
323
+ def _diff_from_century(century)
324
+ (7*(century-1)).div(9)-1
325
+ end
326
+
327
+ # 通日 - > 百年代
328
+ #
329
+ # @param [Integer] jdn 通日
330
+ #
331
+ # @return [Integer] 百年代
332
+ #
333
+ def _century_from_jdn(jdn)
334
+ (9 * jdn - 15490078).div(328718)
335
+ end
336
+
337
+ private
338
+
339
+ def _normalize(args=[], options={})
340
+ @label ||= 'Christian::RevisedJulian'
341
+ # @diff ||= [-2, -1, -1, 0, 1, 2, 2, 3, 4, 5] # 1~10世紀の各世紀のユリウス暦と差の日数
342
+ super
343
+ end
344
+ end
345
+
346
+ #
347
+ # Civil Calendar
348
+ #
349
+ class Civil < Gregorian
350
+
351
+ #
352
+ # 改暦日付
353
+ #
354
+ # @return [Integer]
355
+ #
356
+ attr_reader :reform_jdn
357
+
358
+ # @private
359
+ #
360
+ # 対応する ::Date の start 属性
361
+ alias :_default_start :reform_jdn
362
+
363
+ #
364
+ # 年初の最初の定義の年
365
+ #
366
+ # @return [Integer] 年初の最初の定義の年
367
+ # @return nil
368
+ #
369
+ def first_year_of_border
370
+ return nil unless @border.kind_of?(When::Coordinates::MultiBorder)
371
+ year = @border.borders[-1][:key]
372
+ year.kind_of?(Integer) ? year : nil
373
+ end
374
+
375
+ # 年月日 -> 通日
376
+ #
377
+ # @see When::CalendarTypes::TableBased#_coordinates_to_number
378
+ #
379
+ def _coordinates_to_number(y,m,d)
380
+ skip, limit = @the_length[[y,m]]
381
+ d += skip if skip && d >= limit
382
+ jdn = @new._coordinates_to_number(y,m,d)
383
+ jdn >= @reform_jdn ? jdn : @old._coordinates_to_number(y + @origin_of_MSC - @old.origin_of_MSC, m, d)
384
+ end
385
+
386
+ # 通日 - > 年月日
387
+ #
388
+ # @see When::CalendarTypes::TableBased#_number_to_coordinates
389
+ #
390
+ def _number_to_coordinates(jdn)
391
+ if jdn >= @reform_jdn
392
+ date = @new._number_to_coordinates(jdn)
393
+ else
394
+ date = @old._number_to_coordinates(jdn)
395
+ date[0] -= @origin_of_MSC - @old.origin_of_MSC
396
+ end
397
+ skip, limit = @the_length[date[0..-2]]
398
+ date[2] -= skip if skip && date[2] >= limit
399
+ date
400
+ end
401
+
402
+ # 暦要素数
403
+ #
404
+ # @see When::CalendarTypes::TableBased#_length
405
+ #
406
+ def _length(date)
407
+ return @the_length[date][2] if @the_length[date]
408
+ yy, mm = date
409
+ (yy > @reform_date[0]) ||
410
+ (yy == @reform_date[0] && (!mm || mm >= @reform_date[1])) ?
411
+ @new._length(date) :
412
+ @old._length([yy + @origin_of_MSC - @old.origin_of_MSC, mm])
413
+ end
414
+
415
+ # 太陰方程式
416
+ #
417
+ # @param [Numeric] year 西暦の年数
418
+ # @return [Integer] 19年7閏のペースに対する満月の日付の補正量
419
+ # @note 太陽暦日の補正も、本メソッドで行う
420
+ #
421
+ def _lunar_equation(year)
422
+ year >= @the_easter ? @new._lunar_equation(year) : @old._lunar_equation(year)
423
+ end
424
+
425
+ # 復活祭の遅延日数
426
+ #
427
+ # @private
428
+ def _easter_delay(year)
429
+ @old._easter_delay(year)
430
+ end
431
+
432
+ private
433
+
434
+ # オブジェクトの正規化
435
+ #
436
+ # @old = 改暦前の暦法(デフォルトはユリウス暦)
437
+ # @new = 改暦後の暦法(デフォルトはグレゴリオ暦)
438
+ # @reform_date = 改暦日付(月日は 1 オリジンで指定し、0 オリジンに直して保持)
439
+ # @reform_jdn = 改暦日付のユリウス通日
440
+ # @reform = reform_date reform_jdn を内容で判別し、どちらかに反映する
441
+ # @the_easter = 新暦法の復活祭計算の適用を始める年
442
+ # @the_length = 通常と異なる日付となる年月の情報({[年,月]=>[スキップした日数, スキップし始める日, 月の日数]})
443
+ #
444
+ def _normalize(args=[], options={})
445
+ @label ||= 'Christian::Civil'
446
+
447
+ # 前後の暦法
448
+ @old = When.Calendar(@old || 'Julian')
449
+ @new = When.Calendar(@new || 'Gregorian')
450
+ @indices ||= @old.indices
451
+
452
+ # 改暦日付 (0 オリジン)
453
+ @reform = When::Coordinates::Pair._en_pair_date_time(@reform) if @reform.kind_of?(String)
454
+ case @reform.length
455
+ when 0 ;
456
+ when 1 ; @reform_jdn = @reform[0]
457
+ else ; @reform_date = @reform
458
+ end if @reform.kind_of?(Array)
459
+
460
+ if @reform_date
461
+ @reform_date = When::Coordinates::Pair._en_pair_date_time(@reform_date) if @reform_date.kind_of?(String)
462
+ @reform_date = @reform_date.map {|c| c.to_i}
463
+ (1..2).each {|i| @reform_date[i] = @reform_date[i] ? @reform_date[i] - 1 : 0 }
464
+ @reform_jdn = @new._coordinates_to_number(*@reform_date)
465
+ else
466
+ @reform_jdn ||= [@old.class::DefaultReformDate, @new.class::DefaultReformDate].max
467
+ @reform_jdn = @reform_jdn.to_i
468
+ @reform_date = @new._number_to_coordinates(@reform_jdn)
469
+ end
470
+ last_date = @old._number_to_coordinates(@reform_jdn-1)
471
+
472
+ # 復活祭との前後関係
473
+ @the_easter = @reform_jdn > When.CalendarNote('Christian').easter(@reform_date[0], @new) ? @reform_date[0]+1 : @reform_date[0]
474
+
475
+ # 月の日数
476
+ this_month = @reform_date[0..1]
477
+ new_length = @new._length(this_month)
478
+ @the_length = {}
479
+ if @reform_date[1] == last_date[1] # 同一月内に閉じた改暦
480
+ skipped_length = @reform_date[2] - last_date[2] - 1
481
+ @the_length[this_month] = [skipped_length, last_date[2]+1, new_length-skipped_length]
482
+ else
483
+ last_month = [(@reform_date[1] > last_date[1] ? @reform_date[0] : @reform_date[0]-1), last_date[1]]
484
+ @the_length[this_month] = [@reform_date[2], 0, new_length - @reform_date[2]]
485
+ @the_length[last_month] = [false, false, last_date[2]+1]
486
+ end
487
+
488
+ super
489
+ end
490
+
491
+ #
492
+ # 整数のindex化
493
+ #
494
+ def _to_index(date)
495
+ digit = date[-1] - @base[date.length-1]
496
+ skip, limit = @the_length[date[0..-2]]
497
+ skip && digit >= limit ? digit-skip : digit
498
+ end
499
+
500
+ #
501
+ # indexの整数化
502
+ #
503
+ def _from_index(date)
504
+ digit = date[-1]
505
+ skip, limit = @the_length[date[0..-2]]
506
+ (skip && digit >= limit ? digit+skip : digit)+@base[date.length-1]
507
+ end
508
+ end
509
+ end
510
+
511
+ module Coordinates
512
+
513
+ #
514
+ # 日時要素の境界 - 復活祭
515
+ #
516
+ class Easter < Border
517
+
518
+ # 境界の取得
519
+ #
520
+ # @param [Array<Numeric>] date 境界を計算する年
521
+ # @param [When::TM::ReferenceSystem] frame 使用する暦法
522
+ #
523
+ # @return [Array<Numeric>] その年の境界
524
+ #
525
+ def border(date=[], frame=When::Gregorian)
526
+ frame._encode(frame._number_to_coordinates(frame.note.easter(date[0], frame)), false)
527
+ end
528
+
529
+ private
530
+
531
+ # 要素の正規化
532
+ def _normalize(args=[], options={})
533
+ @border = [0,0,0]
534
+ end
535
+ end
536
+ end
537
+
538
+ #
539
+ # キリスト教の暦注(クリスマスと復活祭)
540
+ #
541
+ class CalendarNote::Christian < CalendarNote
542
+
543
+ Notes = [When::BasicTypes::M17n, [
544
+ "locale:[=en:, ja=ja:, alias]",
545
+ "names:[Christian]",
546
+
547
+ # 年の暦注 ----------------------------
548
+ [When::BasicTypes::M17n,
549
+ "names:[year]"
550
+ ],
551
+
552
+ # 月の暦注 ----------------------------
553
+ [When::BasicTypes::M17n,
554
+ "names:[month]",
555
+ [When::BasicTypes::M17n,
556
+ "names:[Month]"
557
+ ]
558
+ ],
559
+
560
+ # 日の暦注 ----------------------------
561
+ [When::BasicTypes::M17n,
562
+ "names:[day]",
563
+ [When::BasicTypes::M17n, "names:[Week, 七曜]" ],
564
+ [When::BasicTypes::M17n, "names:[Easter, 復活祭]" ],
565
+ [When::BasicTypes::M17n, "names:[Christmas, クリスマス]"],
566
+ [When::BasicTypes::M17n, "names:[Fixed_feast=, 固定祝日=]" ],
567
+ [When::BasicTypes::M17n, "names:[Moveable_feast, 移動祝日]" ]
568
+ ]
569
+ ]]
570
+
571
+ # 固定祝日
572
+ Fixed_feasts = {
573
+ [ 1, 6] => "Epiphany",
574
+ [ 3, 1] => "St.David's Day",
575
+ [ 3, 17] => "St.Patrick's Day",
576
+ [ 3, 25] => "Annunciation-Lady Day",
577
+ [ 4, 23] => "St.George's Day",
578
+ [ 6, 24] => "Midsummer Day",
579
+ [ 9, 14] => "Holy Cross Day",
580
+ [ 9, 29] => "Michaelmas Day",
581
+ [11, 30] => "St.Andrew's Day",
582
+ [12, 13] => "St.Lucia's Day",
583
+ [12, 21] => "St.Thomas's Day",
584
+ # [12, 25] => "Christmas Day"
585
+ }
586
+
587
+ # 移動祝日 (日付と曜日による)
588
+ moveable_feasts = {}
589
+ [[[ 9, 15, 2], "III Quatember"],
590
+ [[11, 27, 6], "Advent Sunday"],
591
+ [[12, 14, 2], "IV Quatember" ]].each do |pair|
592
+ date, name = pair
593
+ 7.times do
594
+ moveable_feasts[date.dup] = name
595
+ date[1] += 1
596
+ if date[1] > 30
597
+ date[0] += 1
598
+ date[1] = 1
599
+ end
600
+ end
601
+ end
602
+
603
+ # 移動祝日
604
+ Moveable_feasts = {
605
+ # 復活祭からの日数による
606
+ -63 => "Septuagesima Sunday",
607
+ -56 => "Sexagesima Sunday",
608
+ -49 => "Quinquagesima Sunday",
609
+ -46 => "Ash Wednesday",
610
+ -42 => "Quadragesima Sunday",
611
+ -40 => "I Quatember",
612
+ -35 => "Reminizer Sunday",
613
+ -28 => "Oculi Sunday",
614
+ -21 => "Laetare Sunday",
615
+ -14 => "Judica Sunday",
616
+ -7 => "Palmarum",
617
+ -2 => "Good Friday",
618
+ # 0 => "Easter Day",
619
+ 7 => "Low Sunday",
620
+ 35 => "Rogation Sunday",
621
+ 39 => "Ascension Day",
622
+ 49 => "Whitsunday",
623
+ 53 => "II Quatember",
624
+ 56 => "Trinity Sunday",
625
+ 60 => "Corpus Christi",
626
+ }.update(moveable_feasts)
627
+
628
+ #
629
+ # 暦法によってイベントの動作を変えるか否か
630
+ #
631
+ CalendarDepend = true
632
+
633
+ # 週日補正フラグ
634
+ # @return [Integer]
635
+ attr_reader :w
636
+
637
+ # 最も遅い満月の3月0日からの日数
638
+ # @return [Integer]
639
+ attr_reader :d
640
+
641
+ # クリスマスの3月0日からの日数
642
+ # @return [Integer]
643
+ attr_reader :x
644
+
645
+ # 平年数
646
+ # @return [Integer]
647
+ attr_reader :n
648
+
649
+ # 置閏周期
650
+ # @return [Integer]
651
+ attr_reader :s
652
+
653
+ # 月の位相の補正
654
+ # @return [Integer]
655
+ attr_reader :c
656
+
657
+ # ガード
658
+ # @return [Integer]
659
+ attr_reader :g
660
+
661
+ # ベース
662
+ # @return [Integer]
663
+ attr_reader :b
664
+
665
+ # 満月補正フラグ
666
+ # @return [Integer]
667
+ attr_reader :f
668
+
669
+ # 七曜
670
+ #
671
+ # @param [When::TM::TemporalPosition] date
672
+ # @param [When::TM::CalDate] base (not used)
673
+ #
674
+ # @return [When::Coordinates::Residue] 七曜
675
+ #
676
+ def week(date, base=nil)
677
+ When.Residue('Week')[date.to_i % 7]
678
+ end
679
+
680
+ # クリスマス
681
+ #
682
+ # @param [Numeric] date 西暦の年数
683
+ # @param [When::TM::TemporalPosition] date
684
+ # @param [When::TM::ReferenceSystem] frame 使用する暦法(デフォルトは When::Gregorian)
685
+ #
686
+ # @return [Integer] クリスマスのユリウス通日(dateが西暦の年数の場合)
687
+ # @return [When::TM::CalDate] クリスマスのWhen::TM::CalDate(yearがWhen::TM::TemporalPositionの場合)
688
+ #
689
+ def christmas(date, frame=nil)
690
+ _event(date, 'christmas', frame) do |year, frame|
691
+ @x - 1 + frame._coordinates_to_number(year, 2, 0)
692
+ end
693
+ end
694
+
695
+ # 復活祭
696
+ #
697
+ # @param [Numeric] date 西暦の年数
698
+ # @param [When::TM::TemporalPosition] date
699
+ # @param [When::TM::ReferenceSystem] frame 使用する暦法(デフォルトは When::Gregorian)
700
+ #
701
+ # @return [Integer] 復活祭のユリウス通日(dateが西暦の年数の場合)
702
+ # @return [When::TM::CalDate] 復活祭のWhen::TM::CalDate(yearがWhen::TM::TemporalPositionの場合)
703
+ #
704
+ def easter(date, frame=nil)
705
+ _event(date, 'easter', frame) do |year, frame|
706
+ golden = (year+@b) % @s + 1
707
+ m = (frame._lunar_equation(year) + 11*golden + @c) % 30
708
+ if @f == 0
709
+ m += 1 if m==0 || m==1 && golden>=@n
710
+ else
711
+ m += (golden-1) / @f
712
+ m -= 30 if m>=@n
713
+ end
714
+ result = frame._coordinates_to_number(year, 2, 0) + @d - 1 - m
715
+ result += @g - (result-@w) % 7 if @w<7
716
+ result + frame._easter_delay(year)
717
+ end
718
+ end
719
+
720
+ # イベントの標準的な間隔を返す
721
+ # @private
722
+ def _delta(parameter=nil)
723
+ return When::P1Y
724
+ end
725
+
726
+ # @private
727
+ alias :christmas_delta :_delta
728
+
729
+ # @private
730
+ alias :easter_delta :_delta
731
+
732
+ # 固定祝日
733
+ #
734
+ # @param [When::TM::TemporalPosition] date
735
+ # @param [When::TM::ReferenceSystem] frame 使用する暦法(デフォルトは When::Gregorian)
736
+ #
737
+ # @return [String] 祝日の名称
738
+ # @return [nil] 祝日に該当しない
739
+ #
740
+ def fixed_feast(date, frame=nil)
741
+ date = When.Calendar(frame||'Gregorian') ^ date unless date.frame.kind_of?(When::CalendarTypes::Christian)
742
+ Fixed_feasts[date.cal_date[-2..-1]]
743
+ end
744
+
745
+ # 移動祝日
746
+ #
747
+ # @param [When::TM::TemporalPosition] date
748
+ # @param [When::TM::ReferenceSystem] frame 使用する暦法(デフォルトは When::Gregorian)
749
+ #
750
+ # @return [String] 祝日の名称
751
+ # @return [nil] 祝日に該当しない
752
+ #
753
+ def moveable_feast(date, frame=nil)
754
+ result = Moveable_feasts[date.to_i - easter(date, frame).to_i]
755
+ return result if result
756
+ date = When.Calendar(frame||'Gregorian') ^ date unless date.frame.kind_of?(When::CalendarTypes::Christian)
757
+ Moveable_feasts[date.cal_date[-2..-1] + [date.to_i % 7]]
758
+ end
759
+
760
+ private
761
+
762
+ # オブジェクトの正規化
763
+ # w - 週日補正フラグ(デフォルト 6)
764
+ # d - 最も遅い満月 (デフォルト 3月0日から 50日)
765
+ # x - クリスマス (デフォルト 3月0日から300日)
766
+ # n - 平年数 (デフォルト 12)
767
+ # s - 置閏周期 (デフォルト 19)
768
+ # c - 月の位相の補正(デフォルト 3)
769
+ # g - ガード (デフォルト 7)
770
+ # b - ベース (デフォルト 0)
771
+ # f - 満月補正フラグ(デフォルト 0)
772
+ def _normalize(args=[], options={})
773
+ w, d, x, n, s, c, g, b, f = args
774
+ @w = (w || @w || 6).to_i
775
+ @d = (d || @d || 50).to_i
776
+ @x = (x || @x || 300).to_i
777
+ @n = (n || @n || 12).to_i
778
+ @s = (s || @s || 19).to_i
779
+ @c = (c || @c || 3).to_i
780
+ @g = (g || @g || 7).to_i
781
+ @b = (b || @b || 0).to_i
782
+ @f = (f || @f || 0).to_i
783
+ @event = 'easter'
784
+ @prime ||= [['Month'], ['Week']]
785
+ super
786
+ end
787
+
788
+ #
789
+ # 任意の暦をグレゴリオorユリウス暦日に変換
790
+ #
791
+ def _to_date_for_note(date)
792
+ return When.Calendar(When::CalendarTypes::Christian._default_start(date)) ^ date if ::Object.const_defined?(:Date) &&
793
+ ::Date.method_defined?(:+) && date.kind_of?(::Date)
794
+ return When::Gregorian ^ date if date.kind_of?(::Time)
795
+ return date if date.frame.kind_of?(When::CalendarTypes::Christian)
796
+ When.Calendar(date.frame.iri =~ /Coptic/ || date.to_i < 2299161 ? 'Julian' : 'Gregorian') ^ date
797
+ end
798
+
799
+ # 当該年のイベントの日付
800
+ # date : 西暦の年数 or When::TM::(Temporal)Position
801
+ # event : イベント名 (String)
802
+ # frame : 暦法(デフォルトは When:Gregorian)
803
+ #
804
+ # @return [Integer] イベントのユリウス通日(dateが西暦の年数の場合)
805
+ # @return [When::TM::CalDate] イベントのWhen::TM::CalDate(yearがWhen::TM::(Temporal)Positionの場合)
806
+ #
807
+ def _event(date, event, frame=nil)
808
+ case date
809
+ when Numeric
810
+ year = date * 1
811
+ when When::TimeValue
812
+ options = date._attr
813
+ options[:precision] = When::DAY
814
+ options[:events] = [event]
815
+ if frame
816
+ frame = When.Calendar(frame)
817
+ date = frame.jul_trans(date, options)
818
+ else
819
+ frame = date.frame
820
+ end
821
+ year = date.most_significant_coordinate * 1
822
+ else
823
+ raise TypeError, "Irregal date type: #{date.class}"
824
+ end
825
+ frame ||= When::Gregorian
826
+ result = yield(year, frame)
827
+ return result if date.kind_of?(Numeric)
828
+ return frame.jul_trans(result, options)
829
+ end
830
+ end
831
+ end