Index: /ruby/trunk/lib/open_ehr/am/archetype/constraint_model/primitive.rb
===================================================================
--- /ruby/trunk/lib/open_ehr/am/archetype/constraint_model/primitive.rb	(revision 399)
+++ /ruby/trunk/lib/open_ehr/am/archetype/constraint_model/primitive.rb	(revision 400)
@@ -133,57 +133,48 @@
           end
 
-          class CDate < CPrimitive
+          module CDateModule
             attr_accessor :range, :timezone_validity
             attr_reader :month_validity, :day_validity
 
+            def month_validity=(month_validity)
+              if (month_validity == ValidityKind::OPTIONAL &&
+                  !(@day_validity == ValidityKind::OPTIONAL ||
+                    @day_validity == ValidityKind::DISALLOWED)) ||
+                  (month_validity == ValidityKind::DISALLOWED &&
+                  !(@day_validity == ValidityKind::DISALLOWED))
+                raise ArgumentError, 'month validity disallowed'
+              end
+              @month_validity = month_validity
+            end
+
+            def day_validity=(day_validity)
+              @day_validity = day_validity
+            end
+
+            def validity_is_range?
+              return !@range.nil?
+            end
+
+            private
+            def consistency_validity(month_validity, day_validity)
+            end
+          end
+
+          class CDate < CPrimitive
+            include CDateModule
+
             def initialize(args = { })
               super(args)
               self.range = args[:range]
-              consistency_validity(args[:month_validity], args[:day_validity])
-              @month_validity = args[:month_validity]
-              @day_validity = args[:day_validity]
               self.timezone_validity = args[:timezone_validity]
-            end
-
-            def month_validity=(month_validity)
-              consistency_validity(month_validity, @day_validity)
-              @month_validity = month_validity
-            end
-
-            def day_validity=(day_validity)
-              consistency_validity(@month_validity, day_validity)
-              @day_validity = day_validity
-            end
-
-            def validity_is_range?
-              return !@range.nil?
-            end
-
-            private
-            def consistency_validity(month_validity, day_validity)
-              if (month_validity == ValidityKind::OPTIONAL) &&
-                  !((day_validity == ValidityKind::OPTIONAL) ||
-                    (day_validity == ValidityKind::DISALLOWED))
-                raise ArgumentError, 'month_validity inconsistent'
-              end
-              if (month_validity == ValidityKind::DISALLOWED) &&
-                  !(day_validity == ValidityKind::DISALLOWED)
-                raise ArgumentError, 'month validity disallowed'
-              end
-            end
-          end
-
-          class CTime < CPrimitive
+              self.day_validity = args[:day_validity]
+              self.month_validity = args[:month_validity]
+            end
+          end
+
+          module CTimeModule
             attr_accessor :range
             attr_reader :minute_validity, :second_validity,
                         :millisecond_validity
-
-            def initialize(args = { })
-              super
-              self.range = args[:range]
-              self.millisecond_validity = args[:millisecond_validity]
-              self.second_validity = args[:second_validity]
-              self.minute_validity = args[:minute_validity]
-            end
 
             def minute_validity=(minute_validity)
@@ -215,4 +206,54 @@
             end
           end
+
+          class CTime < CPrimitive
+            include CTimeModule
+
+            def initialize(args = { })
+              super
+              self.range = args[:range]
+              self.millisecond_validity = args[:millisecond_validity]
+              self.second_validity = args[:second_validity]
+              self.minute_validity = args[:minute_validity]
+            end
+          end
+
+          class CDateTime < CPrimitive
+            include CDateModule, CTimeModule
+            attr_reader :hour_validity
+
+            def initialize(args = { })
+              super
+              self.timezone_validity = args[:timezone_validity]
+              self.millisecond_validity = args[:millisecond_validity]
+              self.second_validity = args[:second_validity]
+              self.minute_validity = args[:minute_validity]
+              self.hour_validity = args[:hour_vaildity]
+              self.day_validity = args[:day_validity]
+              self.month_validity = args[:day_validity]
+            end
+
+            def hour_validity=(hour_validity)
+              if (hour_validity == ValidityKind::DISALLOWED &&
+                  @minute_validity != ValidityKind::DISALLOWED) ||
+                  (hour_validity == ValidityKind::OPTIONAL &&
+                   !(@minute_validity == ValidityKind::OPTIONAL ||
+                     @minute_validity == ValidityKind::DISALLOWED))
+                raise ArgumentError, 'hour_validity is invalid'
+              end
+              @hour_validity = hour_validity
+            end
+
+            def day_validity=(day_validity)
+              if (day_validity == ValidityKind::DISALLOWED &&
+                  @hour_validity != ValidityKind::DISALLOWED) ||
+                  (day_validity == ValidityKind::OPTIONAL &&
+                   !(@hour_validity == ValidityKind::OPTIONAL ||
+                     @hour_validity == ValidityKind::DISALLOWED))
+                raise ArgumentError, 'day_validity is invaild'
+              end
+              @day_validity = day_validity
+            end
+          end
         end # of Primitive
       end # of CostraintModel
Index: /ruby/trunk/spec/lib/open_ehr/am/archetype/constraint_model/primitive/c_date_time_spec.rb
===================================================================
--- /ruby/trunk/spec/lib/open_ehr/am/archetype/constraint_model/primitive/c_date_time_spec.rb	(revision 400)
+++ /ruby/trunk/spec/lib/open_ehr/am/archetype/constraint_model/primitive/c_date_time_spec.rb	(revision 400)
@@ -0,0 +1,106 @@
+require File.dirname(__FILE__) + '/../../../../../../spec_helper'
+include OpenEHR::AssumedLibraryTypes
+include OpenEHR::AM::Archetype
+include OpenEHR::AM::Archetype::ConstraintModel::Primitive
+
+describe CDateTime do
+  before(:each) do
+    default_value = ISO8601DateTime.new('2010-01-25T01:23:45.1')
+    assumed_value = ISO8601DateTime.new('2001-12-23T22:02:33.2')
+    range = Interval.new(:lower => ISO8601DateTime.new('1995-04-19T01:01:22'),
+                         :upper => ISO8601DateTime.new('2022-12-31T23:55:59'))
+    @c_date_time =
+      CDateTime.new(:default_value => default_value,
+                    :assumed_value => assumed_value,
+                    :range => range,
+                    :month_validity => ValidityKind::MANDATORY,
+                    :day_validity => ValidityKind::MANDATORY,
+                    :hour_vaildity => ValidityKind::MANDATORY,
+                    :minute_validity => ValidityKind::MANDATORY,
+                    :second_validity => ValidityKind::OPTIONAL,
+                    :millisecond_validity => ValidityKind::DISALLOWED,
+                    :timezone_validity => ValidityKind::OPTIONAL)
+  end
+
+  it 'should be an instance of CDateTime' do
+    @c_date_time.should be_an_instance_of CDateTime
+  end
+
+  it 'hour_validity should be assigned properly' do
+    @c_date_time.hour_validity.should be_equal ValidityKind::MANDATORY
+  end
+
+  it 'should raise ArgumentError if hour_validity is DISALLOWED and minute_validity is not DISALLOWED' do
+    lambda {
+      @c_date_time.hour_validity = ValidityKind::DISALLOWED
+    }.should raise_error ArgumentError
+  end
+
+  it 'should not raise ArgumentError if hour_validity is DISALLOWED and minute_validity is DISALLOWED' do
+    @c_date_time.second_validity = ValidityKind::DISALLOWED
+    @c_date_time.minute_validity = ValidityKind::DISALLOWED
+    lambda {
+      @c_date_time.hour_validity = ValidityKind::DISALLOWED
+    }.should_not raise_error ArgumentError
+  end
+
+  it 'should raise ArgumentError if hour_validity is OPTIONAL and minute_validity is MANDATORY' do
+    lambda {
+      @c_date_time.hour_validity = ValidityKind::OPTIONAL
+    }.should raise_error ArgumentError
+  end
+
+  it 'should not raise ArgumentError if hour_validity is OPTIONAL and minute_validity is OPTIONAL' do
+    @c_date_time.minute_validity = ValidityKind::OPTIONAL
+    lambda {
+      @c_date_time.hour_validity = ValidityKind::OPTIONAL
+    }.should_not raise_error ArgumentError
+  end
+
+  it 'should not raise Argument Error if hour_validity is OPTIONAL and minute_validity is DISALLOWED' do
+    @c_date_time.second_validity = ValidityKind::DISALLOWED
+    @c_date_time.minute_validity = ValidityKind::DISALLOWED
+    lambda {
+      @c_date_time.hour_validity = ValidityKind::OPTIONAL
+    }.should_not raise_error ArgumentError
+  end
+
+  it 'should raise ArgumentError if day_validity is DISALLOWED and hour_validity is not DISALLOWED' do
+    lambda {
+      @c_date_time.day_validity = ValidityKind::DISALLOWED
+    }.should raise_error ArgumentError
+  end
+
+  it 'should not raise ArgumentError if day_validity is DISALLOWED and hour_validity is DISALLOWED' do
+    @c_date_time.second_validity = ValidityKind::DISALLOWED
+    @c_date_time.minute_validity = ValidityKind::DISALLOWED
+    @c_date_time.hour_validity = ValidityKind::DISALLOWED
+    lambda {
+      @c_date_time.day_validity = ValidityKind::DISALLOWED
+    }.should_not raise_error ArgumentError
+  end
+
+  it 'should raise ArgumentError if day_validity is OPTIONAL and hour_validity is MANDATORY' do
+    lambda {
+      @c_date_time.day_validity = ValidityKind::OPTIONAL
+    }.should raise_error ArgumentError
+  end
+
+  it 'should not raise ArgumentError if day_validity OPTIONAL and hour_validity is OPTIONAL' do
+    @c_date_time.second_validity = ValidityKind::DISALLOWED
+    @c_date_time.minute_validity = ValidityKind::DISALLOWED
+    @c_date_time.hour_validity = ValidityKind::OPTIONAL
+    lambda {
+      @c_date_time.day_validity = ValidityKind::OPTIONAL
+    }.should_not raise_error ArgumentError
+  end
+
+  it 'should not raise ArgumentError if day_validity OPTIONAL and hour_validity is DISALLOWED' do
+    @c_date_time.second_validity = ValidityKind::DISALLOWED
+    @c_date_time.minute_validity = ValidityKind::DISALLOWED
+    @c_date_time.hour_validity = ValidityKind::DISALLOWED
+    lambda {
+      @c_date_time.day_validity = ValidityKind::OPTIONAL
+    }.should_not raise_error ArgumentError
+  end
+end
Index: /ruby/trunk/spec/lib/open_ehr/am/archetype/constraint_model/primitive/c_time_spec.rb
===================================================================
--- /ruby/trunk/spec/lib/open_ehr/am/archetype/constraint_model/primitive/c_time_spec.rb	(revision 399)
+++ /ruby/trunk/spec/lib/open_ehr/am/archetype/constraint_model/primitive/c_time_spec.rb	(revision 400)
@@ -3,5 +3,4 @@
 include OpenEHR::AM::Archetype
 include OpenEHR::AM::Archetype::ConstraintModel::Primitive
-
 
 describe CTime do
