when_exe 0.3.2 → 0.3.3

Sign up to get free protection for your applications and to get access to all the features.
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