when_exe 0.3.6 → 0.3.7

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.
Files changed (117) hide show
  1. checksums.yaml +7 -0
  2. data/README.md +171 -0
  3. data/lib/when_exe.rb +78 -47
  4. data/lib/when_exe/basictypes.rb +752 -747
  5. data/lib/when_exe/calendarnote.rb +805 -801
  6. data/lib/when_exe/calendartypes.rb +1583 -1531
  7. data/lib/when_exe/coordinates.rb +16 -15
  8. data/lib/when_exe/core/duration.rb +114 -110
  9. data/lib/when_exe/core/extension.rb +504 -504
  10. data/lib/when_exe/ephemeris.rb +1917 -1913
  11. data/lib/when_exe/ephemeris/moon.rb +333 -333
  12. data/lib/when_exe/ephemeris/notes.rb +389 -387
  13. data/lib/when_exe/ephemeris/planets.rb +585 -585
  14. data/lib/when_exe/ephemeris/sun.rb +214 -214
  15. data/lib/when_exe/googlecalendar.rb +144 -140
  16. data/lib/when_exe/icalendar.rb +1636 -1636
  17. data/lib/when_exe/inspect.rb +46 -22
  18. data/lib/when_exe/locales/akt.rb +176 -176
  19. data/lib/when_exe/locales/encoding_conversion.rb +134 -126
  20. data/lib/when_exe/locales/iast.rb +90 -90
  21. data/lib/when_exe/locales/locale.rb +750 -746
  22. data/lib/when_exe/locales/transliteration_table.rb +62 -62
  23. data/lib/when_exe/mini_application.rb +307 -305
  24. data/lib/when_exe/parts/enumerator.rb +2 -2
  25. data/lib/when_exe/parts/geometric_complex.rb +397 -397
  26. data/lib/when_exe/parts/method_cash.rb +224 -224
  27. data/lib/when_exe/parts/resource.rb +1069 -1071
  28. data/lib/when_exe/parts/timezone.rb +240 -230
  29. data/lib/when_exe/region/armenian.rb +56 -56
  30. data/lib/when_exe/region/babylonian.rb +405 -0
  31. data/lib/when_exe/region/bahai.rb +146 -146
  32. data/lib/when_exe/region/balinese.rb +622 -622
  33. data/lib/when_exe/region/chinese.rb +95 -25
  34. data/lib/when_exe/region/chinese/calendars.rb +1016 -1016
  35. data/lib/when_exe/region/chinese/epochs.rb +1 -1
  36. data/lib/when_exe/region/chinese/twins.rb +803 -795
  37. data/lib/when_exe/region/christian.rb +824 -824
  38. data/lib/when_exe/region/coptic.rb +106 -87
  39. data/lib/when_exe/region/discordian.rb +225 -225
  40. data/lib/when_exe/region/far_east.rb +188 -188
  41. data/lib/when_exe/region/french.rb +56 -56
  42. data/lib/when_exe/region/geologicalage.rb +639 -639
  43. data/lib/when_exe/region/goddess.rb +58 -58
  44. data/lib/when_exe/region/indian.rb +1254 -1251
  45. data/lib/when_exe/region/iranian.rb +8 -8
  46. data/lib/when_exe/region/islamic.rb +3 -3
  47. data/lib/when_exe/region/japanese.rb +93 -99
  48. data/lib/when_exe/region/japanese/calendars.rb +396 -397
  49. data/lib/when_exe/region/japanese/epochs.rb +26 -26
  50. data/lib/when_exe/region/japanese/nihon_shoki.rb +71 -71
  51. data/lib/when_exe/region/japanese/notes.rb +1383 -1386
  52. data/lib/when_exe/region/japanese/residues.rb +1306 -1306
  53. data/lib/when_exe/region/japanese/twins.rb +225 -225
  54. data/lib/when_exe/region/japanese/weeks.rb +112 -0
  55. data/lib/when_exe/region/javanese.rb +230 -230
  56. data/lib/when_exe/region/jewish.rb +126 -126
  57. data/lib/when_exe/region/korean.rb +378 -378
  58. data/lib/when_exe/region/m17n.rb +114 -113
  59. data/lib/when_exe/region/martian.rb +258 -255
  60. data/lib/when_exe/region/mayan.rb +32 -32
  61. data/lib/when_exe/region/residue.rb +89 -89
  62. data/lib/when_exe/region/roman.rb +36 -24
  63. data/lib/when_exe/region/ryukyu.rb +97 -97
  64. data/lib/when_exe/region/shire.rb +240 -240
  65. data/lib/when_exe/region/soviet.rb +209 -0
  66. data/lib/when_exe/region/symmetry.rb +50 -50
  67. data/lib/when_exe/region/thai.rb +336 -335
  68. data/lib/when_exe/region/tibetan.rb +316 -315
  69. data/lib/when_exe/region/vietnamese.rb +440 -439
  70. data/lib/when_exe/region/weekdate.rb +80 -80
  71. data/lib/when_exe/region/world.rb +175 -175
  72. data/lib/when_exe/region/yerm.rb +14 -14
  73. data/lib/when_exe/region/zoroastrian.rb +203 -203
  74. data/lib/when_exe/timestandard.rb +707 -681
  75. data/lib/when_exe/tmduration.rb +338 -330
  76. data/lib/when_exe/tmobjects.rb +1346 -1325
  77. data/lib/when_exe/tmposition.rb +2115 -2072
  78. data/lib/when_exe/tmreference.rb +1693 -1669
  79. data/lib/when_exe/version.rb +1 -1
  80. data/link_to_online_documents +1 -1
  81. data/test/examples/JapanHolidaysRFC6350.ics +1 -1
  82. data/test/test.rb +67 -61
  83. data/test/test/basictypes.rb +409 -409
  84. data/test/test/calendarnote.rb +86 -69
  85. data/test/test/calendartypes.rb +97 -97
  86. data/test/test/coordinates.rb +396 -396
  87. data/test/test/ephemeris.rb +83 -74
  88. data/test/test/ephemeris/moon.rb +14 -14
  89. data/test/test/ephemeris/planets.rb +14 -14
  90. data/test/test/ephemeris/sun.rb +14 -14
  91. data/test/test/googlecalendar.rb +194 -176
  92. data/test/test/icalendar.rb +867 -858
  93. data/test/test/inspect.rb +117 -117
  94. data/test/test/parts.rb +487 -487
  95. data/test/test/region/balinese.rb +34 -0
  96. data/test/test/region/chinese.rb +218 -206
  97. data/test/test/region/christian.rb +245 -245
  98. data/test/test/region/coptic.rb +27 -27
  99. data/test/test/region/french.rb +33 -33
  100. data/test/test/region/geologicalage.rb +17 -17
  101. data/test/test/region/indian.rb +57 -57
  102. data/test/test/region/iran.rb +54 -54
  103. data/test/test/region/islamic.rb +18 -18
  104. data/test/test/region/japanese.rb +237 -219
  105. data/test/test/region/jewish.rb +61 -61
  106. data/test/test/region/m17n.rb +184 -184
  107. data/test/test/region/mayan.rb +195 -195
  108. data/test/test/region/residue.rb +147 -139
  109. data/test/test/region/thai.rb +116 -116
  110. data/test/test/region/tibetan.rb +30 -30
  111. data/test/test/region/vietnamese.rb +102 -102
  112. data/test/test/region/yerm.rb +146 -146
  113. data/test/test/timestandard.rb +81 -81
  114. data/test/test/tmobjects.rb +328 -328
  115. data/test/test/tmposition.rb +397 -284
  116. data/test/test/tmreference.rb +157 -157
  117. metadata +13 -10
@@ -39,27 +39,27 @@ module When
39
39
  # Analyze notation with crescent
40
40
  #
41
41
  # @param [String] source Notation with crescents
42
- # @param [Array<Integer>] Upper default elements (default - today's Yerm date)
42
+ # @param [Array<Integer>] abbr Upper default elements (default - today's Yerm date)
43
43
  #
44
44
  # @return [String] Notation with hyphens
45
45
  #
46
46
  def self.parse(source, abbr=nil)
47
47
  c, y, m, d = abbr || (When::Yerm^When.today).cal_date
48
48
  case source
49
- when /^(-?\d+)[-\(](\d+)\((\d+)\((\d+)$/; c, y, m, d = [$1, $2, $3, $4]
50
- when /^(-?\d+)-(\d+)\((\d+)$/ ; c, y, m, d = [$1, $2, $3 ]
51
- when /^(-?\d+)-(\d+)$/ ; c, y, m, d = [$1, $2 ]
52
- when /^(-?\d+)-$/ ; c, y, m, d = [$1 ]
53
- when /^(\d+)\((\d+)\((\d+)$/ ; y, m, d = [ $1, $2, $3]
54
- when /^(\d+)\((\d+)$/ ; m, d = [ $1, $2]
55
- when /^(\d+)$/ ; d = $1
49
+ when /\A(-?\d+)[-\(](\d+)\((\d+)\((\d+)\z/; c, y, m, d = [$1, $2, $3, $4]
50
+ when /\A(-?\d+)-(\d+)\((\d+)\z/ ; c, y, m, d = [$1, $2, $3 ]
51
+ when /\A(-?\d+)-(\d+)\z/ ; c, y, m, d = [$1, $2 ]
52
+ when /\A(-?\d+)-\z/ ; c, y, m, d = [$1 ]
53
+ when /\A(\d+)\((\d+)\((\d+)\z/ ; y, m, d = [ $1, $2, $3]
54
+ when /\A(\d+)\((\d+)\z/ ; m, d = [ $1, $2]
55
+ when /\A(\d+)\z/ ; d = $1
56
56
 
57
- when /^(\d+)\)(\d+)\)(\d+)[-\)](-?\d+)$/; c, y, m, d = [$4, $3, $2, $1]
58
- when /^(\d+)\)(\d+)-(-?\d+)$/ ; c, y, m, d = [$3, $2, $1 ]
59
- when /^(\d+)-(-\d+)$/ ; c, y, m, d = [$2, $1 ]
60
- when /^(-\d+)$/ ; c, y, m, d = [$1 ]
61
- when /^(\d+)\)(\d+)\)(\d+)$/ ; y, m, d = [ $3, $2, $1]
62
- when /^(\d+)\)(\d+)$/ ; m, d = [ $2, $1]
57
+ when /\A(\d+)\)(\d+)\)(\d+)[-\)](-?\d+)\z/; c, y, m, d = [$4, $3, $2, $1]
58
+ when /\A(\d+)\)(\d+)-(-?\d+)\z/ ; c, y, m, d = [$3, $2, $1 ]
59
+ when /\A(\d+)-(-\d+)\z/ ; c, y, m, d = [$2, $1 ]
60
+ when /\A(-\d+)\z/ ; c, y, m, d = [$1 ]
61
+ when /\A(\d+)\)(\d+)\)(\d+)\z/ ; y, m, d = [ $3, $2, $1]
62
+ when /\A(\d+)\)(\d+)\z/ ; m, d = [ $2, $1]
63
63
  else ; c, y, m, d = [ ]
64
64
  end
65
65
 
@@ -1,203 +1,203 @@
1
- # -*- coding: utf-8 -*-
2
- =begin
3
- Copyright (C) 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
- =begin
9
-
10
- References
11
-
12
- (1) http://en.wikipedia.org/wiki/Zoroastrian_calendar
13
- (2) http://www.moonwise.co.uk/year/1375zoroastrian.htm
14
- (3) http://www.zoroastrian.org/articles/nowruz.htm
15
-
16
- =end
17
-
18
- module When
19
- class BasicTypes::M17n
20
-
21
- Zoroastrian = [self, [
22
- "locale:[=en:, ja=ja:, ar=ar:, alias=ja:]",
23
- "names:[Zoroastrian=]",
24
- "[Zoroastrian=en:Zoroastrian_calendar#The_reckoning_of_years, ゾロアスター暦= ]",
25
- "[Qadimi=en:Zoroastrian_calendar#The_Qadimi_calendar , カディミ暦= ]",
26
- "[Shahanshahi=en:Zoroastrian_calendar#The_Shahanshahi_calendar, シャハンシャヒ暦=]",
27
- "[Fasli=en:Zoroastrian_calendar#The_Fasli_calendar , ファスリ暦= ]"
28
- ]]
29
- end
30
-
31
- #
32
- # ゾロアスター暦の暦注
33
- #
34
- class CalendarNote::Zoroastrian < CalendarNote
35
-
36
- Notes = [When::BasicTypes::M17n, [
37
- "locale:[=en:]",
38
- "names:[Zoroastrian]",
39
-
40
- # 年の暦注 ----------------------------
41
- [When::BasicTypes::M17n,
42
- "names:[year]",
43
- ],
44
-
45
- # 月の暦注 ----------------------------
46
- [When::BasicTypes::M17n,
47
- "names:[month]",
48
- [When::BasicTypes::M17n,
49
- "names:[Month]",
50
- "[Fravardin= ]",
51
- "[Ardibehest= ]",
52
- "[Khordad= ]",
53
- "[Tir= ]",
54
- "[Amardad= ]",
55
- "[Shehrevar= ]",
56
- "[Meher= ]",
57
- "[Avan= ]",
58
- "[Adar= ]",
59
- "[Dae= ]",
60
- "[Bahman= ]",
61
- "[Aspandarmad= ]",
62
- "[Gatha Days= ]"
63
- ]
64
- ],
65
-
66
- # 日の暦注 ----------------------------
67
- [When::BasicTypes::M17n,
68
- "names:[day]",
69
- [When::BasicTypes::M17n,
70
- "names:[divinity]",
71
- "[Hormazd= ]", # 01
72
- "[Bahman= ]", # 02
73
- "[Ardibehest= ]", # 03
74
- "[Shehrevar= ]", # 04
75
- "[Aspandarmad= ]", # 05
76
- "[Khordad= ]", # 06
77
- "[Amardad= ]", # 07
78
- "[Daepadar= ]", # 08
79
- "[Adar= ]", # 09
80
- "[Avan= ]", # 10
81
- "[Khorshed= ]", # 11
82
- "[Mohor= ]", # 12
83
- "[Tir= ]", # 13
84
- "[Gosh= ]", # 14
85
- "[Daepmeher= ]", # 15
86
- "[Meher= ]", # 16
87
- "[Srosh= ]", # 17
88
- "[Rashne= ]", # 18
89
- "[Fravardin= ]", # 19
90
- "[Behram= ]", # 20
91
- "[Ram= ]", # 21
92
- "[Govad= ]", # 22
93
- "[Daepdin= ]", # 23
94
- "[Din= ]", # 24
95
- "[Ashishvangh= ]", # 25
96
- "[Ashtad= ]", # 26
97
- "[Asman= ]", # 27
98
- "[Zamyad= ]", # 28
99
- "[Mahrespand= ]", # 29
100
- "[Aneran= ]", # 30
101
- "[Ahunavad= ]", # 31
102
- "[Ushtavad= ]", # 32
103
- "[Spentomad= ]", # 33
104
- "[Vohukhshathra= ]", # 34
105
- "[Vahishtoist= ]", # 35
106
- "[intercalary day=]" # 36
107
- ]
108
- ]
109
- ]]
110
-
111
- # 暦注 - 日の名前
112
- #
113
- # @param [When::TM::CalDate] date
114
- #
115
- # @return [String]
116
- #
117
- def divinity(date)
118
- y, m, d = date.cal_date
119
- When.CalendarNote('Zoroastrian/Notes::day::divinity::*')[m <= 12 ? d-1 : d+29]
120
- end
121
- end
122
-
123
- module CalendarTypes
124
-
125
- #
126
- # Zoroastrian Calendar
127
- #
128
- Zoroastrian = [CyclicTableBased, {
129
- 'label' => 'Zoroastrian::Zoroastrian',
130
- 'indices' => [
131
- When.Index('ZoroastrianNotes::month::Month', {:unit =>13}),
132
- When::Coordinates::DefaultDayIndex
133
- ],
134
- 'origin_of_MSC' => 1,
135
- 'origin_of_LSC' => 1952063 + 5 - 365 * 1020,
136
- 'epoch_in_CE' => 31,
137
- 'rule_table' => {
138
- 'T' => {'Rule' =>[365]},
139
- 365 => {'Length'=>[30]*12+[5]}
140
- },
141
- 'note' => 'Zoroastrian'
142
- }]
143
-
144
- #
145
- # Qadimi Calendar
146
- #
147
- Qadimi = [CyclicTableBased, {
148
- 'label' => 'Zoroastrian::Qadimi',
149
- 'indices' => [
150
- When.Index('ZoroastrianNotes::month::Month', {:unit =>13}),
151
- When::Coordinates::DefaultDayIndex
152
- ],
153
- 'origin_of_MSC' => 1,
154
- 'origin_of_LSC' => 1952063,
155
- 'epoch_in_CE' => 31,
156
- 'rule_table' => {
157
- 'T' => {'Rule' =>[365]},
158
- 365 => {'Length'=>[30]*12+[5]}
159
- },
160
- 'note' => 'Zoroastrian'
161
- }]
162
-
163
- #
164
- # Shahanshahi Calendar
165
- #
166
- Shahanshahi = [CyclicTableBased, {
167
- 'label' => 'Zoroastrian::Shahanshahi',
168
- 'indices' => [
169
- When.Index('ZoroastrianNotes::month::Month', {:unit =>13}),
170
- When::Coordinates::DefaultDayIndex
171
- ],
172
- 'origin_of_MSC' => 1,
173
- 'origin_of_LSC' => 1952063 + 30,
174
- 'epoch_in_CE' => 31,
175
- 'rule_table' => {
176
- 'T' => {'Rule' =>[365]},
177
- 365 => {'Length'=>[30]*12+[5]}
178
- },
179
- 'note' => 'Zoroastrian'
180
- }]
181
-
182
- #
183
- # Fasli Calendar
184
- #
185
- Fasli = [{'Epoch'=>{
186
- 'ZRE'=>{'origin_of_MSC'=>1737},
187
- 'YZ' =>{'origin_of_MSC'=>-630}
188
- }}, Bahai, {
189
- 'label' => 'Zoroastrian::Fasli',
190
- 'indices' => [
191
- When.Index('ZoroastrianNotes::month::Month', {:unit =>13}),
192
- When::Coordinates::DefaultDayIndex
193
- ],
194
- 'origin_of_MSC' => -630,
195
- 'epoch_in_CE' => 0,
196
- 'rule_table' => {
197
- 365 => {'Length'=>[30] * 12 + [5]},
198
- 366 => {'Length'=>[30] * 12 + [6]}
199
- },
200
- 'note' => 'Zoroastrian'
201
- }]
202
- end
203
- end
1
+ # -*- coding: utf-8 -*-
2
+ =begin
3
+ Copyright (C) 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
+ =begin
9
+
10
+ References
11
+
12
+ (1) http://en.wikipedia.org/wiki/Zoroastrian_calendar
13
+ (2) http://www.moonwise.co.uk/year/1375zoroastrian.htm
14
+ (3) http://www.zoroastrian.org/articles/nowruz.htm
15
+
16
+ =end
17
+
18
+ module When
19
+ class BasicTypes::M17n
20
+
21
+ Zoroastrian = [self, [
22
+ "locale:[=en:, ja=ja:, ar=ar:, alias=ja:]",
23
+ "names:[Zoroastrian=]",
24
+ "[Zoroastrian=en:Zoroastrian_calendar#The_reckoning_of_years, ゾロアスター暦=]",
25
+ "[Qadimi=en:Zoroastrian_calendar#The_Qadimi_calendar , カディミ暦= ]",
26
+ "[Shahanshahi=en:Zoroastrian_calendar#The_Shahanshahi_calendar, 諸王の王の暦= ]",
27
+ "[Fasli=en:Zoroastrian_calendar#The_Fasli_calendar , ファスリ暦= ]"
28
+ ]]
29
+ end
30
+
31
+ #
32
+ # ゾロアスター暦の暦注
33
+ #
34
+ class CalendarNote::Zoroastrian < CalendarNote
35
+
36
+ Notes = [When::BasicTypes::M17n, [
37
+ "locale:[=en:]",
38
+ "names:[Zoroastrian]",
39
+
40
+ # 年の暦注 ----------------------------
41
+ [When::BasicTypes::M17n,
42
+ "names:[year]",
43
+ ],
44
+
45
+ # 月の暦注 ----------------------------
46
+ [When::BasicTypes::M17n,
47
+ "names:[month]",
48
+ [When::BasicTypes::M17n,
49
+ "names:[Month]",
50
+ "[Fravardin= ]",
51
+ "[Ardibehest= ]",
52
+ "[Khordad= ]",
53
+ "[Tir= ]",
54
+ "[Amardad= ]",
55
+ "[Shehrevar= ]",
56
+ "[Meher= ]",
57
+ "[Avan= ]",
58
+ "[Adar= ]",
59
+ "[Dae= ]",
60
+ "[Bahman= ]",
61
+ "[Aspandarmad= ]",
62
+ "[Gatha Days= ]"
63
+ ]
64
+ ],
65
+
66
+ # 日の暦注 ----------------------------
67
+ [When::BasicTypes::M17n,
68
+ "names:[day]",
69
+ [When::BasicTypes::M17n,
70
+ "names:[divinity]",
71
+ "[Hormazd= ]", # 01
72
+ "[Bahman= ]", # 02
73
+ "[Ardibehest= ]", # 03
74
+ "[Shehrevar= ]", # 04
75
+ "[Aspandarmad= ]", # 05
76
+ "[Khordad= ]", # 06
77
+ "[Amardad= ]", # 07
78
+ "[Daepadar= ]", # 08
79
+ "[Adar= ]", # 09
80
+ "[Avan= ]", # 10
81
+ "[Khorshed= ]", # 11
82
+ "[Mohor= ]", # 12
83
+ "[Tir= ]", # 13
84
+ "[Gosh= ]", # 14
85
+ "[Daepmeher= ]", # 15
86
+ "[Meher= ]", # 16
87
+ "[Srosh= ]", # 17
88
+ "[Rashne= ]", # 18
89
+ "[Fravardin= ]", # 19
90
+ "[Behram= ]", # 20
91
+ "[Ram= ]", # 21
92
+ "[Govad= ]", # 22
93
+ "[Daepdin= ]", # 23
94
+ "[Din= ]", # 24
95
+ "[Ashishvangh= ]", # 25
96
+ "[Ashtad= ]", # 26
97
+ "[Asman= ]", # 27
98
+ "[Zamyad= ]", # 28
99
+ "[Mahrespand= ]", # 29
100
+ "[Aneran= ]", # 30
101
+ "[Ahunavad= ]", # 31
102
+ "[Ushtavad= ]", # 32
103
+ "[Spentomad= ]", # 33
104
+ "[Vohukhshathra= ]", # 34
105
+ "[Vahishtoist= ]", # 35
106
+ "[intercalary day=]" # 36
107
+ ]
108
+ ]
109
+ ]]
110
+
111
+ # 暦注 - 日の名前
112
+ #
113
+ # @param [When::TM::CalDate] date
114
+ #
115
+ # @return [String]
116
+ #
117
+ def divinity(date)
118
+ y, m, d = date.cal_date
119
+ When.CalendarNote('Zoroastrian/Notes::day::divinity::*')[m <= 12 ? d-1 : d+29]
120
+ end
121
+ end
122
+
123
+ module CalendarTypes
124
+
125
+ #
126
+ # Zoroastrian Calendar
127
+ #
128
+ Zoroastrian = [CyclicTableBased, {
129
+ 'label' => 'Zoroastrian::Zoroastrian',
130
+ 'indices' => [
131
+ When.Index('ZoroastrianNotes::month::Month', {:unit =>13}),
132
+ When::Coordinates::DefaultDayIndex
133
+ ],
134
+ 'origin_of_MSC' => 1,
135
+ 'origin_of_LSC' => 1952063 + 5 - 365 * 1020,
136
+ 'epoch_in_CE' => 31,
137
+ 'rule_table' => {
138
+ 'T' => {'Rule' =>[365]},
139
+ 365 => {'Length'=>[30]*12+[5]}
140
+ },
141
+ 'note' => 'Zoroastrian'
142
+ }]
143
+
144
+ #
145
+ # Qadimi Calendar
146
+ #
147
+ Qadimi = [CyclicTableBased, {
148
+ 'label' => 'Zoroastrian::Qadimi',
149
+ 'indices' => [
150
+ When.Index('ZoroastrianNotes::month::Month', {:unit =>13}),
151
+ When::Coordinates::DefaultDayIndex
152
+ ],
153
+ 'origin_of_MSC' => 1,
154
+ 'origin_of_LSC' => 1952063,
155
+ 'epoch_in_CE' => 31,
156
+ 'rule_table' => {
157
+ 'T' => {'Rule' =>[365]},
158
+ 365 => {'Length'=>[30]*12+[5]}
159
+ },
160
+ 'note' => 'Zoroastrian'
161
+ }]
162
+
163
+ #
164
+ # Shahanshahi Calendar
165
+ #
166
+ Shahanshahi = [CyclicTableBased, {
167
+ 'label' => 'Zoroastrian::Shahanshahi',
168
+ 'indices' => [
169
+ When.Index('ZoroastrianNotes::month::Month', {:unit =>13}),
170
+ When::Coordinates::DefaultDayIndex
171
+ ],
172
+ 'origin_of_MSC' => 1,
173
+ 'origin_of_LSC' => 1952063 + 30,
174
+ 'epoch_in_CE' => 31,
175
+ 'rule_table' => {
176
+ 'T' => {'Rule' =>[365]},
177
+ 365 => {'Length'=>[30]*12+[5]}
178
+ },
179
+ 'note' => 'Zoroastrian'
180
+ }]
181
+
182
+ #
183
+ # Fasli Calendar
184
+ #
185
+ Fasli = [{'Epoch'=>{
186
+ 'ZRE'=>{'origin_of_MSC'=>1737},
187
+ 'YZ' =>{'origin_of_MSC'=>-630}
188
+ }}, Bahai, {
189
+ 'label' => 'Zoroastrian::Fasli',
190
+ 'indices' => [
191
+ When.Index('ZoroastrianNotes::month::Month', {:unit =>13}),
192
+ When::Coordinates::DefaultDayIndex
193
+ ],
194
+ 'origin_of_MSC' => -630,
195
+ 'epoch_in_CE' => 0,
196
+ 'rule_table' => {
197
+ 365 => {'Length'=>[30] * 12 + [5]},
198
+ 366 => {'Length'=>[30] * 12 + [6]}
199
+ },
200
+ 'note' => 'Zoroastrian'
201
+ }]
202
+ end
203
+ end
@@ -1,681 +1,707 @@
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
- #
9
- # 標準的な時刻系の定義
10
- #
11
- module When::TimeStandard
12
-
13
- # TT(Terrestrial Time) - UTC(Universal Time, Coordinated) at 1970-01-01T00:00:00Z
14
- DeltaT0 = (40 + 377.0/2048) * When::TM::Duration::SECOND
15
-
16
- TAI_UTC = # http://maia.usno.navy.mil/ser7/tai-utc.dat
17
- [[2437300.5, 1.422818, 37300.0, 0.001296 ],
18
- [2437512.5, 1.372818, 37300.0, 0.001296 ],
19
- [2437665.5, 1.845858, 37665.0, 0.0011232],
20
- [2438334.5, 1.945858, 37665.0, 0.0011232],
21
- [2438395.5, 3.24013, 38761.0, 0.001296 ],
22
- [2438486.5, 3.34013, 38761.0, 0.001296 ],
23
- [2438639.5, 3.44013, 38761.0, 0.001296 ],
24
- [2438761.5, 3.54013, 38761.0, 0.001296 ],
25
- [2438820.5, 3.64013, 38761.0, 0.001296 ],
26
- [2438942.5, 3.74013, 38761.0, 0.001296 ],
27
- [2439004.5, 3.84013, 38761.0, 0.001296 ],
28
- [2439126.5, 4.31317, 39126.0, 0.002592 ],
29
- [2439887.5, 4.21317, 39126.0, 0.002592 ],
30
- [2441317.5, 10.0],
31
- [2441499.5, 11.0],
32
- [2441683.5, 12.0],
33
- [2442048.5, 13.0],
34
- [2442413.5, 14.0],
35
- [2442778.5, 15.0],
36
- [2443144.5, 16.0],
37
- [2443509.5, 17.0],
38
- [2443874.5, 18.0],
39
- [2444239.5, 19.0],
40
- [2444786.5, 20.0],
41
- [2445151.5, 21.0],
42
- [2445516.5, 22.0],
43
- [2446247.5, 23.0],
44
- [2447161.5, 24.0],
45
- [2447892.5, 25.0],
46
- [2448257.5, 26.0],
47
- [2448804.5, 27.0],
48
- [2449169.5, 28.0],
49
- [2449534.5, 29.0],
50
- [2450083.5, 30.0],
51
- [2450630.5, 31.0],
52
- [2451179.5, 32.0],
53
- [2453736.5, 33.0],
54
- [2454832.5, 34.0],
55
- [2456109.5, 35.0]]
56
-
57
- DeltaT = [ 63.467, # 1999
58
- 63.827, 64.092, 64.300, 64.473, 64.573, 64.689, 64.846, 65.145, 65.456, 65.779, # 2000-
59
- 66.070, 66.324, 66.603, 66.909 # 2010-
60
- ]
61
-
62
- class << self
63
- # When::TimeStandard Module のグローバルな設定を行う
64
- #
65
- # @param [String] leap_seconds http://maia.usno.navy.mil/ser7/tai-utc.dat 形式のファイルのファイルパス
66
- # @param [Array<Array<Numeric>>] leap_seconds 閏秒の挿入記録 [ [ JD, TAI-UTC, (MJD, OFFSET) ] ]
67
- # [ JD - 閏秒を挿入した日時のユリウス日 ]
68
- # [ TAI-UTC - 閏秒を挿入後の TAI と UTC の差 ]
69
- # [ MJD - 周波数オフセットの基準となる日時の修正ユリウス日 ]
70
- # [ OFFSET - 周波数オフセット値 ]
71
- #
72
- # @return [void]
73
- #
74
- # @note
75
- # 本メソッドでマルチスレッド対応の管理変数の初期化を行っている。
76
- # このため、本メソッド自体はスレッドセーフでない。
77
- #
78
- def _setup_(leap_seconds=nil)
79
- @_lock_ = Mutex.new if When.multi_thread
80
- leap_seconds ||= TAI_UTC
81
- @leap_seconds =
82
- if leap_seconds.kind_of?(String)
83
- OpenURI
84
- open(leap_seconds) do |file|
85
- file.read.split(/[\n\r]+/).map { |line|
86
- line.split(/[^\d.]+/)[3..6].map {|d| d.to_f}
87
- }.reverse
88
- end
89
- else
90
- leap_seconds.reverse
91
- end
92
- end
93
-
94
- # 設定情報を取得する
95
- #
96
- # @return [Hash] 設定情報
97
- #
98
- def _setup_info
99
- {:leap_seconds => _leap_seconds}
100
- end
101
-
102
- # @private
103
- # 閏秒の挿入記録を取得する
104
- def _leap_seconds
105
- @leap_seconds ||= TAI_UTC.reverse
106
- end
107
-
108
- # 処理系が閏秒を無視しているか否か
109
- # @private
110
- def _is_systemtime_universal?
111
- @is_systemtime_universal = ((Time.utc(1976).to_i - Time.utc(1975).to_i) % 86400 == 0) if @is_systemtime_universal == nil
112
- @is_systemtime_universal
113
- end
114
-
115
- # ΔT
116
- #
117
- # @param [Numeric] jd_utc ユリウス日(Universal Time, Coordinated)
118
- #
119
- # @return [Numeric] (dynamical_time - universal_time) / second
120
- # 1/2048 second(≒0.5ms)未満を四捨五入
121
- #
122
- def delta_t(jd_utc)
123
- (delta_t_coordinated(jd_utc) * 4096 + 1).floor / 4096.0
124
- end
125
- alias :deltaT :delta_t
126
-
127
- # ΔT - 閏秒による(TT-UTC)
128
- #
129
- # @param [Numeric] jd_utc ユリウス日(Universal Time, Coordinated)
130
- #
131
- # @return [Numeric] (Terrestrial Time - Universal Time, Coordinated) / second
132
- #
133
- def delta_t_coordinated(jd_utc)
134
- list = _leap_seconds
135
- list.each do |v|
136
- if jd_utc >= v[0]
137
- result = 32.184 + v[1]
138
- result += (jd_utc - (2400000.5 + v[2])) * v[3] unless (v[3]||0) == 0
139
- return result
140
- end
141
- end
142
- delta_t_observed(jd_utc)
143
- end
144
-
145
- # ΔT - 観測による(TT-UT1) mix of Table and NASA
146
- #
147
- # @param [Numeric] jd_utc ユリウス日(Universal Time, Coordinated)
148
- #
149
- # @return [Numeric] (Terrestrial Time - Universal Time 1) / second
150
- #
151
- def delta_t_observed(jd_utc)
152
- year = (jd_utc - When::Ephemeris::EPOCH2000)/When::Ephemeris::JYEAR + 2000 # 0年からの経過世紀
153
- return delta_t_observed_poly(year) unless 2000 <= year && year < 2050
154
- return delta_t_observed_poly(year) + DeltaThreshold * (year - 2050.0) / (YearThreshold - 2050.0) if year >= YearThreshold
155
-
156
- i = (year-1999.0).floor # 1999年からの経過年(整数)
157
- n = year % 1
158
- d0 = DeltaT[i+0] - DeltaT[i-1]
159
- d1 = DeltaT[i+1] - DeltaT[i+0]
160
- d2 = DeltaT[i+2] - DeltaT[i+1]
161
- d10 = d1 - d0
162
- d21 = d2 - d1
163
- d210 = d21 - d10
164
- DeltaT[i] + n*d1 + n*(n-1.0)/4.0*(d10+d21) + n*(n-1.0)*(n-0.5)/6.0*d210
165
- end
166
-
167
- # ΔT - 観測による(TT-UT1) from http://eclipse.gsfc.nasa.gov/SEhelp/deltatpoly2004.html
168
- #
169
- # @param [Numeric] jd_utc ユリウス日(Universal Time, Coordinated)
170
- #
171
- # @return [Numeric] (Terrestrial Time - Universal Time 1) / second
172
- #
173
- def delta_t_observed_nasa(jd_utc)
174
- delta_t_observed_poly((jd_utc - When::Ephemeris::EPOCH2000)/When::Ephemeris::JYEAR + 2000.0) # 0年からの経過年
175
- end
176
-
177
- # 多項式による近似
178
- def delta_t_observed_poly(year)
179
- u = (year-1820)/100
180
-
181
- # 2150 ... 3000
182
- if year >= 2150
183
- -20 + 32 * u**2
184
-
185
- # 2050 ... 2150
186
- elsif year >= 2050
187
- -20 + 32 * u**2 - 0.5628 * (2150 - year)
188
-
189
- # 2005 ... 2050
190
- elsif year >= 2005
191
- t = year - 2000
192
- 62.92 + 0.32217 * t + 0.005589 * t**2
193
-
194
- # 1986 ... 2005
195
- elsif year >= 1986
196
- t = year - 2000
197
- 63.86 + 0.3345 * t - 0.060374 * t**2 + 0.0017275 * t**3 + 0.000651814 * t**4 + 0.00002373599 * t**5
198
-
199
- # 1961 ... 1986
200
- elsif year >= 1961
201
- t = year - 1975
202
- 45.45 + 1.067*t - t**2/260 - t**3 / 718
203
-
204
- # 1941 ... 1961
205
- elsif year >= 1941
206
- t = year - 1950
207
- 29.07 + 0.407*t - t**2/233 + t**3 / 2547
208
-
209
- # 1920 ... 1941
210
- elsif year >= 1920
211
- t = year - 1920
212
- 21.20 + 0.84493*t - 0.076100 * t**2 + 0.0020936 * t**3
213
-
214
- # 1900 ... 1920
215
- elsif year >= 1900
216
- t = year - 1900
217
- -2.79 + 1.494119 * t - 0.0598939 * t**2 + 0.0061966 * t**3 - 0.000197 * t**4
218
-
219
- # 1860 ... 1900
220
- elsif year >= 1860
221
- t = year - 1860
222
- 7.62 + 0.5737 * t - 0.251754 * t**2 + 0.01680668 * t**3 - 0.0004473624 * t**4 + t**5 / 233174
223
-
224
- # 1800 ... 1860
225
- elsif year >= 1800
226
- t = year - 1800
227
- 13.72 - 0.332447 * t + 0.0068612 * t**2 + 0.0041116 * t**3 - 0.00037436 * t**4 + 0.0000121272 * t**5 - 0.0000001699 * t**6 + 0.000000000875 * t**7
228
-
229
- # 1700 ... 1800
230
- elsif year >= 1700
231
- t = year - 1700
232
- 8.83 + 0.1603 * t - 0.0059285 * t**2 + 0.00013336 * t**3 - t**4 / 1174000
233
-
234
- # 1600 ... 1700
235
- elsif year >= 1600
236
- t = year - 1600
237
- 120 - 0.9808 * t - 0.01532 * t**2 + t**3 / 7129
238
-
239
- # 500 ... 1600
240
- elsif year >= 500
241
- u = (year - 1000) / 100
242
- 1574.2 - 556.01 * u + 71.23472 * u**2 + 0.319781 * u**3 - 0.8503463 * u**4 - 0.005050998 * u**5 + 0.0083572073 * u**6
243
-
244
- # -500 ... 500
245
- elsif year >= -500
246
- u = year / 100
247
- 10583.6 - 1014.41 * u + 33.78311 * u**2 - 5.952053 * u**3 - 0.1798452 * u**4 + 0.022174192 * u**5 + 0.0090316521 * u**6
248
-
249
- # ... -500
250
- else
251
- -20 + 32 * u**2
252
- end
253
- end
254
- private :delta_t_observed_poly
255
-
256
- # universal time を dynamical time に変換する
257
- #
258
- # @param [Numeric] time universal time
259
- #
260
- # @return [Numeric] dynamical time
261
- #
262
- def to_dynamical_time(time)
263
- return time unless -Float::MAX/4 < time && time < Float::MAX/4
264
- jd_utc = When::TM::JulianDate._t_to_d(time * 1)
265
- +time + delta_t(jd_utc) * When::TM::Duration::SECOND
266
- end
267
-
268
- # dynamical time を universal time に変換する
269
- #
270
- # @param [Numeric] time dynamical time
271
- #
272
- # @return [Numeric] universal time
273
- #
274
- def from_dynamical_time(time)
275
- return time unless -Float::MAX/4 < time && time < Float::MAX/4
276
- jd_tt = When::TM::JulianDate._t_to_d(time)
277
- utc = time - delta_t(jd_tt) * When::TM::Duration::SECOND
278
- diff = time - to_dynamical_time(utc)
279
- return utc if diff == 0 # 間に閏秒なし
280
- utc += diff
281
- diff = time - to_dynamical_time(utc)
282
- return utc if diff == 0 # 間に閏秒なし
283
- return When::Coordinates::LeapSeconds.new(utc+diff, -diff, When::TM::Duration::SECOND)
284
- end
285
-
286
- # Time オブジェクトを dynamical time に変換する
287
- #
288
- # @param [::Time] time
289
- #
290
- # @return [Numeric] [dynamical time
291
- #
292
- def from_time_object(time)
293
- time = time.to_f * When::TM::Duration::SECOND
294
- _is_systemtime_universal? ? to_dynamical_time(time) : time + DeltaT0
295
- end
296
-
297
- # dynamical time を Time オブジェクトに変換する
298
- #
299
- # @param [Numeric] time dynamical time
300
- #
301
- # @return [::Time]
302
- #
303
- def to_time_object(time)
304
- time = _is_systemtime_universal? ? from_dynamical_time(time) : time - DeltaT0
305
- ::Time.at(+time / When::TM::Duration::SECOND)
306
- end
307
- end
308
-
309
- # @private
310
- YearThreshold = 1997.0 + DeltaT.size
311
-
312
- # @private
313
- DeltaThreshold = DeltaT[-2] - delta_t_observed_poly(YearThreshold)
314
-
315
- #
316
- # When::TM::Calendar のための TimeBasis の初期化
317
- #
318
- # @private
319
- module TimeBasis
320
-
321
- # @private
322
- attr_reader :_time_basis
323
-
324
- module FixedTimeBasis
325
-
326
- private
327
-
328
- # 太陽黄経のための日付境界のオフセットを反映した通日
329
- #
330
- # @param [Numeric] t ユリウス日(Terrestrial Time)
331
- #
332
- # @return [Integer]
333
- #
334
- def solar_sdn(t)
335
- (t + 0.5 + @_time_basis_offset[0]).floor
336
- end
337
-
338
- # 月の位相のための日付境界のオフセットを反映した通日
339
- #
340
- # @param [Numeric] t ユリウス日(Terrestrial Time)
341
- #
342
- # @return [Integer]
343
- #
344
- def lunar_sdn(t)
345
- (t + 0.5 + @_time_basis_offset[-1]).floor
346
- end
347
- end
348
-
349
- module ApparentTimeBasis
350
-
351
- private
352
-
353
- # 太陽黄経のための日付境界のオフセットを反映した通日
354
- #
355
- # @param [Numeric] t ユリウス日(Terrestrial Time)
356
- #
357
- # @return [Integer]
358
- #
359
- def solar_sdn(t)
360
- time_basis.time_standard.from_dynamical_date(t + 0.5 + @_time_basis_offset[0]).floor
361
- end
362
-
363
- # 月の位相のための日付境界のオフセットを反映した通日
364
- #
365
- # @param [Numeric] t ユリウス日(Terrestrial Time)
366
- #
367
- # @return [Integer]
368
- #
369
- def lunar_sdn(t)
370
- time_basis.time_standard.from_dynamical_date(t + 0.5 + @_time_basis_offset[-1]).floor
371
- end
372
- end
373
-
374
- #
375
- # When::TM::Calendar のための TimeBasis の初期化
376
- #
377
- def _normalize_time_basis
378
-
379
- @_time_basis ||= @time_basis || (@location ? @location.long / When::Coordinates::Spatial::DEGREE * 240 : When::UTC)
380
- @_time_basis = When::Locale._split(@_time_basis) if @_time_basis.kind_of?(String)
381
- @_time_basis = [@_time_basis] unless @_time_basis.kind_of?(Array)
382
- @_time_basis = @_time_basis.map {|clock| When.Clock(clock)}
383
- @_time_basis_offset = @_time_basis.map {|clock| -clock.universal_time / When::TM::Duration::DAY}
384
-
385
- @time_basis = @_time_basis[0] if @time_basis
386
-
387
- if @_time_basis[0].time_standard.kind_of?(LocalApparentTime)
388
- extend ApparentTimeBasis
389
- else
390
- extend FixedTimeBasis
391
- end
392
- end
393
- end
394
-
395
- #
396
- # 時刻系のひながた
397
- #
398
- class TimeStandard < When::BasicTypes::Object
399
-
400
- include When::TimeStandard
401
-
402
- Ratio = 1.0
403
-
404
- # universal time を dynamical time に変換する
405
- #
406
- # @param [Numeric] time universal time
407
- #
408
- # @return [Numeric] dynamical time
409
- #
410
- def to_dynamical_time(time)
411
- When::TimeStandard.to_dynamical_time(time)
412
- end
413
-
414
- # dynamical time universal time に変換する
415
- #
416
- # @param [Numeric] time dynamical time
417
- #
418
- # @return [Numeric] universal time
419
- #
420
- def from_dynamical_time(time)
421
- When::TimeStandard.from_dynamical_time(time)
422
- end
423
-
424
- # 当該時刻系の日付を dynamical date に変換する
425
- #
426
- # @param [Numeric] date 当該時刻系の日付
427
- #
428
- # @return [Numeric] dynamical date
429
- #
430
- def to_dynamical_date(date)
431
- When::TM::JulianDate._t_to_d(
432
- to_dynamical_time(
433
- When::TM::JulianDate._d_to_t(date)))
434
- end
435
-
436
- # dynamical date を当該時刻系の日付に変換する
437
- #
438
- # @param [Numeric] date dynamical date
439
- #
440
- # @return [Numeric] 当該時刻系の日付
441
- #
442
- def from_dynamical_date(date)
443
- When::TM::JulianDate._t_to_d(
444
- from_dynamical_time(
445
- When::TM::JulianDate._d_to_t(date)))
446
- end
447
-
448
- # Time オブジェクトを universal time に変換する
449
- #
450
- # @param [::Time] time
451
- #
452
- # @return [Numeric] universal time
453
- #
454
- def from_time_object(time)
455
- from_dynamical_time(When::TimeStandard.from_time_object(time))
456
- end
457
-
458
- # universal time を Time オブジェクトに変換する
459
- #
460
- # @param [Numeric] time universal time
461
- #
462
- # @return [::Time]
463
- #
464
- def to_time_object(time)
465
- When::TimeStandard.to_time_object(to_dynamical_time(time))
466
- end
467
-
468
- # 当該時刻系に閏秒があるか?
469
- #
470
- # @return [Boolean] - false 閏秒なし
471
- #
472
- def has_leap?
473
- false
474
- end
475
-
476
- # 時間の歩度
477
- #
478
- # @return [Numeric]
479
- #
480
- def rate_of_clock
481
- self.class::Ratio
482
- end
483
-
484
- private
485
-
486
- def _normalize(args=[], options={})
487
- end
488
- end
489
-
490
- #
491
- # 協定世界時
492
- #
493
- class UniversalTime < TimeStandard
494
-
495
- # Time オブジェクトを universal time に変換する
496
- #
497
- # @param [::Time] time
498
- #
499
- # @return [Numeric] universal time
500
- #
501
- def from_time_object(time)
502
- result = time.to_f * When::TM::Duration::SECOND
503
- return result if When::TimeStandard._is_systemtime_universal?
504
- from_dynamical_time(result + DeltaT0)
505
- end
506
-
507
- # universal time を Time オブジェクトに変換する
508
- #
509
- # @param [Numeric] time universal time
510
- #
511
- # @return [::Time]
512
- #
513
- def to_time_object(time)
514
- time = to_dynamical_time(time) - DeltaT0 unless When::TimeStandard._is_systemtime_universal?
515
- ::Time.at(+time / When::TM::Duration::SECOND)
516
- end
517
-
518
- # 当該時刻系に閏秒があるか?
519
- #
520
- # @return [Boolean] - true 閏秒あり
521
- #
522
- def has_leap?
523
- true
524
- end
525
- end
526
-
527
- #
528
- # 地方平均太陽時
529
- #
530
- class LocalMeanTime < TimeStandard
531
-
532
- # local mean time dynamical time に変換する
533
- #
534
- # @param [Numeric] time local mean time
535
- #
536
- # @return [Numeric] dynamical time
537
- #
538
- def to_dynamical_time(time)
539
- super(time - When::TM::Duration::DAY * @location.long / (360.0 * When::Coordinates::Spatial::DEGREE))
540
- end
541
-
542
- # dynamical time を local mean time に変換する
543
- #
544
- # @param [Numeric] time dynamical time
545
- #
546
- # @return [Numeric] local mean time
547
- #
548
- def from_dynamical_time(time)
549
- super(time) + When::TM::Duration::DAY * @location.long / (360.0 * When::Coordinates::Spatial::DEGREE)
550
- end
551
-
552
- private
553
-
554
- # オブジェクトの正規化
555
- def _normalize(args=[], options={})
556
- @location = When.Resource(@location || '_l:long=0&lat=0')
557
- super
558
- end
559
- end
560
-
561
- #
562
- # 地方真太陽時
563
- #
564
- class LocalApparentTime < TimeStandard
565
-
566
- # local apparent time を dynamical time に変換する
567
- #
568
- # @param [Numeric] time local apparent time
569
- #
570
- # @return [Numeric] dynamical time
571
- #
572
- def to_dynamical_time(time)
573
- date = When::TM::JulianDate._t_to_d(time) - @location.long / (360.0 * When::Coordinates::Spatial::DEGREE)
574
- diff = 0
575
- 2.times do
576
- diff = @datum.equation_of_time(date-diff)
577
- end
578
- super(When::TM::JulianDate._d_to_t(date-diff))
579
- end
580
-
581
- # dynamical time local apparent time に変換する
582
- #
583
- # @param [Numeric] time dynamical time
584
- #
585
- # @return [Numeric] local apparent time
586
- #
587
- def from_dynamical_time(time)
588
- super(time) + When::TM::Duration::DAY * (@location.long / (360.0 * When::Coordinates::Spatial::DEGREE) +
589
- @datum.equation_of_time(When::TM::JulianDate._t_to_d(time)))
590
- end
591
-
592
- private
593
-
594
- # オブジェクトの正規化
595
- def _normalize(args=[], options={})
596
- @location ||= '_l:long=0&lat=0'
597
- @location = When.Resource(@location) if @location.kind_of?(String)
598
- @datum = When.Resource(@datum || '_ep:Earth' )
599
- super
600
- end
601
- end
602
-
603
- #
604
- # 不定時法
605
- #
606
- class TemporalHourSystem < LocalApparentTime
607
-
608
- # @private
609
- alias :_to_dynamical_time :to_dynamical_time
610
- # @private
611
- alias :_from_dynamical_time :from_dynamical_time
612
-
613
- # temporal hour system を dynamical time に変換する
614
- #
615
- # @param [Numeric] time temporal hour system
616
- #
617
- # @return [Numeric] dynamical time
618
- #
619
- def to_dynamical_time(time)
620
- noon, frac = When::TM::JulianDate._t_to_d(time).divmod(1)
621
-
622
- r, *p =
623
- case (frac * 4).floor
624
- when 3 ; [-1.5, [noon+1, -1],[noon+1, +1]] # morning
625
- when 0 ; [+0.5, [noon, -1],[noon, +1]] # afternoon
626
- else ; [-0.5, [noon, +1],[noon+1, -1]] # night
627
- end
628
-
629
- s, e = p.map {|v|
630
- When::TM::JulianDate._d_to_t(@formula.day_event(_to_dynamical_date(v[0]), v[1], When.Resource('_ep:Sun'), @height))
631
- }
632
-
633
- s + (e - s) * (frac * 2 + r)
634
- end
635
-
636
- # dynamical time を temporal hour system に変換する
637
- #
638
- # @param [Numeric] time dynamical time
639
- #
640
- # @return [Numeric] temporal hour system
641
- #
642
- def from_dynamical_time(time)
643
- date = When::TM::JulianDate._t_to_d(time)
644
-
645
- d, t = [-1, +1].map {|v| @formula.day_event(date, v, When.Resource('_ep:Sun'), @height)}
646
-
647
- if date < d # after midnight
648
- t = @formula.sunset(date-1, @height)
649
- f = (date - t) / (d - t) / 2 - 0.25
650
-
651
- elsif date > t # before midnight
652
- d = @formula.sunrise(date+1, @height)
653
- f = (date - t) / (d - t) / 2 - 0.25
654
-
655
- else # day time
656
- f = (date - d) / (t - d) / 2 + 0.25
657
- end
658
-
659
- When::TM::JulianDate._d_to_t(_from_dynamical_date(d).floor + 0.5 + f)
660
- end
661
-
662
- private
663
-
664
- # オブジェクトの正規化
665
- def _normalize(args=[], options={})
666
- @formula = When::Ephemeris::Formula.new({:location=>@location})
667
- @height ||= 'T'
668
- super
669
- end
670
-
671
- # 単位を「日」にした to_dynamical_time
672
- def _to_dynamical_date(date)
673
- When::TM::JulianDate._t_to_d(_to_dynamical_time(When::TM::JulianDate._d_to_t(date)))
674
- end
675
-
676
- # 単位を「日」にした from_dynamical_time
677
- def _from_dynamical_date(date)
678
- When::TM::JulianDate._t_to_d(_from_dynamical_time(When::TM::JulianDate._d_to_t(date)))
679
- end
680
- end
681
- end
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
+ #
9
+ # 標準的な時刻系の定義
10
+ #
11
+ module When::TimeStandard
12
+
13
+ # TT(Terrestrial Time) - UTC(Universal Time, Coordinated) at 1970-01-01T00:00:00Z
14
+ DeltaT0 = (40 + 377.0/2048) * When::TM::Duration::SECOND
15
+
16
+ TAI_UTC = # http://maia.usno.navy.mil/ser7/tai-utc.dat
17
+ [[2437300.5, 1.422818, 37300.0, 0.001296 ],
18
+ [2437512.5, 1.372818, 37300.0, 0.001296 ],
19
+ [2437665.5, 1.845858, 37665.0, 0.0011232],
20
+ [2438334.5, 1.945858, 37665.0, 0.0011232],
21
+ [2438395.5, 3.24013, 38761.0, 0.001296 ],
22
+ [2438486.5, 3.34013, 38761.0, 0.001296 ],
23
+ [2438639.5, 3.44013, 38761.0, 0.001296 ],
24
+ [2438761.5, 3.54013, 38761.0, 0.001296 ],
25
+ [2438820.5, 3.64013, 38761.0, 0.001296 ],
26
+ [2438942.5, 3.74013, 38761.0, 0.001296 ],
27
+ [2439004.5, 3.84013, 38761.0, 0.001296 ],
28
+ [2439126.5, 4.31317, 39126.0, 0.002592 ],
29
+ [2439887.5, 4.21317, 39126.0, 0.002592 ],
30
+ [2441317.5, 10.0],
31
+ [2441499.5, 11.0],
32
+ [2441683.5, 12.0],
33
+ [2442048.5, 13.0],
34
+ [2442413.5, 14.0],
35
+ [2442778.5, 15.0],
36
+ [2443144.5, 16.0],
37
+ [2443509.5, 17.0],
38
+ [2443874.5, 18.0],
39
+ [2444239.5, 19.0],
40
+ [2444786.5, 20.0],
41
+ [2445151.5, 21.0],
42
+ [2445516.5, 22.0],
43
+ [2446247.5, 23.0],
44
+ [2447161.5, 24.0],
45
+ [2447892.5, 25.0],
46
+ [2448257.5, 26.0],
47
+ [2448804.5, 27.0],
48
+ [2449169.5, 28.0],
49
+ [2449534.5, 29.0],
50
+ [2450083.5, 30.0],
51
+ [2450630.5, 31.0],
52
+ [2451179.5, 32.0],
53
+ [2453736.5, 33.0],
54
+ [2454832.5, 34.0],
55
+ [2456109.5, 35.0]]
56
+
57
+ DeltaT = [ 63.467, # 1999
58
+ 63.827, 64.092, 64.300, 64.473, 64.573, 64.689, 64.846, 65.145, 65.456, 65.779, # 2000-
59
+ 66.070, 66.324, 66.603, 66.909 # 2010-
60
+ ]
61
+
62
+ class << self
63
+ # When::TimeStandard Module のグローバルな設定を行う
64
+ #
65
+ # @param [String] leap_seconds http://maia.usno.navy.mil/ser7/tai-utc.dat 形式のファイルのファイルパス
66
+ # @param [Array<Array<Numeric>>] leap_seconds 閏秒の挿入記録 [ [ JD, TAI-UTC, (MJD, OFFSET) ] ]
67
+ # [ JD - 閏秒を挿入した日時のユリウス日 ]
68
+ # [ TAI-UTC - 閏秒を挿入後の TAI と UTC の差 ]
69
+ # [ MJD - 周波数オフセットの基準となる日時の修正ユリウス日 ]
70
+ # [ OFFSET - 周波数オフセット値 ]
71
+ #
72
+ # @return [void]
73
+ #
74
+ # @note
75
+ # 本メソッドでマルチスレッド対応の管理変数の初期化を行っている。
76
+ # このため、本メソッド自体はスレッドセーフでない。
77
+ #
78
+ def _setup_(leap_seconds=nil)
79
+ @_lock_ = Mutex.new if When.multi_thread
80
+ leap_seconds ||= TAI_UTC
81
+ @leap_seconds =
82
+ if leap_seconds.kind_of?(String)
83
+ OpenURI
84
+ open(leap_seconds) do |file|
85
+ file.read.split(/[\n\r]+/).map { |line|
86
+ line.split(/[^\d.]+/)[3..6].map {|d| d.to_f}
87
+ }.reverse
88
+ end
89
+ else
90
+ leap_seconds.reverse
91
+ end
92
+ end
93
+
94
+ # 設定情報を取得する
95
+ #
96
+ # @return [Hash] 設定情報
97
+ #
98
+ def _setup_info
99
+ {:leap_seconds => _leap_seconds}
100
+ end
101
+
102
+ # @private
103
+ # 閏秒の挿入記録を取得する
104
+ def _leap_seconds
105
+ @leap_seconds ||= TAI_UTC.reverse
106
+ end
107
+
108
+ # 処理系が閏秒を無視しているか否か
109
+ # @private
110
+ def _is_systemtime_universal?
111
+ @is_systemtime_universal = ((Time.utc(1976).to_i - Time.utc(1975).to_i) % 86400 == 0) if @is_systemtime_universal == nil
112
+ @is_systemtime_universal
113
+ end
114
+
115
+ # ΔT
116
+ #
117
+ # @param [Numeric] jd_utc ユリウス日(Universal Time, Coordinated)
118
+ #
119
+ # @return [Numeric] (dynamical_time - universal_time) / second
120
+ # 1/2048 second(≒0.5ms)未満を四捨五入
121
+ #
122
+ def delta_t(jd_utc)
123
+ (delta_t_coordinated(jd_utc) * 4096 + 1).floor / 4096.0
124
+ end
125
+ alias :deltaT :delta_t
126
+
127
+ # ΔT - 閏秒による(TT-UTC)
128
+ #
129
+ # @param [Numeric] jd_utc ユリウス日(Universal Time, Coordinated)
130
+ #
131
+ # @return [Numeric] (Terrestrial Time - Universal Time, Coordinated) / second
132
+ #
133
+ def delta_t_coordinated(jd_utc)
134
+ list = _leap_seconds
135
+ list.each do |v|
136
+ if jd_utc >= v[0]
137
+ result = 32.184 + v[1]
138
+ result += (jd_utc - (2400000.5 + v[2])) * v[3] unless (v[3]||0) == 0
139
+ return result
140
+ end
141
+ end
142
+ delta_t_observed(jd_utc)
143
+ end
144
+
145
+ # ΔT - 観測による(TT-UT1) mix of Table and NASA
146
+ #
147
+ # @param [Numeric] jd_utc ユリウス日(Universal Time, Coordinated)
148
+ #
149
+ # @return [Numeric] (Terrestrial Time - Universal Time 1) / second
150
+ #
151
+ def delta_t_observed(jd_utc)
152
+ year = (jd_utc - When::Ephemeris::EPOCH2000)/When::Ephemeris::JYEAR + 2000 # 0年からの経過世紀
153
+ return delta_t_observed_poly(year) unless 2000 <= year && year < 2050
154
+ return delta_t_observed_poly(year) + DeltaThreshold * (year - 2050.0) / (YearThreshold - 2050.0) if year >= YearThreshold
155
+
156
+ i = (year-1999.0).floor # 1999年からの経過年(整数)
157
+ n = year % 1
158
+ d0 = DeltaT[i+0] - DeltaT[i-1]
159
+ d1 = DeltaT[i+1] - DeltaT[i+0]
160
+ d2 = DeltaT[i+2] - DeltaT[i+1]
161
+ d10 = d1 - d0
162
+ d21 = d2 - d1
163
+ d210 = d21 - d10
164
+ DeltaT[i] + n*d1 + n*(n-1.0)/4.0*(d10+d21) + n*(n-1.0)*(n-0.5)/6.0*d210
165
+ end
166
+
167
+ # ΔT - 観測による(TT-UT1) from http://eclipse.gsfc.nasa.gov/SEhelp/deltatpoly2004.html
168
+ #
169
+ # @param [Numeric] jd_utc ユリウス日(Universal Time, Coordinated)
170
+ #
171
+ # @return [Numeric] (Terrestrial Time - Universal Time 1) / second
172
+ #
173
+ def delta_t_observed_nasa(jd_utc)
174
+ delta_t_observed_poly((jd_utc - When::Ephemeris::EPOCH2000)/When::Ephemeris::JYEAR + 2000.0) # 0年からの経過年
175
+ end
176
+
177
+ # 多項式による近似
178
+ def delta_t_observed_poly(year)
179
+ u = (year-1820)/100
180
+
181
+ # 2150 ... 3000
182
+ if year >= 2150
183
+ -20 + 32 * u**2
184
+
185
+ # 2050 ... 2150
186
+ elsif year >= 2050
187
+ -20 + 32 * u**2 - 0.5628 * (2150 - year)
188
+
189
+ # 2005 ... 2050
190
+ elsif year >= 2005
191
+ t = year - 2000
192
+ 62.92 + 0.32217 * t + 0.005589 * t**2
193
+
194
+ # 1986 ... 2005
195
+ elsif year >= 1986
196
+ t = year - 2000
197
+ 63.86 + 0.3345 * t - 0.060374 * t**2 + 0.0017275 * t**3 + 0.000651814 * t**4 + 0.00002373599 * t**5
198
+
199
+ # 1961 ... 1986
200
+ elsif year >= 1961
201
+ t = year - 1975
202
+ 45.45 + 1.067*t - t**2/260 - t**3 / 718
203
+
204
+ # 1941 ... 1961
205
+ elsif year >= 1941
206
+ t = year - 1950
207
+ 29.07 + 0.407*t - t**2/233 + t**3 / 2547
208
+
209
+ # 1920 ... 1941
210
+ elsif year >= 1920
211
+ t = year - 1920
212
+ 21.20 + 0.84493*t - 0.076100 * t**2 + 0.0020936 * t**3
213
+
214
+ # 1900 ... 1920
215
+ elsif year >= 1900
216
+ t = year - 1900
217
+ -2.79 + 1.494119 * t - 0.0598939 * t**2 + 0.0061966 * t**3 - 0.000197 * t**4
218
+
219
+ # 1860 ... 1900
220
+ elsif year >= 1860
221
+ t = year - 1860
222
+ 7.62 + 0.5737 * t - 0.251754 * t**2 + 0.01680668 * t**3 - 0.0004473624 * t**4 + t**5 / 233174
223
+
224
+ # 1800 ... 1860
225
+ elsif year >= 1800
226
+ t = year - 1800
227
+ 13.72 - 0.332447 * t + 0.0068612 * t**2 + 0.0041116 * t**3 - 0.00037436 * t**4 + 0.0000121272 * t**5 - 0.0000001699 * t**6 + 0.000000000875 * t**7
228
+
229
+ # 1700 ... 1800
230
+ elsif year >= 1700
231
+ t = year - 1700
232
+ 8.83 + 0.1603 * t - 0.0059285 * t**2 + 0.00013336 * t**3 - t**4 / 1174000
233
+
234
+ # 1600 ... 1700
235
+ elsif year >= 1600
236
+ t = year - 1600
237
+ 120 - 0.9808 * t - 0.01532 * t**2 + t**3 / 7129
238
+
239
+ # 500 ... 1600
240
+ elsif year >= 500
241
+ u = (year - 1000) / 100
242
+ 1574.2 - 556.01 * u + 71.23472 * u**2 + 0.319781 * u**3 - 0.8503463 * u**4 - 0.005050998 * u**5 + 0.0083572073 * u**6
243
+
244
+ # -500 ... 500
245
+ elsif year >= -500
246
+ u = year / 100
247
+ 10583.6 - 1014.41 * u + 33.78311 * u**2 - 5.952053 * u**3 - 0.1798452 * u**4 + 0.022174192 * u**5 + 0.0090316521 * u**6
248
+
249
+ # ... -500
250
+ else
251
+ -20 + 32 * u**2
252
+ end
253
+ end
254
+ private :delta_t_observed_poly
255
+
256
+ # universal time を dynamical time に変換する
257
+ #
258
+ # @param [Numeric] time universal time
259
+ #
260
+ # @return [Numeric] dynamical time
261
+ #
262
+ def to_dynamical_time(time)
263
+ return time unless -Float::MAX/4 < time && time < Float::MAX/4
264
+ jd_utc = When::TM::JulianDate._t_to_d(time * 1)
265
+ +time + delta_t(jd_utc) * When::TM::Duration::SECOND
266
+ end
267
+
268
+ # dynamical time を universal time に変換する
269
+ #
270
+ # @param [Numeric] time dynamical time
271
+ #
272
+ # @return [Numeric] universal time
273
+ #
274
+ def from_dynamical_time(time)
275
+ return time unless -Float::MAX/4 < time && time < Float::MAX/4
276
+ jd_tt = When::TM::JulianDate._t_to_d(time)
277
+ utc = time - delta_t(jd_tt) * When::TM::Duration::SECOND
278
+ diff = time - to_dynamical_time(utc)
279
+ return utc if diff == 0 # 間に閏秒なし
280
+ utc += diff
281
+ diff = time - to_dynamical_time(utc)
282
+ return utc if diff == 0 # 間に閏秒なし
283
+ return When::Coordinates::LeapSeconds.new(utc+diff, -diff, When::TM::Duration::SECOND)
284
+ end
285
+
286
+ # Time オブジェクトを dynamical time に変換する
287
+ #
288
+ # @param [::Time] time
289
+ #
290
+ # @return [Numeric] [dynamical time
291
+ #
292
+ def from_time_object(time)
293
+ time = time.to_f * When::TM::Duration::SECOND
294
+ _is_systemtime_universal? ? to_dynamical_time(time) : time + DeltaT0
295
+ end
296
+
297
+ # dynamical time を Time オブジェクトに変換する
298
+ #
299
+ # @param [Numeric] time dynamical time
300
+ #
301
+ # @return [::Time]
302
+ #
303
+ def to_time_object(time)
304
+ time = _is_systemtime_universal? ? from_dynamical_time(time) : time - DeltaT0
305
+ ::Time.at(+time / When::TM::Duration::SECOND)
306
+ end
307
+ end
308
+
309
+ # @private
310
+ YearThreshold = 1997.0 + DeltaT.size
311
+
312
+ # @private
313
+ DeltaThreshold = DeltaT[-2] - delta_t_observed_poly(YearThreshold)
314
+
315
+ #
316
+ # When::TM::Calendar のための TimeBasis の初期化
317
+ #
318
+ # @private
319
+ module TimeBasis
320
+
321
+ # @private
322
+ attr_reader :_time_basis
323
+
324
+ module FixedTimeBasis
325
+
326
+ private
327
+
328
+ # 太陽黄経のための日付境界のオフセットを反映した通日
329
+ #
330
+ # @param [Numeric] t ユリウス日(Terrestrial Time)
331
+ #
332
+ # @return [Integer]
333
+ #
334
+ def solar_sdn(t)
335
+ (t + 0.5 + @_time_basis_offset[0]).floor
336
+ end
337
+
338
+ # 月の位相のための日付境界のオフセットを反映した通日
339
+ #
340
+ # @param [Numeric] t ユリウス日(Terrestrial Time)
341
+ #
342
+ # @return [Integer]
343
+ #
344
+ def lunar_sdn(t)
345
+ (t + 0.5 + @_time_basis_offset[-1]).floor
346
+ end
347
+ end
348
+
349
+ module ApparentTimeBasis
350
+
351
+ private
352
+
353
+ # 太陽黄経のための日付境界のオフセットを反映した通日
354
+ #
355
+ # @param [Numeric] t ユリウス日(Terrestrial Time)
356
+ #
357
+ # @return [Integer]
358
+ #
359
+ def solar_sdn(t)
360
+ time_basis.time_standard.from_dynamical_date(t + 0.5).floor
361
+ end
362
+
363
+ # 月の位相のための日付境界のオフセットを反映した通日
364
+ #
365
+ # @param [Numeric] t ユリウス日(Terrestrial Time)
366
+ #
367
+ # @return [Integer]
368
+ #
369
+ def lunar_sdn(t)
370
+ time_basis.time_standard.from_dynamical_date(t + 0.5).floor
371
+ end
372
+ end
373
+
374
+ #
375
+ # When::TM::Calendar のための TimeBasis の初期化
376
+ #
377
+ def _normalize_time_basis
378
+
379
+ @_time_basis ||= @time_basis || (@location ? @location.long / When::Coordinates::Spatial::DEGREE * 240 : When::UTC)
380
+ @_time_basis = When::Locale._split(@_time_basis) if @_time_basis.kind_of?(String)
381
+ @_time_basis = [@_time_basis] unless @_time_basis.kind_of?(Array)
382
+ @_time_basis = @_time_basis.map {|clock| When.Clock(clock)}
383
+ @_time_basis_offset = @_time_basis.map {|clock| -clock.universal_time / When::TM::Duration::DAY}
384
+
385
+ @time_basis = @_time_basis[0] if @time_basis
386
+
387
+ if @_time_basis[0].time_standard.kind_of?(LocalApparentTime)
388
+ extend ApparentTimeBasis
389
+ else
390
+ extend FixedTimeBasis
391
+ end
392
+ end
393
+ end
394
+
395
+ #
396
+ # Local Time と Universal Time の差分
397
+ #
398
+ # @private
399
+ module LocalTime
400
+
401
+ # local time と universal time の差 / 日
402
+ #
403
+ # @return [Numeric] difference / day
404
+ #
405
+ def localdate_difference
406
+ @localdate_difference ||= @location.long / (360.0 * When::Coordinates::Spatial::DEGREE)
407
+ end
408
+
409
+ # local time と universal time の差 / 128秒
410
+ #
411
+ # @return [Numeric] difference / day
412
+ #
413
+ def localtime_difference
414
+ @localtime_difference ||= When::TM::Duration::DAY * localdate_difference
415
+ end
416
+ end
417
+
418
+ #
419
+ # 時刻系のひながた
420
+ #
421
+ class TimeStandard < When::BasicTypes::Object
422
+
423
+ include When::TimeStandard
424
+
425
+ Ratio = 1.0
426
+
427
+ # universal time を dynamical time に変換する
428
+ #
429
+ # @param [Numeric] time universal time
430
+ #
431
+ # @return [Numeric] dynamical time
432
+ #
433
+ def to_dynamical_time(time)
434
+ When::TimeStandard.to_dynamical_time(time)
435
+ end
436
+
437
+ # dynamical time を universal time に変換する
438
+ #
439
+ # @param [Numeric] time dynamical time
440
+ #
441
+ # @return [Numeric] universal time
442
+ #
443
+ def from_dynamical_time(time)
444
+ When::TimeStandard.from_dynamical_time(time)
445
+ end
446
+
447
+ # 当該時刻系の日付を dynamical date に変換する
448
+ #
449
+ # @param [Numeric] date 当該時刻系の日付
450
+ #
451
+ # @return [Numeric] dynamical date
452
+ #
453
+ def to_dynamical_date(date)
454
+ When::TM::JulianDate._t_to_d(
455
+ to_dynamical_time(
456
+ When::TM::JulianDate._d_to_t(+date)))
457
+ end
458
+
459
+ # dynamical date を当該時刻系の日付に変換する
460
+ #
461
+ # @param [Numeric] date dynamical date
462
+ #
463
+ # @return [Numeric] 当該時刻系の日付
464
+ #
465
+ def from_dynamical_date(date)
466
+ When::TM::JulianDate._t_to_d(
467
+ from_dynamical_time(
468
+ When::TM::JulianDate._d_to_t(+date)))
469
+ end
470
+
471
+ # Time オブジェクトを universal time に変換する
472
+ #
473
+ # @param [::Time] time
474
+ #
475
+ # @return [Numeric] universal time
476
+ #
477
+ def from_time_object(time)
478
+ from_dynamical_time(When::TimeStandard.from_time_object(time))
479
+ end
480
+
481
+ # universal time を Time オブジェクトに変換する
482
+ #
483
+ # @param [Numeric] time universal time
484
+ #
485
+ # @return [::Time]
486
+ #
487
+ def to_time_object(time)
488
+ When::TimeStandard.to_time_object(to_dynamical_time(time))
489
+ end
490
+
491
+ # 当該時刻系に閏秒があるか?
492
+ #
493
+ # @return [Boolean] - false 閏秒なし
494
+ #
495
+ def has_leap?
496
+ false
497
+ end
498
+
499
+ # 時間の歩度
500
+ #
501
+ # @return [Numeric]
502
+ #
503
+ def rate_of_clock
504
+ self.class::Ratio
505
+ end
506
+
507
+ private
508
+
509
+ def _normalize(args=[], options={})
510
+ end
511
+ end
512
+
513
+ #
514
+ # 協定世界時
515
+ #
516
+ class UniversalTime < TimeStandard
517
+
518
+ # Time オブジェクトを universal time に変換する
519
+ #
520
+ # @param [::Time] time
521
+ #
522
+ # @return [Numeric] universal time
523
+ #
524
+ def from_time_object(time)
525
+ result = time.to_f * When::TM::Duration::SECOND
526
+ return result if When::TimeStandard._is_systemtime_universal?
527
+ from_dynamical_time(result + DeltaT0)
528
+ end
529
+
530
+ # universal time を Time オブジェクトに変換する
531
+ #
532
+ # @param [Numeric] time universal time
533
+ #
534
+ # @return [::Time]
535
+ #
536
+ def to_time_object(time)
537
+ time = to_dynamical_time(time) - DeltaT0 unless When::TimeStandard._is_systemtime_universal?
538
+ ::Time.at(+time / When::TM::Duration::SECOND)
539
+ end
540
+
541
+ # 当該時刻系に閏秒があるか?
542
+ #
543
+ # @return [Boolean] - true 閏秒あり
544
+ #
545
+ def has_leap?
546
+ true
547
+ end
548
+ end
549
+
550
+ #
551
+ # 地方平均太陽時
552
+ #
553
+ class LocalMeanTime < TimeStandard
554
+
555
+ include LocalTime
556
+
557
+ # local mean time を dynamical time に変換する
558
+ #
559
+ # @param [Numeric] time local mean time
560
+ #
561
+ # @return [Numeric] dynamical time
562
+ #
563
+ def to_dynamical_time(time)
564
+ super(time - localtime_difference)
565
+ end
566
+
567
+ # dynamical time を local mean time に変換する
568
+ #
569
+ # @param [Numeric] time dynamical time
570
+ #
571
+ # @return [Numeric] local mean time
572
+ #
573
+ def from_dynamical_time(time)
574
+ super(time) + localtime_difference
575
+ end
576
+
577
+ private
578
+
579
+ # オブジェクトの正規化
580
+ def _normalize(args=[], options={})
581
+ @location = When.Resource(@location || '_l:long=0&lat=0')
582
+ super
583
+ end
584
+ end
585
+
586
+ #
587
+ # 地方真太陽時
588
+ #
589
+ class LocalApparentTime < TimeStandard
590
+
591
+ include LocalTime
592
+
593
+ # local apparent time を dynamical time に変換する
594
+ #
595
+ # @param [Numeric] time local apparent time
596
+ #
597
+ # @return [Numeric] dynamical time
598
+ #
599
+ def to_dynamical_time(time)
600
+ date = When::TM::JulianDate._t_to_d(time) - localdate_difference
601
+ diff = 0
602
+ 2.times do
603
+ diff = @datum.equation_of_time(date-diff)
604
+ end
605
+ super(When::TM::JulianDate._d_to_t(date-diff))
606
+ end
607
+
608
+ # dynamical time を local apparent time に変換する
609
+ #
610
+ # @param [Numeric] time dynamical time
611
+ #
612
+ # @return [Numeric] local apparent time
613
+ #
614
+ def from_dynamical_time(time)
615
+ super(time) + When::TM::Duration::DAY * (localdate_difference + @datum.equation_of_time(When::TM::JulianDate._t_to_d(time)))
616
+ end
617
+
618
+ private
619
+
620
+ # オブジェクトの正規化
621
+ def _normalize(args=[], options={})
622
+ @location ||= '_l:long=0&lat=0'
623
+ @location = When.Resource(@location) if @location.kind_of?(String)
624
+ @datum = When.Resource(@datum || '_ep:Earth' )
625
+ super
626
+ end
627
+ end
628
+
629
+ #
630
+ # 不定時法
631
+ #
632
+ class TemporalHourSystem < LocalApparentTime
633
+
634
+ # @private
635
+ alias :_to_dynamical_time :to_dynamical_time
636
+ # @private
637
+ alias :_from_dynamical_time :from_dynamical_time
638
+
639
+ # temporal hour system を dynamical time に変換する
640
+ #
641
+ # @param [Numeric] time temporal hour system
642
+ #
643
+ # @return [Numeric] dynamical time
644
+ #
645
+ def to_dynamical_time(time)
646
+ noon, frac = When::TM::JulianDate._t_to_d(time).divmod(1)
647
+
648
+ r, *p =
649
+ case (frac * 4).floor
650
+ when 3 ; [-1.5, [noon+1, -1],[noon+1, +1]] # morning
651
+ when 0 ; [+0.5, [noon, -1],[noon, +1]] # afternoon
652
+ else ; [-0.5, [noon, +1],[noon+1, -1]] # night
653
+ end
654
+
655
+ s, e = p.map {|v|
656
+ When::TM::JulianDate._d_to_t(@formula.day_event(_to_dynamical_date(v[0]), v[1], When.Resource('_ep:Sun'), @height))
657
+ }
658
+
659
+ s + (e - s) * (frac * 2 + r)
660
+ end
661
+
662
+ # dynamical time を temporal hour system に変換する
663
+ #
664
+ # @param [Numeric] time dynamical time
665
+ #
666
+ # @return [Numeric] temporal hour system
667
+ #
668
+ def from_dynamical_time(time)
669
+ date = When::TM::JulianDate._t_to_d(time)
670
+
671
+ d, t = [-1, +1].map {|v| @formula.day_event(date, v, When.Resource('_ep:Sun'), @height)}
672
+
673
+ if date < d # after midnight
674
+ t = @formula.sunset(date-1, @height)
675
+ f = (date - t) / (d - t) / 2 - 0.25
676
+
677
+ elsif date > t # before midnight
678
+ d = @formula.sunrise(date+1, @height)
679
+ f = (date - t) / (d - t) / 2 - 0.25
680
+
681
+ else # day time
682
+ f = (date - d) / (t - d) / 2 + 0.25
683
+ end
684
+
685
+ When::TM::JulianDate._d_to_t(_from_dynamical_date(d).floor + 0.5 + f)
686
+ end
687
+
688
+ private
689
+
690
+ # オブジェクトの正規化
691
+ def _normalize(args=[], options={})
692
+ @formula = When::Ephemeris::Formula.new({:location=>@location})
693
+ @height ||= 'T'
694
+ super
695
+ end
696
+
697
+ # 単位を「日」にした to_dynamical_time
698
+ def _to_dynamical_date(date)
699
+ When::TM::JulianDate._t_to_d(_to_dynamical_time(When::TM::JulianDate._d_to_t(date)))
700
+ end
701
+
702
+ # 単位を「日」にした from_dynamical_time
703
+ def _from_dynamical_date(date)
704
+ When::TM::JulianDate._t_to_d(_from_dynamical_time(When::TM::JulianDate._d_to_t(date)))
705
+ end
706
+ end
707
+ end