Index: ruby/trunk/lib/models/assumed_library_types.rb
===================================================================
--- ruby/trunk/lib/models/assumed_library_types.rb	(revision 119)
+++ ruby/trunk/lib/models/assumed_library_types.rb	(revision 120)
@@ -2,4 +2,5 @@
 require 'date'
 require 'time'
+require 'parsedate'
 
 module OpenEHR
@@ -109,28 +110,16 @@
     end # end of TIME_DEFINITIONS
 
-    class ISO8601_DATE < TIME_DEFINITIONS
+    module ISO8601_DATE_MODULE
       attr_reader :year, :month, :day
-      def initialize(year = nil, month = nil, day = nil)
-        @year = @month = @day = nil
-        if !year.nil?
-          self.year = year
-        end
-        if !month.nil?
-          self.month = month
-        end
-        if !day.nil?
-          self.day = day
-        end
-      end
       def year=(year)
-        raise ArgumentError, "Year is not valid" if !ISO8601_DATE.valid_year?(year)
+        raise ArgumentError, "Year is not valid" unless ISO8601_DATE.valid_year?(year)
         @year = year
       end
       def month=(month)
-        raise ArgumentError, "Month is not valid" if !ISO8601_DATE.valid_month?(month)
+        raise ArgumentError, "Month is not valid" unless month.nil? or ISO8601_DATE.valid_month?(month)
         @month = month
       end
       def day=(day)
-        raise ArgumentError, "Day is not valid" if !ISO8601_DATE.valid_day?(@year, @month, day)
+        raise ArgumentError, "Day is not valid" unless day.nil? or ISO8601_DATE.valid_day?(@year, @month, day)
         @day = day
       end
@@ -156,4 +145,26 @@
         month_unknown? or day_unknown?
       end
+    end
+
+    class ISO8601_DATE < TIME_DEFINITIONS
+      include ISO8601_DATE_MODULE
+      def initialize(string)
+        /(\d{4})(?:-(\d{2})(?:-(\d{2})?)?)?/ =~ string
+        if $1.nil?
+          raise ArgumentError, 'data invalid'
+        else
+          self.year = $1.to_i
+        end
+        if $2.nil?
+          self.month = nil
+        else
+          self.month = $2.to_i
+        end
+        if $3.nil?
+          self.day = nil
+        else
+          self.day = $3.to_i
+        end
+      end
       def self.valid_iso8601_date?(string)
         begin
@@ -164,14 +175,9 @@
         true
       end
-
     end # end of ISO8601_DATE
 
-    class ISO8601_TIME < TIME_DEFINITIONS
+    module ISO8601_TIME_MODULE
       attr_reader :hour, :minute, :second, :fractional_second, :timezone
-      def initialize(hh, mm = nil, ss = nil, msec = nil, tz = nil)
-        raise ArgumentError, "Not valid hour format" if !ISO8601_TIME.valid_hour?(hh,mm,ss)
-        @hour = hh; @minute = mm; @second = ss
-        @fractional_second = msec; @timezone = tz
-      end
+
       def hour=(hour)
         raise ArgumentError, "hour is not valid" if !ISO8601_TIME.valid_hour?(hour, @minute, @second)
@@ -189,12 +195,12 @@
       end
       def second=(second)
-        raise ArgumentError, "minute not defined" if @minute.nil?
+        raise ArgumentError, "minute not defined" if @minute.nil? and !second.nil?
         raise ArgumentError, "second is not valid" if !second.nil? and !ISO8601_TIME.valid_second?(second)
         @second = second
       end
       def fractional_second=(fractional_second)
-        raise ArgumentError, "minute not defined" if minute_unknown?
-        raise ArgumentError, "second not defined" if second_unknown?
-        raise ArgumentError, "fractional second should be lower than 1.0" if fractional_second >= 1.0
+        raise ArgumentError, "minute not defined" if minute_unknown? and !fractional_second.nil?
+        raise ArgumentError, "second not defined" if second_unknown? and !fractional_second.nil?
+        raise ArgumentError, "fractional second should be lower than 1.0" if !fractional_second.nil? and fractional_second >= 1.0
         @fractional_second = fractional_second
       end
@@ -204,4 +210,15 @@
         else
           return true
+        end
+      end
+      def timezone=(timezone)
+        unless timezone.nil? or timezone == 'Z'
+          if /[+-](\d{2}):?(\d{2})/ =~ timezone
+            @timezone = timezone
+          else
+            raise ArgumentError, "timezone invalid"
+          end
+        else
+          @timezone = nil
         end
       end
@@ -231,4 +248,36 @@
         s
       end
+    end
+
+    class ISO8601_TIME < TIME_DEFINITIONS
+      include ISO8601_TIME_MODULE
+      def initialize(string)
+        /(\d{2}):?(\d{2})?(:?)(\d{2})?((\.|,)(\d+))?(Z|([+-](\d{2}):?(\d{2})))?/ =~ string
+        if $2.nil?
+          self.minute = nil
+        else
+          self.minute = $2.to_i
+        end
+        if $4.nil?
+          self.second = nil
+        else
+          self.second = $4.to_i
+        end
+        if $1.nil?
+          raise ArgumentError, 'data invalid'
+        else
+          self.hour = $1.to_i
+        end
+        if $7.nil?
+          self.fractional_second = nil
+        else
+          self.fractional_second = ("0." + $7).to_f
+        end
+        if $8.nil?
+          self.timezone = nil
+        else
+          self.timezone = $8
+        end
+      end
       def self.valid_iso8601_time?(s)
         if /(\d{2}):?(\d{2})?(:?)(\d{2})?((\.|,)(\d+))?(Z|([+-](\d{2}):?(\d{2})))?/ =~ s
@@ -273,4 +322,51 @@
     end # end of ISO8601_TIME
 
+    class ISO8601_DATE_TIME < ISO8601_DATE
+      include ISO8601_DATE_MODULE, ISO8601_TIME_MODULE
+      def initialize(string)
+        /(\d{4})(?:-(\d{2})(?:-(\d{2})(?:T(\d{2}):(\d{2})(?::(\d{2})(?:\.(\d))?)?(Z|([+-]\d{2}):(\d{2}))?)?)?)?/ =~ string
+        if $1.empty?
+          raise ArgumentError, 'format invalid'
+        else
+          self.year = $1.to_i
+        end
+        if $2.nil?
+          self.month = nil
+        else
+          self.month = $2.to_i
+        end
+        if $3.nil?
+          self.day = nil
+        else
+          self.day = $3.to_i
+        end
+        if $5.nil?
+          self.minute = nil
+        else
+          self.minute = $5.to_i
+        end
+        if $6.nil?
+          self.second = nil
+        else
+          self.second = $6.to_i
+        end
+        if $4.nil?
+          self.hour = nil
+        else
+          self.hour = $4.to_i
+        end
+        if $7.nil?
+          self.fractional_second = nil
+        else
+          self.fractional_second = ("0."+$7).to_f
+        end
+        if $8.nil?
+          self.timezone = nil
+        else
+          self.timezone = $8+$9+$10
+        end
+      end
+    end
+
     class ISO8601_TIMEZONE
       attr_accessor :sign, :hour, :minute
Index: ruby/trunk/lib/models/rm/data_types/quantity.rb
===================================================================
--- ruby/trunk/lib/models/rm/data_types/quantity.rb	(revision 119)
+++ ruby/trunk/lib/models/rm/data_types/quantity.rb	(revision 120)
@@ -58,4 +58,7 @@
           end
         end
+
+        autoload :Date_Time, "rm/data_types/quantity/date_time.rb"
+        
       end # of Quantity
     end # of Data_Types
Index: ruby/trunk/lib/models/rm/data_types/quantity/date_time.rb
===================================================================
--- ruby/trunk/lib/models/rm/data_types/quantity/date_time.rb	(revision 119)
+++ ruby/trunk/lib/models/rm/data_types/quantity/date_time.rb	(revision 120)
@@ -7,7 +7,25 @@
       module Quantity
         module Date_Time
+          class DV_Temporal < OpenEHR::RM::Data_Types::Quantity::DV_Absolute_Quantity
+            attr_reader :value
+            def initialize(value)
+              self.value = value
+            end
+            def value=(value)
+              if value.empty? or value.nil?
+                raise ArgumentError, 'invalid value'
+              end
+              @value = value
+            end
+            def diff(value)
+              raise NotImplementedError, 'diff must be implemented'
+            end
+          end
+
           class DV_Date < DV_Temporal
+            def initialize
+            end
           end
-        end
+        end # of Date_Time
       end # of Quantity
     end # of Data_Types
Index: ruby/trunk/lib/models/tests/rm/test_data_types.rb
===================================================================
--- ruby/trunk/lib/models/tests/rm/test_data_types.rb	(revision 119)
+++ ruby/trunk/lib/models/tests/rm/test_data_types.rb	(revision 120)
@@ -159,2 +159,15 @@
   end
 end
+
+class QuantityDateTimeTest < Test::Unit::TestCase
+  def setup
+    assert_nothing_raised(Exception){@dv_temporal = OpenEHR::RM::Data_Types::Quantity::Date_Time::DV_Temporal.new('2008')}
+  end
+  def test_init
+    assert_instance_of OpenEHR::RM::Data_Types::Quantity::Date_Time::DV_Temporal, @dv_temporal
+  end
+  def test_dv_temporal
+    assert_equal '2008', @dv_temporal.value
+    assert_raise(NotImplementedError){@dv_temporal.diff('2009')}
+  end
+end
Index: ruby/trunk/lib/models/tests/test_assumed_library_types.rb
===================================================================
--- ruby/trunk/lib/models/tests/test_assumed_library_types.rb	(revision 119)
+++ ruby/trunk/lib/models/tests/test_assumed_library_types.rb	(revision 120)
@@ -6,6 +6,8 @@
     assert_nothing_raised(Exception){@interval = OpenEHR::Assumed_Library_Types::Interval.new(1,2)}
     assert_nothing_raised(Exception){@time_definition = OpenEHR::Assumed_Library_Types::TIME_DEFINITIONS.new}
-    assert_nothing_raised(Exception){@iso8601_date = OpenEHR::Assumed_Library_Types::ISO8601_DATE.new}
-    assert_nothing_raised(Exception){@iso8601_time = OpenEHR::Assumed_Library_Types::ISO8601_TIME.new(1)}
+    assert_nothing_raised(Exception){@iso8601_date = OpenEHR::Assumed_Library_Types::ISO8601_DATE.new('2009-04-27')}
+    assert_nothing_raised(Exception){@iso8601_time = OpenEHR::Assumed_Library_Types::ISO8601_TIME.new('15:55:37.32+0900')}
+    assert_nothing_raised(Exception){@iso8601_date_time = OpenEHR::Assumed_Library_Types::ISO8601_DATE_TIME.new('2009-04-27T15:55:37.32+0900')}
+#    assert_nothing_raised(Exception){@iso8601_duration = OpenEHR::Assumed_Library_Types::ISO8601_DURATION.new()}
     assert_nothing_raised(Exception){@iso8601_timezone = OpenEHR::Assumed_Library_Types::ISO8601_TIMEZONE.new}
   end
@@ -15,4 +17,5 @@
     assert_instance_of OpenEHR::Assumed_Library_Types::ISO8601_DATE, @iso8601_date
     assert_instance_of OpenEHR::Assumed_Library_Types::ISO8601_TIME, @iso8601_time
+    assert_instance_of OpenEHR::Assumed_Library_Types::ISO8601_DATE_TIME, @iso8601_date_time
     assert_instance_of OpenEHR::Assumed_Library_Types::ISO8601_TIMEZONE, @iso8601_timezone
   end
@@ -62,5 +65,5 @@
   end
 
-  def test_date_time_valid
+  def test_time_definition_validity
     assert OpenEHR::Assumed_Library_Types::TIME_DEFINITIONS.valid_year?(2008)
     assert !OpenEHR::Assumed_Library_Types::TIME_DEFINITIONS.valid_year?(-20)
@@ -161,4 +164,8 @@
   end
   def test_iso8601_date
+    assert_equal 2009, @iso8601_date.year
+    assert_equal 4,@iso8601_date.month
+    assert_equal 27,@iso8601_date.day
+    assert_nothing_raised(Exception){@iso8601_date = OpenEHR::Assumed_Library_Types::ISO8601_DATE.new('2008')}
     assert @iso8601_date.day_unknown?
     assert @iso8601_date.month_unknown?
@@ -166,5 +173,4 @@
     assert @iso8601_date.is_extended?
     assert_nothing_raised(Exception){@iso8601_date.year = 2008}
-    assert_equal 2008, @iso8601_date.year 
     assert_raise(ArgumentError){@iso8601_date.year = -1}
     assert_equal "2008", @iso8601_date.as_string
@@ -187,4 +193,13 @@
 
   def test_iso8601_time
+    assert_equal 15, @iso8601_time.hour
+    assert_equal 55, @iso8601_time.minute
+    assert_equal 37, @iso8601_time.second
+    assert_equal 0.32, @iso8601_time.fractional_second
+    assert_equal '+0900', @iso8601_time.timezone
+
+#    assert_nothing_raised(Exception){@iso8601_time = OpenEHR::Assumed_Library_Types::ISO8601_TIME.new('15:55:37.32+0900')}
+
+    assert_nothing_raised(Exception){@iso8601_time = OpenEHR::Assumed_Library_Types::ISO8601_TIME.new('01')}
     assert_equal 1, @iso8601_time.hour
     assert @iso8601_time.is_partial?
@@ -240,4 +255,11 @@
     assert !OpenEHR::Assumed_Library_Types::ISO8601_TIME.valid_iso8601_time?("240000.011Z")
   end
+
+  def test_iso_8601_date_time
+    assert_equal 2009, @iso8601_date_time.year
+    
+#    assert_nothing_raised(Exception){@iso8601_date_time = OpenEHR::Assumed_Library_Types::ISO8601_DATE_TIME.new('2009-04-27T15:55:37.32+0900')}
+  end
+
   def test_iso8601_timezone
     @iso8601_timezone.sign = "+1"
