(* $Id$ ISO 10303 TC184/SC4/WG12 N8369 EXPRESS Source: ISO 10303-41 ed4 Fundamentals of product description and support - Date time schema The following permission notice and disclaimer shall be included in all copies of this EXPRESS schema ("the Schema"), and derivations of the Schema: Copyright ISO 2014 All rights reserved Permission is hereby granted, free of charge in perpetuity, to any person obtaining a copy of the Schema, to use, copy, modify, merge and distribute free of charge, copies of the Schema for the purposes of developing, implementing, installing and using software based on the Schema, and to permit persons to whom the Schema is furnished to do so, subject to the following conditions: THE SCHEMA IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SCHEMA OR THE USE OR OTHER DEALINGS IN THE SCHEMA. In addition, any modified copy of the Schema shall include the following notice: THIS SCHEMA HAS BEEN MODIFIED FROM THE SCHEMA DEFINED IN ISO 10303-41 ed4 Fundamentals of product description and support - Date time schema AND SHOULD NOT BE INTERPRETED AS COMPLYING WITH THAT STANDARD *) SCHEMA date_time_schema '{iso standard 10303 part(41) version(7) object(1) date_time_schema(7)}'; REFERENCE FROM basic_attribute_schema -- ISO 10303-41 (description_attribute, description_attribute_select, get_description_value); REFERENCE FROM measure_schema -- ISO 10303-41 (measure_with_unit, time_measure_with_unit); REFERENCE FROM support_resource_schema -- ISO 10303-41 (bag_to_set, identifier, label, text); TYPE dts_description_attribute_select = SELECT BASED_ON description_attribute_select WITH ( date_role, date_time_role, time_role); END_TYPE; TYPE ahead_or_behind = ENUMERATION OF (ahead, exact, behind); END_TYPE; TYPE date_time_or_event_occurrence = SELECT (date_time_select, event_occurrence); END_TYPE; TYPE date_time_select = SELECT (date, date_and_time, local_time); END_TYPE; TYPE day_in_month_number = INTEGER; WHERE WR1: {1 <= SELF <= 31}; END_TYPE; TYPE day_in_week_number = INTEGER; WHERE WR1: { 1 <= SELF <= 7 }; END_TYPE; TYPE day_in_year_number = INTEGER; WHERE WR1: {1 <= SELF <= 366}; END_TYPE; TYPE hour_in_day = INTEGER; WHERE WR1: { 0 <= SELF < 24 }; END_TYPE; TYPE minute_in_hour = INTEGER; WHERE WR1: { 0 <= SELF <= 59 }; END_TYPE; TYPE month_in_year_number = INTEGER; WHERE WR1: { 1 <= SELF <= 12 }; END_TYPE; TYPE second_in_minute = REAL; WHERE WR1: { 0 <= SELF < 60.0 }; END_TYPE; TYPE week_in_year_number = INTEGER; WHERE WR1: { 1 <= SELF <= 53 }; END_TYPE; TYPE year_number = INTEGER; WHERE WR1: (SELF > 1581); END_TYPE; ENTITY calendar_date SUBTYPE OF (date); day_component : day_in_month_number; month_component : month_in_year_number; WHERE WR1: valid_calendar_date (SELF); END_ENTITY; ENTITY coordinated_universal_time_offset; hour_offset : INTEGER; minute_offset : OPTIONAL INTEGER; sense : ahead_or_behind; DERIVE actual_minute_offset : INTEGER := NVL(minute_offset,0); WHERE WR1: { 0 <= hour_offset < 24 }; WR2: { 0 <= actual_minute_offset <= 59 }; WR3: NOT (((hour_offset <> 0) OR (actual_minute_offset <>0)) AND (sense = exact)); END_ENTITY; ENTITY date SUPERTYPE OF (ONEOF (calendar_date, ordinal_date, week_of_year_and_day_date, year_month)); year_component : year_number; END_ENTITY; ENTITY date_and_time; date_component : date; time_component : local_time; END_ENTITY; ENTITY date_role; name : label; DERIVE description : text := get_description_value (SELF); WHERE WR1: SIZEOF (USEDIN (SELF, 'BASIC_ATTRIBUTE_SCHEMA.' + 'DESCRIPTION_ATTRIBUTE.DESCRIBED_ITEM')) <= 1; END_ENTITY; ENTITY date_time_role; name : label; DERIVE description : text := get_description_value (SELF); WHERE WR1: SIZEOF (USEDIN (SELF, 'BASIC_ATTRIBUTE_SCHEMA.' + 'DESCRIPTION_ATTRIBUTE.DESCRIBED_ITEM')) <= 1; END_ENTITY; ENTITY event_occurrence; id : identifier; name : label; description : OPTIONAL text; END_ENTITY; ENTITY event_occurrence_context_role; name : label; description : OPTIONAL text; END_ENTITY; ENTITY event_occurrence_relationship; name : label; description : OPTIONAL text; relating_event : event_occurrence; related_event : event_occurrence; END_ENTITY; ENTITY event_occurrence_role; name : label; description : OPTIONAL text; END_ENTITY; ENTITY local_time; hour_component : hour_in_day; minute_component : OPTIONAL minute_in_hour; second_component : OPTIONAL second_in_minute; zone : coordinated_universal_time_offset; WHERE WR1: valid_time (SELF); END_ENTITY; ENTITY ordinal_date SUBTYPE OF (date); day_component : day_in_year_number; WHERE WR1: (NOT leap_year(SELF.year_component) AND { 1 <= day_component <= 365 }) OR (leap_year(SELF.year_component) AND { 1 <= day_component <= 366 }); END_ENTITY; ENTITY relative_event_occurrence SUBTYPE OF (event_occurrence); base_event : event_occurrence; offset : time_measure_with_unit; END_ENTITY; ENTITY time_interval; id : identifier; name : label; description : OPTIONAL text; END_ENTITY; ENTITY time_interval_relationship; name : label; description : OPTIONAL text; relating_time_interval : time_interval; related_time_interval : time_interval; END_ENTITY; ENTITY time_interval_role; name : label; description : OPTIONAL text; END_ENTITY; ENTITY time_interval_with_bounds SUBTYPE OF (time_interval); primary_bound : OPTIONAL date_time_or_event_occurrence; secondary_bound : OPTIONAL date_time_or_event_occurrence; duration : OPTIONAL time_measure_with_unit; WHERE WR1: EXISTS(primary_bound) OR EXISTS(secondary_bound); WR2: NOT (EXISTS(primary_bound) AND EXISTS(secondary_bound) AND EXISTS(duration)); WR3: EXISTS(primary_bound) AND NOT EXISTS(secondary_bound) AND (NOT EXISTS(duration) OR duration_is_positive(duration)); WR4: EXISTS(secondary_bound) AND NOT EXISTS(primary_bound) AND EXISTS(duration) AND duration_is_negative(duration); END_ENTITY; ENTITY time_role; name : label; DERIVE description : text := get_description_value (SELF); WHERE WR1: SIZEOF (USEDIN (SELF, 'BASIC_ATTRIBUTE_SCHEMA.' + 'DESCRIPTION_ATTRIBUTE.DESCRIBED_ITEM')) <= 1; END_ENTITY; ENTITY week_of_year_and_day_date SUBTYPE OF (date); week_component : week_in_year_number; day_component : OPTIONAL day_in_week_number; WHERE WR1: NOT(leap_year(SELF\date.year_component)) OR { 1<= (day_component + (7 * (week_component - 1))) <= 366 }; WR2: leap_year(SELF\date.year_component) OR { 1<= (day_component + (7 * (week_component - 1))) <= 365 }; END_ENTITY; ENTITY year_month SUBTYPE OF (date); month_component : month_in_year_number; END_ENTITY; FUNCTION acyclic_event_occurrence_relationship (relation : event_occurrence_relationship; relatives : SET[1:?] OF event_occurrence; specific_relation : STRING) : BOOLEAN; LOCAL x : SET OF event_occurrence_relationship; END_LOCAL; IF relation.relating_event IN relatives THEN RETURN (FALSE); END_IF; x := QUERY(evnt <* bag_to_set(USEDIN(relation.relating_event, 'DATE_TIME_SCHEMA.' + 'EVENT_OCCURRENCE_RELATIONSHIP.' + 'RELATED_EVENT')) | specific_relation IN TYPEOF(evnt)); REPEAT i := 1 TO HIINDEX(x); IF NOT acyclic_event_occurrence_relationship(x[i], relatives + relation.relating_event, specific_relation) THEN RETURN (FALSE); END_IF; END_REPEAT; RETURN (TRUE); END_FUNCTION; FUNCTION acyclic_time_interval_relationship (relation : time_interval_relationship; relatives : SET[1:?] OF time_interval; specific_relation : STRING) : BOOLEAN; LOCAL x : SET OF time_interval_relationship; END_LOCAL; IF relation.relating_time_interval IN relatives THEN RETURN (FALSE); END_IF; x := QUERY(ti <* bag_to_set(USEDIN(relation.relating_time_interval, 'DATE_TIME_SCHEMA.' + 'TIME_INTERVAL_RELATIONSHIP.' + 'RELATED_TIME_INTERVAL')) | specific_relation IN TYPEOF(ti)); REPEAT i := 1 TO HIINDEX(x); IF NOT acyclic_time_interval_relationship(x[i], relatives + relation.relating_time_interval, specific_relation) THEN RETURN (FALSE); END_IF; END_REPEAT; RETURN (TRUE); END_FUNCTION; FUNCTION duration_is_positive (duration : time_measure_with_unit) : BOOLEAN; IF (duration\measure_with_unit.value_component > 0.0) THEN RETURN (TRUE); ELSE RETURN (FALSE); END_IF; END_FUNCTION; FUNCTION duration_is_negative (duration : time_measure_with_unit) : BOOLEAN; IF (duration\measure_with_unit.value_component < 0.0) THEN RETURN (TRUE); ELSE RETURN (FALSE); END_IF; END_FUNCTION; FUNCTION leap_year (year : year_number) : BOOLEAN; IF ((((year MOD 4) = 0) AND ((year MOD 100) <> 0)) OR ((year MOD 400) = 0)) THEN RETURN (TRUE); ELSE RETURN (FALSE); END_IF; END_FUNCTION; FUNCTION valid_calendar_date (date : calendar_date) : LOGICAL; CASE date.month_component OF 1 : RETURN({ 1 <= date.day_component <= 31 }); 2 : BEGIN IF (leap_year(date.year_component)) THEN RETURN({ 1 <= date.day_component <= 29 }); ELSE RETURN({ 1 <= date.day_component <= 28 }); END_IF; END; 3 : RETURN({ 1 <= date.day_component <= 31 }); 4 : RETURN({ 1 <= date.day_component <= 30 }); 5 : RETURN({ 1 <= date.day_component <= 31 }); 6 : RETURN({ 1 <= date.day_component <= 30 }); 7 : RETURN({ 1 <= date.day_component <= 31 }); 8 : RETURN({ 1 <= date.day_component <= 31 }); 9 : RETURN({ 1 <= date.day_component <= 30 }); 10 : RETURN({ 1 <= date.day_component <= 31 }); 11 : RETURN({ 1 <= date.day_component <= 30 }); 12 : RETURN({ 1 <= date.day_component <= 31 }); END_CASE; RETURN (FALSE); END_FUNCTION; FUNCTION valid_time (time : local_time) : BOOLEAN; IF EXISTS(time.second_component) THEN RETURN (EXISTS(time.minute_component)); ELSE RETURN (TRUE); END_IF; END_FUNCTION; END_SCHEMA;