Schema: date_time_schema

Source : ISO 10303-41



SCHEMA date_time_schema;

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 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 dts_description_attribute_select = SELECT BASED_ON description_attribute_select WITH
   (date_role,
    date_time_role,
    time_role);
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_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 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 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;  -- date_time_schema