when_exe 0.3.2 → 0.3.3

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 (93) hide show
  1. data/LICENSE.ja.txt +25 -25
  2. data/LICENSE.txt +31 -31
  3. data/bin/locales.rb +2 -1
  4. data/bin/when.rb.config +1 -1
  5. data/lib/when_exe.rb +70 -48
  6. data/lib/when_exe/basictypes.rb +99 -65
  7. data/lib/when_exe/calendartypes.rb +40 -178
  8. data/lib/when_exe/coordinates.rb +156 -62
  9. data/lib/when_exe/core/compatibility.rb +10 -0
  10. data/lib/when_exe/core/extension.rb +40 -0
  11. data/lib/when_exe/ephemeris.rb +112 -50
  12. data/lib/when_exe/icalendar.rb +125 -91
  13. data/lib/when_exe/inspect.rb +100 -48
  14. data/lib/when_exe/locales/ar.rb +48 -48
  15. data/lib/when_exe/locales/bg.rb +1 -1
  16. data/lib/when_exe/locales/bs.rb +4 -2
  17. data/lib/when_exe/locales/ca.rb +1 -1
  18. data/lib/when_exe/locales/en_CA.rb +3 -4
  19. data/lib/when_exe/locales/en_IE.rb +88 -0
  20. data/lib/when_exe/locales/en_US.rb +87 -0
  21. data/lib/when_exe/locales/es_CR.rb +84 -0
  22. data/lib/when_exe/locales/es_EC.rb +85 -0
  23. data/lib/when_exe/locales/es_PA.rb +85 -0
  24. data/lib/when_exe/locales/fr.rb +39 -39
  25. data/lib/when_exe/locales/hu.rb +15 -14
  26. data/lib/when_exe/locales/it.rb +1 -1
  27. data/lib/when_exe/locales/ja.rb +2 -2
  28. data/lib/when_exe/locales/locales.rb +7 -0
  29. data/lib/when_exe/locales/lt.rb +21 -19
  30. data/lib/when_exe/locales/ms.rb +84 -0
  31. data/lib/when_exe/locales/nl.rb +2 -2
  32. data/lib/when_exe/locales/ru.rb +1 -1
  33. data/lib/when_exe/locales/uk.rb +1 -1
  34. data/lib/when_exe/locales/ur.rb +84 -0
  35. data/lib/when_exe/mini_application.rb +44 -43
  36. data/lib/when_exe/parts/enumerator.rb +3 -3
  37. data/lib/when_exe/parts/geometric_complex.rb +6 -1
  38. data/lib/when_exe/parts/locale.rb +49 -18
  39. data/lib/when_exe/parts/method_cash.rb +61 -0
  40. data/lib/when_exe/parts/resource.rb +221 -106
  41. data/lib/when_exe/parts/timezone.rb +70 -33
  42. data/lib/when_exe/region/bahai.rb +2 -2
  43. data/lib/when_exe/region/balinese.rb +40 -43
  44. data/lib/when_exe/region/chinese.rb +93 -33
  45. data/lib/when_exe/region/chinese_calendar.rb +117 -1
  46. data/lib/when_exe/region/chinese_epoch.rb +65 -10
  47. data/lib/when_exe/region/christian.rb +97 -2
  48. data/lib/when_exe/region/ephemeric_notes.rb +353 -0
  49. data/lib/when_exe/region/french.rb +1 -1
  50. data/lib/when_exe/region/geologicalage.rb +171 -171
  51. data/lib/when_exe/region/indian.rb +18 -14
  52. data/lib/when_exe/region/iranian.rb +1 -1
  53. data/lib/when_exe/region/japanese.rb +49 -12
  54. data/lib/when_exe/region/japanese_notes.rb +838 -507
  55. data/lib/when_exe/region/japanese_residues.rb +724 -662
  56. data/lib/when_exe/region/javanese.rb +7 -7
  57. data/lib/when_exe/region/mayan.rb +19 -17
  58. data/lib/when_exe/region/nihon_shoki.rb +3 -3
  59. data/lib/when_exe/region/residue.rb +29 -28
  60. data/lib/when_exe/region/shire.rb +2 -2
  61. data/lib/when_exe/region/tibetan.rb +87 -5
  62. data/lib/when_exe/region/world.rb +1 -1
  63. data/lib/when_exe/timestandard.rb +85 -7
  64. data/lib/when_exe/tmobjects.rb +32 -4
  65. data/lib/when_exe/tmposition.rb +104 -55
  66. data/lib/when_exe/tmreference.rb +157 -60
  67. data/lib/when_exe/version.rb +2 -2
  68. data/test/examples/JapanHolidays.ics +3 -3
  69. data/test/examples/JapanHolidaysRFC6350.ics +499 -0
  70. data/test/examples/Residue.m17n +3 -2
  71. data/test/examples/Spatial.m17n +3 -3
  72. data/test/examples/USA-DST.ics +27 -27
  73. data/test/examples/today.rb +1 -1
  74. data/test/test.rb +4 -2
  75. data/test/test/basictypes.rb +40 -15
  76. data/test/test/coordinates.rb +9 -4
  77. data/test/test/icalendar.rb +24 -14
  78. data/test/test/inspect.rb +5 -3
  79. data/test/test/parts.rb +11 -2
  80. data/test/test/region/chinese.rb +4 -4
  81. data/test/test/region/civil.rb +124 -0
  82. data/test/test/region/geologicalage.rb +5 -2
  83. data/test/test/region/indian.rb +2 -0
  84. data/test/test/region/japanese.rb +156 -1
  85. data/test/test/region/jewish.rb +3 -3
  86. data/test/test/region/m17n.rb +9 -9
  87. data/test/test/region/mayan.rb +122 -5
  88. data/test/test/region/residue.rb +1 -1
  89. data/test/test/tmobjects.rb +27 -64
  90. data/test/test/tmposition.rb +48 -1
  91. data/test/test/tmreference.rb +66 -4
  92. data/when_exe.gemspec +1 -1
  93. metadata +15 -6
@@ -255,7 +255,14 @@ module When::TM
255
255
  # 処理を @position (type: When::TM::Position) に委譲する
256
256
  #
257
257
  def method_missing(name, *args, &block)
258
- @position.send(name.to_sym, *args, &block)
258
+ self.class.module_eval %Q{
259
+ def #{name}(*args, &block)
260
+ list = args.map {|arg| arg.kind_of?(self.class) ? arg.position : arg}
261
+ @position.send("#{name}", *list, &block)
262
+ end
263
+ } unless When::Parts::MethodCash.escape(name)
264
+ list = args.map {|arg| arg.kind_of?(self.class) ? arg.position : arg}
265
+ @position.send(name, *list, &block)
259
266
  end
260
267
  end
261
268
 
@@ -385,7 +392,12 @@ module When::TM
385
392
  # 処理を @begin (type: When::TM::Instant) に委譲する
386
393
  #
387
394
  def method_missing(name, *args, &block)
388
- @begin.send(name.to_sym, *args, &block)
395
+ self.class.module_eval %Q{
396
+ def #{name}(*args, &block)
397
+ @begin.send("#{name}", *args, &block)
398
+ end
399
+ } unless When::Parts::MethodCash.escape(name)
400
+ @begin.send(name, *args, &block)
389
401
  end
390
402
  end
391
403
 
@@ -410,6 +422,8 @@ module When::TM
410
422
 
411
423
  private
412
424
 
425
+ alias :_method_missing :method_missing
426
+
413
427
  # その他のメソッド
414
428
  #
415
429
  # @note
@@ -417,7 +431,16 @@ module When::TM
417
431
  # 処理を @geometry (type: When::TM::Instant) に委譲する
418
432
  #
419
433
  def method_missing(name, *args, &block)
420
- @geometry.send(name.to_sym, *args, &block)
434
+ return _method_missing(name, *args, &block) if When::Parts::MethodCash::Escape.key?(name) ||
435
+ !respond_to?(:geometry)
436
+ self.class.module_eval %Q{
437
+ def #{name}(*args, &block)
438
+ list = args.map {|arg| arg.respond_to?(:geometry) ? arg.geometry : arg}
439
+ geometry.send("#{name}", *list, &block)
440
+ end
441
+ } unless When::Parts::MethodCash.escape(name)
442
+ list = args.map {|arg| arg.respond_to?(:geometry) ? arg.geometry : arg}
443
+ geometry.send(name, *list, &block)
421
444
  end
422
445
  end
423
446
 
@@ -828,7 +851,12 @@ module When::TM
828
851
  # 処理を @duration (type:Numeric) に委譲する
829
852
  #
830
853
  def method_missing(name, *args, &block)
831
- @duration.send(name.to_sym, *args, &block)
854
+ self.class.module_eval %Q{
855
+ def #{name}(*args, &block)
856
+ @duration.send("#{name}", *args, &block)
857
+ end
858
+ } unless When::Parts::MethodCash.escape(name)
859
+ @duration.send(name, *args, &block)
832
860
  end
833
861
  end
834
862
 
@@ -1,6 +1,6 @@
1
1
  # -*- coding: utf-8 -*-
2
2
  =begin
3
- Copyright (C) 2011-2013 Takashi SUGA
3
+ Copyright (C) 2011-2014 Takashi SUGA
4
4
 
5
5
  You may use and/or modify this file according to the license described in the LICENSE.txt file included in this archive.
6
6
  =end
@@ -136,6 +136,8 @@ module When::TM
136
136
 
137
137
  private
138
138
 
139
+ alias :_method_missing :method_missing
140
+
139
141
  # その他のメソッド
140
142
  #
141
143
  # @note
@@ -145,8 +147,15 @@ module When::TM
145
147
  # (両方ともに有効なメソッドは@any_otherを優先する)
146
148
  #
147
149
  def method_missing(name, *args, &block)
148
- union = @any_other.respond_to?(name.to_sym) ? @any_other : @date_time8601
149
- union.send(name.to_sym, *args, &block)
150
+ return _method_missing(name, *args, &block) if When::Parts::MethodCash::Escape.key?(name)
151
+ self.class.module_eval %Q{
152
+ def #{name}(*args, &block)
153
+ union = @any_other.respond_to?("#{name}") ? @any_other : @date_time8601
154
+ union.send("#{name}", *args, &block)
155
+ end
156
+ } unless When::Parts::MethodCash.escape(name)
157
+ union = @any_other.respond_to?(name) ? @any_other : @date_time8601
158
+ union.send(name, *args, &block)
150
159
  end
151
160
  end
152
161
 
@@ -265,6 +274,7 @@ module When::TM
265
274
  # @option options [When::TM::Clock, When::V::Timezone, When::Parts::Timezone, String] :clock 時法の指定
266
275
  # @option options [String] :tz 時法の指定(時間帯を指定する場合 :clock の替わりに用いることができる)
267
276
  # @option options [Array<Numeric>] :abbr ISO8601上位省略形式のためのデフォルト日付(省略時 指定なし)
277
+ # @option options [Integer] :extra_year_digits ISO8601拡大表記のための年の構成要素拡大桁数(省略時 1桁)
268
278
  # @option options [String] :wkst ISO8601週日形式のための暦週開始曜日(省略時 'MO')
269
279
  # @option options [Integer] :precision 生成するオブジェクトの分解能
270
280
  # @option options [When::TimeStandard::TimeStandard] :time_standard 時刻系の指定(省略時 When::TimeStandard::UnversalTime)
@@ -430,12 +440,13 @@ module When::TM
430
440
  clock = Clock.get_clock_option(query)
431
441
  main[:clock] = clock if clock
432
442
  [:indeterminated_position, :frame, :events, :precision,
433
- :era_name, :era, :abbr, :wkst, :time_standard, :location].each do |key|
443
+ :era_name, :era, :abbr, :extra_year_digits, :wkst, :time_standard, :location].each do |key|
434
444
  main[key] = query.delete(key) if (query.key?(key))
435
445
  end
436
446
  long = query.delete(:long)
437
447
  lat = query.delete(:lat)
438
- main[:location] ||= "_l:long=#{long}&lat=#{lat}" if long && lat
448
+ alt = query.delete(:alt)
449
+ main[:location] ||= "_l:long=#{long||0}&lat=#{lat||0}&alt=#{alt||0}" if long && lat
439
450
  trans = query.delete(:trans) || {}
440
451
  [:lower, :upper, :count].each do |key|
441
452
  trans[key] = query.delete(key) if (query.key?(key))
@@ -446,6 +457,13 @@ module When::TM
446
457
  return main
447
458
  end
448
459
 
460
+ # 比較
461
+ # @private
462
+ def _verify(source, target)
463
+ return source.universal_time <=> target.universal_time if source.time_standard.equal?(target.time_standard)
464
+ return source.dynamical_time <=> target.dynamical_time
465
+ end
466
+
449
467
  private
450
468
 
451
469
  # date_time_or_duration
@@ -503,9 +521,10 @@ module When::TM
503
521
  #
504
522
  def time_standard
505
523
  return @time_standard if @time_standard.kind_of?(When::TimeStandard)
506
- @time_standard = When.Resource(@time_standard ||
507
- (frame ? frame.time_standard : nil) ||
508
- 'UniversalTime', '_t:')
524
+ @time_standard ||= clock.time_standard if respond_to?(:clock) && clock
525
+ @time_standard ||= frame.time_standard if frame
526
+ @time_standard ||= 'UniversalTime'
527
+ @time_standard = When.Resource(@time_standard, '_t:')
509
528
  end
510
529
 
511
530
  # 時間の歩度
@@ -664,7 +683,8 @@ module When::TM
664
683
  when Integer ; self + PeriodDuration.new(other, When::DAY)
665
684
  when Numeric ; self + IntervalLength.new(other, 'day')
666
685
  when PeriodDuration ; _plus(other)
667
- when Duration ; @frame.jul_trans(JulianDate.dynamical_time(dynamical_time + other.duration), self._attr)
686
+ when Duration ; @frame.kind_of?(Calendar) ? @frame.jul_trans(JulianDate.dynamical_time(dynamical_time + other.duration), self._attr) :
687
+ JulianDate.dynamical_time(dynamical_time + other.duration, self._attr)
668
688
  else ; raise TypeError, "The right operand should be Numeric or Duration"
669
689
  end
670
690
  rescue RangeError
@@ -686,7 +706,8 @@ module When::TM
686
706
  when Integer ; self - PeriodDuration.new(other, When::DAY)
687
707
  when Numeric ; self - IntervalLength.new(other, 'day')
688
708
  when PeriodDuration ; _plus(-other)
689
- when Duration ; @frame.jul_trans(JulianDate.dynamical_time(dynamical_time - other.duration), self._attr)
709
+ when Duration ; @frame.kind_of?(Calendar) ? @frame.jul_trans(JulianDate.dynamical_time(dynamical_time - other.duration), self._attr) :
710
+ JulianDate.dynamical_time(dynamical_time - other.duration, self._attr)
690
711
  else ; raise TypeError, "The right operand should be Numeric, Duration or TemporalPosition"
691
712
  end
692
713
  rescue RangeError
@@ -711,7 +732,7 @@ module When::TM
711
732
  # 分解能に対応する Duration だけ,日時を戻す
712
733
  #
713
734
  def prev
714
- @precision==When::DAY ? _force_euqal_day(-1) : self-period
735
+ @precision==When::DAY ? _force_euqal_day(-1) : self-period
715
736
  rescue RangeError
716
737
  (When.Calendar('Gregorian') ^ self) - period
717
738
  end
@@ -723,7 +744,7 @@ module When::TM
723
744
  # 分解能に対応する Duration だけ,日時を進める
724
745
  #
725
746
  def succ
726
- @precision==When::DAY ? _force_euqal_day(+1) : self+period
747
+ @precision==When::DAY ? _force_euqal_day(+1) : self+period
727
748
  rescue RangeError
728
749
  (When.Calendar('Gregorian') ^ self) + period
729
750
  end
@@ -773,8 +794,25 @@ module When::TM
773
794
  return self == date
774
795
  end
775
796
 
797
+ # オブジェクトの同値
798
+ #
799
+ # @param [比較先] other
800
+ #
801
+ # @return [Boolean]
802
+ # [ true - 同値 ]
803
+ # [ false - 非同値 ]
804
+ #
805
+ def ==(other)
806
+ (self <=> other) == 0
807
+ rescue
808
+ false
809
+ end
810
+
776
811
  # 大小比較
777
812
  #
813
+ # @param [When::TM::TemporalPosition] other チェックされる日時
814
+ # @param [Numeric] other チェックされる日時の universal time(self と同じtime_standardとみなす)
815
+ #
778
816
  # @return [Integer] (-1, 0, 1)
779
817
  #
780
818
  # 分解能の低い方にあわせて比較を行う
@@ -782,32 +820,34 @@ module When::TM
782
820
  # Ex. when?('2011-03') <=> when?('2011-03-10') -> 0
783
821
  #
784
822
  def <=>(other)
785
- other = other.first if other.kind_of?(When::Parts::GeometricComplex)
823
+ other = other.first if other.kind_of?(Range)
824
+ return universal_time <=> other if other.kind_of?(Numeric)
825
+
786
826
  [self.indeterminated_position, other.indeterminated_position].each do |position|
787
827
  prec = SYSTEM if [TimeValue::Min, TimeValue::Max].include?(position)
788
828
  end
789
829
  prec = [self.precision, other.precision].min unless prec
830
+
790
831
  case prec
791
832
  when DAY ; return self.to_i <=> other.to_i
792
- when SYSTEM ; src, dst = self, other
793
- else
794
- if prec < DAY && respond_to?(:most_significant_coordinate) &&
795
- other.respond_to?(:most_significant_coordinate) && @frame.equal?(other.frame)
796
- result = most_significant_coordinate <=> other.most_significant_coordinate
797
- return result unless result == 0 && @cal_date.length + prec > 1
798
- (@cal_date.length + prec - 2).times do |i|
799
- result = @cal_date[i+1] <=> other.cal_date[i+1]
800
- return result unless result == 0
801
- end
802
- return @cal_date[prec - 1] <=> other.cal_date[prec - 1]
833
+ when SYSTEM ; return TemporalPosition._verify(self, other)
834
+ end
835
+
836
+ if prec < DAY && respond_to?(:most_significant_coordinate) &&
837
+ other.respond_to?(:most_significant_coordinate) && @frame.equal?(other.frame)
838
+ result = most_significant_coordinate <=> other.most_significant_coordinate
839
+ return result unless result == 0 && @cal_date.length + prec > 1
840
+ (@cal_date.length + prec - 2).times do |i|
841
+ result = @cal_date[i+1] <=> other.cal_date[i+1]
842
+ return result unless result == 0
803
843
  end
804
- src, dst =
805
- [(prec >= self.precision ) ? self : self.floor(prec),
806
- (prec >= other.precision) ? other : other.floor(prec)]
844
+ @cal_date[prec - 1] <=> other.cal_date[prec - 1]
845
+ else
846
+ source = (prec >= self.precision ) ? self : self.floor(prec)
847
+ target = (prec >= other.precision) ? other : other.floor(prec)
848
+ return source.to_i <=> target.to_i if prec <= DAY
849
+ TemporalPosition._verify(source, target)
807
850
  end
808
- return src.to_i <=> dst.to_i if prec <= DAY
809
- return src.universal_time <=> dst.universal_time if src.time_standard.equal?(dst.time_standard)
810
- return src.dynamical_time <=> dst.dynamical_time
811
851
  end
812
852
 
813
853
  # 条件を満たすオブジェクトの抽出
@@ -891,10 +931,12 @@ module When::TM
891
931
  # @private
892
932
  def _attr
893
933
  attributes = {}
894
- ['frame', 'events', 'precision', 'options', 'trans', 'query', 'time_standard'].each do |key|
895
- attributes[key.to_sym] = instance_variable_get("@#{key}")
934
+ [:frame, :events, :precision, :options, :trans, :query].each do |key|
935
+ attributes[key] = instance_variable_get("@#{key}")
896
936
  end
897
- return attributes
937
+ attributes[:location] = location
938
+ attributes[:time_standard] = time_standard
939
+ return attributes.delete_if {|k,v| !v}
898
940
  end
899
941
 
900
942
  protected
@@ -965,6 +1007,8 @@ module When::TM
965
1007
  end
966
1008
  end
967
1009
 
1010
+ alias :_method_missing :method_missing
1011
+
968
1012
  # その他のメソッド
969
1013
  #
970
1014
  # @note
@@ -972,7 +1016,14 @@ module When::TM
972
1016
  # 処理を @frame (type: When::TM::Calendar or When::TM::Clock) に委譲する
973
1017
  #
974
1018
  def method_missing(name, *args, &block)
975
- @frame.send(name.to_sym, self, *args, &block)
1019
+
1020
+ return _method_missing(name, *args, &block) if When::Parts::MethodCash::Escape.key?(name)
1021
+ self.class.module_eval %Q{
1022
+ def #{name}(*args, &block)
1023
+ @frame.send("#{name}", self, *args, &block)
1024
+ end
1025
+ } unless When::Parts::MethodCash.escape(name)
1026
+ @frame.send(name, self, *args, &block)
976
1027
  end
977
1028
  end
978
1029
 
@@ -1016,29 +1067,29 @@ module When::TM
1016
1067
  case time
1017
1068
  when Numeric
1018
1069
  options[:frame] ||= When.utc unless time.kind_of?(Integer)
1019
- external_time = (2*time - (2*JulianDate::JD19700101-1)) * Duration::DAY.to_i / 2.0
1070
+ universal_time = (2*time - (2*JulianDate::JD19700101-1)) * Duration::DAY.to_i / 2.0
1020
1071
  when ClockTime
1021
1072
  options[:frame] ||= time.clock
1022
- external_time = time.clk_time[0] + time.universal_time
1073
+ universal_time = time.clk_time[0] + time.universal_time
1023
1074
  when ::Time
1024
1075
  options[:frame] ||= When.Clock(time.gmtoff)
1025
- external_time = When.Resource('_t:UniversalTime').from_time_object(time)
1076
+ universal_time = When.Resource('_t:UniversalTime').from_time_object(time)
1026
1077
  when TimeValue
1027
1078
  options[:frame] ||= time.clock
1028
- external_time = time.universal_time
1079
+ universal_time = time.universal_time
1029
1080
  else
1030
1081
  if ::Object.const_defined?(:Date) && time.respond_to?(:ajd)
1031
1082
  case time
1032
1083
  when ::DateTime
1033
1084
  options[:frame] ||= When.Clock((time.offset * 86400).to_i)
1034
- external_time = (2*time.ajd - (2*JulianDate::JD19700101-1)) * Duration::DAY.to_i / 2.0
1085
+ universal_time = (2*time.ajd - (2*JulianDate::JD19700101-1)) * Duration::DAY.to_i / 2.0
1035
1086
  when ::Date
1036
- external_time = JulianDate._d_to_t(time.jd)
1087
+ universal_time = JulianDate._d_to_t(time.jd)
1037
1088
  end
1038
1089
  end
1039
1090
  end
1040
- raise TypeError, "Can't create #{self} from #{time.class}" unless external_time
1041
- universal_time(external_time, options)
1091
+ raise TypeError, "Can't create #{self} from #{time.class}" unless universal_time
1092
+ universal_time(universal_time, options)
1042
1093
  end
1043
1094
  end
1044
1095
 
@@ -1073,8 +1124,8 @@ module When::TM
1073
1124
  # @return [When::TM::TemporalPosition]
1074
1125
  #
1075
1126
  def +(other)
1076
- raise TypeError,"The right operand should be IntervalLength" if other.kind_of?(PeriodDuration)
1077
- super
1127
+ other = other.to_interval_length if other.kind_of?(PeriodDuration)
1128
+ super(other)
1078
1129
  end
1079
1130
 
1080
1131
  # 減算
@@ -1085,8 +1136,8 @@ module When::TM
1085
1136
  # @return [When::TM::IntervalLength] if other is a When::TM::TemporalPosition
1086
1137
  #
1087
1138
  def -(other)
1088
- raise TypeError,"The right operand should be IntervalLength or (Temporal)Position" if other.kind_of?(PeriodDuration)
1089
- super
1139
+ other = other.to_interval_length if other.kind_of?(PeriodDuration)
1140
+ super(other)
1090
1141
  end
1091
1142
 
1092
1143
  # オブジェクトの生成
@@ -1148,9 +1199,7 @@ module When::TM
1148
1199
  #
1149
1200
  def +(other)
1150
1201
  new_date = super
1151
- if new_date.frame && new_date.frame._need_validate
1152
- new_date.frame = new_date.frame._daylight(self.class.dynamical_time(new_date.dynamical_time, {:frame=>When.utc}))
1153
- end
1202
+ new_date.frame = new_date.frame._daylight(new_date.universal_time) if new_date.frame && new_date.frame._need_validate
1154
1203
  return new_date
1155
1204
  end
1156
1205
 
@@ -1194,7 +1243,7 @@ module When::TM
1194
1243
  def initialize(universal_time, options={})
1195
1244
  @frame = options.delete(:frame)
1196
1245
  @frame = When.Clock(@frame) if (@frame.kind_of?(String))
1197
- @frame = @frame._daylight(self.class.universal_time(universal_time, {:frame=>When.utc})) if @frame && @frame._need_validate
1246
+ @frame = @frame._daylight(universal_time) if @frame && @frame._need_validate
1198
1247
  precision = options.delete(:precision)
1199
1248
  precision ||= DAY unless @frame.kind_of?(Clock)
1200
1249
  @precision = Index.precision(precision)
@@ -1311,7 +1360,7 @@ module When::TM
1311
1360
  #
1312
1361
  def initialize(time, options={})
1313
1362
  # 参照系の取得
1314
- @frame = (options[:frame] || Clock.local_time || When.utc)
1363
+ @frame = options[:frame] || Clock.local_time
1315
1364
  @frame = When.Clock(@frame) if (@frame.kind_of?(String))
1316
1365
  options.delete(:frame)
1317
1366
 
@@ -1850,7 +1899,7 @@ module When::TM
1850
1899
  return @location if @location
1851
1900
  timezone = @clk_time.frame.tz_prop
1852
1901
  return nil unless timezone.kind_of?(When::Parts::Timezone)
1853
- @location = When.Resource("_l:long=#{timezone.longitude.to_f}&lat=#{timezone.latitude.to_f}")
1902
+ @location = timezone.location
1854
1903
  end
1855
1904
 
1856
1905
  # 時刻情報のない When::TM::CalDate を返す
@@ -1880,7 +1929,7 @@ module When::TM
1880
1929
  case options[:time]
1881
1930
  when Array
1882
1931
  if clock._need_validate
1883
- new_clock = clock._daylight { |c| self.class.new(options[:date], options[:time], {:frame=>@frame, :clock=>c}) }
1932
+ new_clock = clock._daylight([@frame, options[:date], options[:time]])
1884
1933
  options[:time] = options[:time].map {|t| t * 1}
1885
1934
  else
1886
1935
  new_clock = clock
@@ -1918,7 +1967,7 @@ module When::TM
1918
1967
  unless options[:validate]
1919
1968
  clock = Clock.get_clock_option(options)
1920
1969
  clock ||= options[:time].frame if options[:time].kind_of?(ClockTime)
1921
- clock ||= Clock.local_time || When.utc
1970
+ clock ||= Clock.local_time
1922
1971
  end
1923
1972
  clock = When.Clock(clock) if (clock.kind_of?(String))
1924
1973
  clock_is_timezone = clock.respond_to?(:daylight)
@@ -1964,7 +2013,7 @@ module When::TM
1964
2013
  else
1965
2014
  cal_date = @cal_date
1966
2015
  end
1967
- clock = clock._daylight {|clock| self.class.new(cal_date, time, {:frame=>@frame, :clock=>clock}) }
2016
+ clock = clock._daylight([@frame, cal_date, time])
1968
2017
  end
1969
2018
  time = time.map {|t| t * 1}
1970
2019
  @clk_time = ClockTime.new(time, {:frame=>clock, :precision=>precision, :validate=>:done}) if clock_is_timezone
@@ -1,6 +1,6 @@
1
1
  # -*- coding: utf-8 -*-
2
2
  =begin
3
- Copyright (C) 2011-2013 Takashi SUGA
3
+ Copyright (C) 2011-2014 Takashi SUGA
4
4
 
5
5
  You may use and/or modify this file according to the license described in the LICENSE.txt file included in this archive.
6
6
  =end
@@ -49,16 +49,15 @@ module When::TM
49
49
  #
50
50
  # Range of time within which the temporal reference system is use
51
51
  #
52
- # @return [When::Parts::GeomerticComplex]
52
+ # @return [Hash<String=>When::Parts::GeomerticComplex>]
53
53
  #
54
54
  # @note
55
55
  # マルチスレッド動作時 CalendarEra の生成で Calendar の本属性が更新される
56
56
  # 参照・更新処理は synchronize { ... } の ... の部分に書く必要がある
57
57
  #
58
58
  def domain
59
- @domain ||= When::Parts::GeometricComplex.new([])
59
+ @domain ||= Hash.new {|hash, key| hash[key] = When::Parts::GeometricComplex.new([])}
60
60
  end
61
- attr_writer :domain
62
61
 
63
62
  # 時間参照系を識別する名称
64
63
  #
@@ -99,7 +98,9 @@ module When::TM
99
98
  class Calendar < ReferenceSystem
100
99
 
101
100
  include When::Coordinates
101
+ include Spatial::Normalize
102
102
  include Temporal
103
+ include When::TimeStandard::TimeBasis
103
104
 
104
105
  # 初期化
105
106
  #
@@ -177,6 +178,7 @@ module When::TM
177
178
  # @return [When::TM::CalDateAndTime] if (options[:clock or :tz] != nil)
178
179
  #
179
180
  def jul_trans(jdt, options={})
181
+ options = TemporalPosition._options(options)
180
182
  unless jdt.kind_of?(When::TimeValue)
181
183
  options[:clock] ||= @time_basis unless rate_of_clock == 1.0
182
184
  jdt = JulianDate.new(jdt, options)
@@ -189,42 +191,63 @@ module When::TM
189
191
  cal_options[:clock] = @time_basis || When.utc
190
192
  jdt = JulianDate.dynamical_time(jdt.dynamical_time, {:time_standard=>time_standard})
191
193
  end
194
+
192
195
  cal_options.update(options)
193
196
  cal_options[:frame] = self
194
- cal_date = to_cal_date(jdt.to_i)
195
- cal_date[0] -= cal_options[:era_name][1] if cal_options[:era_name]
196
- clock = @time_basis || Clock.get_clock_option(cal_options) || jdt.clock
197
- return CalDate.new(cal_date, cal_options) unless clock
198
- clock = When.Clock(clock) if clock.kind_of?(String)
199
- clock = clock._daylight(jdt) if clock._need_validate
200
- frac = clock.universal_time
201
- sdn, time = (jdt.universal_time - frac).divmod(Duration::DAY)
202
- cal_options[:clock] = clock
203
- return DateAndTime.new(to_cal_date(sdn.to_i + JulianDate::JD19700101), time+frac, cal_options)
197
+ clock = Clock.get_clock_option(cal_options) || jdt.clock
198
+
199
+ if clock
200
+ clock = When.Clock(clock) if clock.kind_of?(String)
201
+ clock = clock._daylight(jdt.universal_time) if clock._need_validate
202
+ frac = clock.universal_time
203
+ sdn, time = (jdt.universal_time - frac).divmod(Duration::DAY)
204
+ cal_options[:clock] = clock
205
+ cal_date = to_cal_date(sdn.to_i + JulianDate::JD19700101)
206
+ cal_date[0] -= cal_options[:era_name][1] if cal_options[:era_name]
207
+ DateAndTime.new(cal_date, time+frac, cal_options)
208
+ else
209
+ cal_date = to_cal_date(jdt.to_i)
210
+ cal_date[0] -= cal_options[:era_name][1] if cal_options[:era_name]
211
+ CalDate.new(cal_date, cal_options)
212
+ end
204
213
  end
205
214
  alias :julTrans :jul_trans
206
215
  alias :^ :jul_trans
207
216
 
217
+ # ユリウス日(Numeric)を日付に変換する
218
+ #
219
+ # @param [Integer] jdn
220
+ #
221
+ # @return [Array<Numeric>]
222
+ #
223
+ def to_cal_date(jdn)
224
+ _encode(_number_to_coordinates(jdn))
225
+ end
226
+
208
227
  # 日付をユリウス日(Numeric)に変換する
209
228
  #
210
- # @param [Numeric] cal_date
229
+ # @param [Array<Numeric>] cal_date
211
230
  #
212
231
  # @return [Integer] JulianDate
213
232
  #
214
233
  def to_julian_date(cal_date)
215
234
  date = _decode(cal_date)
216
235
  date[0] = +date[0]
217
- return _coordinates_to_number(*date)
236
+ _coordinates_to_number(*date)
218
237
  end
219
238
 
220
- # ユリウス日(Numeric)を日付に変換する
239
+ # 日付・時刻をUniversal Time(Numeric)に変換する
221
240
  #
222
- # @param [Integer] jdn
241
+ # @param [Array<Numeric>] cal_date 日付
242
+ # @param [Array<Numeric>] clk_time 時刻
243
+ # @param [When::TM::Clock] clock 時法
223
244
  #
224
- # @return [Numeric]
245
+ # @return [Numeric] Universal Time
225
246
  #
226
- def to_cal_date(jdn)
227
- return _encode(_number_to_coordinates(jdn))
247
+ def to_universal_time(cal_date, clk_time, clock=When.utc)
248
+ time = clk_time.dup
249
+ time[0] += _coordinates_to_number(*_decode(cal_date))
250
+ clock.to_universal_time(time) - When::TM::JulianDate::JD19700101 * When::TM::Duration::DAY
228
251
  end
229
252
 
230
253
  # 月初の通日
@@ -264,8 +287,9 @@ module When::TM
264
287
 
265
288
  # オブジェクトの正規化
266
289
  def _normalize(args=[], options={})
267
- @time_basis = When.Calendar(@time_basis) if @time_basis.kind_of?(String)
268
290
  @indices ||= DefaultDateIndices
291
+ _normalize_spatial
292
+ _normalize_time_basis
269
293
  _normalize_temporal
270
294
  @reference_frame ||= []
271
295
  end
@@ -278,29 +302,15 @@ module When::TM
278
302
  class Clock < ReferenceSystem
279
303
 
280
304
  include When::Coordinates
305
+ include Spatial::Normalize
281
306
  include Temporal
282
307
 
283
308
  class << self
284
309
  include When::Parts::Resource::Pool
285
310
 
286
- # 地方時
287
- #
288
- # @return [When::TM::Clock, When::Parts::Timezone, When::V::Timezone]
289
- #
290
- # @note
291
- # 本変数の write access はテスト用である。
292
- # 本変数は、原則、ライブラリ立ち上げ時に _setup_ で初期化する。
293
- # 以降、本変数に代入を行っても、すでに生成した When::TM::TemporalPosition には反映されない。
294
- #
295
- # @note
296
- # マルチスレッド動作時 CalendarEra の生成で Calendar の本属性が更新される
297
- # 参照・更新処理は Clock.synchronize { ... } の ... の部分に書く必要がある
298
- #
299
- attr_accessor :local_time
300
-
301
311
  # When::TM::Clock Class のグローバルな設定を行う
302
312
  #
303
- # @param [When::TM::Clock, When::Parts::Timezone, When::V::Timezone] local 地方時を使用する場合、指定する
313
+ # @param [When::TM::Clock, When::Parts::Timezone, When::V::Timezone, String] local 地方時を使用する場合、指定する
304
314
  #
305
315
  # @return [void]
306
316
  #
@@ -314,9 +324,56 @@ module When::TM
314
324
  @local_time = local
315
325
  end
316
326
 
327
+ # 地方時
328
+ #
329
+ # @param [When::TM::Clock, When::Parts::Timezone, When::V::Timezone, String] local 地方時
330
+ #
331
+ # @return [When::TM::Clock, When::Parts::Timezone, When::V::Timezone, String]
332
+ #
333
+ # @note
334
+ # @local_timeは、原則、ライブラリ立ち上げ時に _setup_ で初期化する。
335
+ # 以降、@local_timeに代入を行っても、すでに生成した When::TM::TemporalPosition 等には反映されない。
336
+ #
337
+ def local_time=(local)
338
+ if @_pool
339
+ @local_time = local
340
+ else
341
+ _setup_(local)
342
+ end
343
+ end
344
+
345
+ # When::TM::Clock のローカルタイムを読みだす
346
+ #
347
+ # @return [When::TM::Clock, When::Parts::Timezone, When::V::Timezone]
348
+ #
349
+ def local_time
350
+ _local_time[1]
351
+ end
352
+
353
+ # When::TM::Clock のローカルタイムが設定されているか?
354
+ #
355
+ # @return [true, false]
356
+ #
357
+ def is_local_time_set?
358
+ _local_time[0]
359
+ end
360
+
361
+ # 共通処理
362
+ def _local_time
363
+ case @local_time
364
+ when Array ; @local_time
365
+ when nil ; @local_time = [false, When.utc]
366
+ when String ; @local_time = [true, When::Parts::Timezone[@local_time] ||
367
+ When::V::Timezone[@local_time] ||
368
+ When.Clock(@local_time)]
369
+ else ; @local_time = [true, @local_time]
370
+ end
371
+ end
372
+ private :_local_time
373
+
317
374
  # @private
318
375
  def get_clock(options)
319
- get_clock_option(options) || @local_time || When.utc
376
+ get_clock_option(options) || local_time
320
377
  end
321
378
 
322
379
  # @private
@@ -443,15 +500,17 @@ module When::TM
443
500
  @time_standard.rate_of_clock
444
501
  end
445
502
 
446
- # 日の小数による参照事象の時刻
503
+ # 128秒単位の実数による参照事象の時刻
447
504
  #
448
505
  # Fraction time of the reference event
449
506
  #
507
+ # @param [Integer] sdn 参照事象の通し番号(ダミー)
508
+ #
450
509
  # @return [Numeric]
451
510
  #
452
511
  # T00:00:00Z からの参照事象の経過時間 / 128秒
453
512
  #
454
- def universal_time
513
+ def universal_time(sdn=nil)
455
514
  return @utc_reference.universal_time
456
515
  end
457
516
 
@@ -477,9 +536,9 @@ module When::TM
477
536
  end
478
537
  alias :clkTrans :clk_trans
479
538
 
480
- # この時法の時刻を日の小数に変換する
539
+ # この時法の時刻を128秒単位の実数に変換する
481
540
  #
482
- # @param [Numeric] clk_time
541
+ # @param [Array<Numeric>] clk_time
483
542
  #
484
543
  # @return [Numeric]
485
544
  #
@@ -487,7 +546,7 @@ module When::TM
487
546
  return _coordinates_to_number(_decode(clk_time)) / @second
488
547
  end
489
548
 
490
- # 日の小数をこの時法の時刻に変換する
549
+ # 128秒単位の実数をこの時法の時刻に変換する
491
550
  #
492
551
  # @param [Numeric] fod
493
552
  #
@@ -544,18 +603,19 @@ module When::TM
544
603
  def ^(date, options={})
545
604
  date = Position.any_other(date, options)
546
605
  my_options = (date.options||{}).merge(options)
547
- frac = self.universal_time
606
+ frac = self.universal_time(date.to_i)
548
607
  sdn, time = (date.universal_time - frac).divmod(Duration::DAY)
549
608
  my_options[:frame] ||= date.frame if date.kind_of?(CalDate)
550
609
  my_options[:clock] = self
551
610
  case date
552
611
  when DateAndTime
553
- return DateAndTime.new(my_options[:frame].to_cal_date(sdn + JulianDate::JD19700101), time+frac, my_options)
612
+ time += frac unless self.kind_of?(When::CalendarTypes::LocalTime)
613
+ DateAndTime.new(my_options[:frame].to_cal_date(sdn + JulianDate::JD19700101), time, my_options)
554
614
  when CalDate
555
- return CalDate.new(my_options[:frame].to_cal_date(date.to_i), my_options)
615
+ CalDate.new(my_options[:frame].to_cal_date(date.to_i), my_options)
556
616
  when JulianDate
557
617
  my_options[:frame] = my_options.delete(:clock)
558
- return JulianDate.universal_time(sdn * Duration::DAY, my_options)
618
+ JulianDate.universal_time(sdn * Duration::DAY, my_options)
559
619
  else
560
620
  raise TypeError, "Irregal (Temporal)Position"
561
621
  end
@@ -616,14 +676,14 @@ module When::TM
616
676
 
617
677
  # 夏時間
618
678
  # @private
619
- def _daylight(zdate=nil, &block)
679
+ def _daylight(time)
620
680
  case @tz_prop
621
681
  when nil ; return self
622
682
  when When::V::TimezoneProperty ; timezone = @tz_prop._pool['..']
623
683
  else ; timezone = @tz_prop
624
684
  end
625
685
  return self unless timezone
626
- return timezone._daylight(zdate, &block)
686
+ return timezone._daylight(time)
627
687
  end
628
688
 
629
689
  # この時法の夏時間-標準時間変化量
@@ -653,6 +713,16 @@ module When::TM
653
713
  When::Coordinates::Index.precision(default || precision)
654
714
  end
655
715
 
716
+ # 丸め量 / When::TM::Duration::SYSTEM
717
+ # @private
718
+ def _round_value(precision)
719
+ offset = When::TM::Duration::DAY / 2
720
+ precision.times do |i|
721
+ offset /= @unit[i+1] ? @unit[i+1] : 10
722
+ end
723
+ offset
724
+ end
725
+
656
726
  private
657
727
 
658
728
  # オブジェクトの正規化
@@ -662,10 +732,14 @@ module When::TM
662
732
  # note
663
733
  @note ||= 'JulianDayNotes'
664
734
 
735
+ # normalize spatial module
736
+ _normalize_spatial
737
+
738
+ # normalize temporal module
665
739
  _normalize_temporal
666
740
 
667
741
  # second
668
- @second = (@second||128).to_f
742
+ @second = (@second||1/When::TM::Duration::SECOND).to_f
669
743
 
670
744
  # zone
671
745
  @zone = Clock.to_hms(@zone || @label || @reference_event)
@@ -674,7 +748,7 @@ module When::TM
674
748
  @time_standard = When.Resource(@time_standard||'UniversalTime', '_t:') unless @time_standard.kind_of?(When::TimeStandard)
675
749
 
676
750
  # utc_reference
677
- @utc_reference ||= @zone ? ClockTime.new(@zone.to_s, {:frame=>When.utc}) : (Clock.local_time || When.utc)
751
+ @utc_reference ||= @zone ? ClockTime.new(@zone.to_s, {:frame=>When.utc}) : Clock.local_time
678
752
 
679
753
  # reference_time & origin_of_LSC
680
754
  case @reference_time
@@ -860,7 +934,12 @@ module When::TM
860
934
  # 処理を @begin (type: When::TM::TemporalPosition) に委譲する
861
935
  #
862
936
  def method_missing(name, *args, &block)
863
- @begin.send(name.to_sym, *args, &block)
937
+ self.class.module_eval %Q{
938
+ def #{name}(*args, &block)
939
+ @begin.send("#{name}", *args, &block)
940
+ end
941
+ } unless When::Parts::MethodCash.escape(name)
942
+ @begin.send(name, *args, &block)
864
943
  end
865
944
  end
866
945
 
@@ -974,7 +1053,7 @@ module When::TM
974
1053
  pool.delete_if {|e|
975
1054
  !parents.each do |parent|
976
1055
  e = e.parent
977
- break false if parent != e.name
1056
+ break false unless parent == e.name
978
1057
  end
979
1058
  }
980
1059
  end
@@ -1311,19 +1390,32 @@ module When::TM
1311
1390
 
1312
1391
  # dating_system
1313
1392
  @dating_system = (@epoch.map {|e| e.frame}).compact.uniq
1393
+ ancestors = hierarchy.inject(['']) {|list,era|
1394
+ list << list[-1] + '::' + era.label.to_s
1395
+ list
1396
+ }
1314
1397
 
1315
1398
  if @epoch.length == 1
1316
1399
  epoch[0].frame.synchronize {
1317
- epoch[0].frame.domain |= When::Parts::GeometricComplex.new([[epoch[0],true]])
1400
+ range = When::Parts::GeometricComplex.new([[epoch[0],true]])
1401
+ ancestors.each do |ancestor|
1402
+ epoch[0].frame.domain[ancestor] |= range
1403
+ end
1318
1404
  } if epoch[0].frame
1319
1405
  elsif reverse?
1320
1406
  epoch[1].frame.synchronize {
1321
- epoch[1].frame.domain |= When::Parts::GeometricComplex.new([[epoch[1],true]], true)
1407
+ range = When::Parts::GeometricComplex.new([[epoch[1],true]], true)
1408
+ ancestors.each do |ancestor|
1409
+ epoch[1].frame.domain[ancestor] |= range
1410
+ end
1322
1411
  } if epoch[1].frame
1323
1412
  else
1324
1413
  (epoch.length-1).times do |i|
1325
1414
  epoch[i].frame.synchronize {
1326
- epoch[i].frame.domain |= When::Parts::GeometricComplex.new([[epoch[i],true], [epoch[i+1],false]])
1415
+ range = When::Parts::GeometricComplex.new([[epoch[i],true], [epoch[i+1],false]])
1416
+ ancestors.each do |ancestor|
1417
+ epoch[i].frame.domain[ancestor] |= range
1418
+ end
1327
1419
  } if epoch[i].frame
1328
1420
  end
1329
1421
  end
@@ -1333,8 +1425,8 @@ module When::TM
1333
1425
  f.reference_frame << self
1334
1426
  f.reference_frame.uniq!
1335
1427
  f.reference_frame.sort!
1336
- first = f.domain.first(When::MinusInfinity)
1337
- last = f.domain.last(When::PlusInfinity)
1428
+ first = f.domain[''].first(When::MinusInfinity)
1429
+ last = f.domain[''].last(When::PlusInfinity)
1338
1430
  f.domain_of_validity = When::EX::Extent.new(
1339
1431
  When::TM::Period.new(
1340
1432
  When::TM::Instant.new(first),
@@ -1562,7 +1654,12 @@ module When::TM
1562
1654
  # 処理を @reference_date (type: When::TM::TemporalPosition) に委譲する
1563
1655
  #
1564
1656
  def method_missing(name, *args, &block)
1565
- @reference_date.send(name.to_sym, *args, &block)
1657
+ self.class.module_eval %Q{
1658
+ def #{name}(*args, &block)
1659
+ @reference_date.send("#{name}", *args, &block)
1660
+ end
1661
+ } unless When::Parts::MethodCash.escape(name)
1662
+ @reference_date.send(name, *args, &block)
1566
1663
  end
1567
1664
  end
1568
1665
  end