?? RIGHT := 110 ??
?? NEWTITLE := 'NOS/VE:  Program Management - System Time Requests' ??
MODULE pmm$system_time_requests;

{  PURPOSE:
{    This module contains the routines for the system time requests:
{
{    pmp$get_compact_date_time
{    pmp$get_date_time_at_timestamp
{    pmp$format_compact_date
{    pmp$format_compact_time
{    pmp$get_legible_date_time
{    pmp$get_date
{    pmp$get_time
{    pmp$get_system_time
{    pmp$get_time_zone
{    pmp$get_universal_date_time
{    pmp$get_date_time_defaults
{    pmp$date_time_compare
{

?? NEWTITLE := 'Global Declarations Referenced By This Module', EJECT ??
?? PUSH (LISTEXT := ON) ??
*copyc cle$ecc_lexical
*copyc clt$date_time_form_string
*copyc oss$mainframe_paged_literal
*copyc ost$date
*copyc ost$date_time
*copyc ost$day_of_week
*IF NOT $true(osv$unix)
*copyc ost$free_running_clock
*IFEND
*copyc ost$time
*copyc pme$program_services_exceptions
*copyc pme$system_time_exceptions
*copyc pmt$comparison_result
*copyc pmt$system_time
*copyc pmt$time_increment
*copyc pmt$use_time_zone
?? POP ??
*copyc osp$append_status_integer
*copyc osp$set_status_condition
*copyc pmp$this_is_a_leap_year
*IF $true(osv$unix)
*copyc pmp_get_date_time
*IFEND
?? EJECT ??
*IF NOT $true(osv$unix)
*copyc osv$base_system_time
*IFEND
*copyc osv$os_defaults
?? OLDTITLE ??
?? NEWTITLE := 'Global Declarations Declared by This Module', EJECT ??

  CONST
    c$max_years = 2155; { 1900 + 255

  TYPE
    t$names_of_the_month = RECORD
      name: string (18),
      start_of_day: 0 .. 12,
    RECEND;
?? EJECT ??
  VAR
    v$leap_year: [STATIC, READ, oss$mainframe_paged_literal] ARRAY [1 .. 12] OF
          1 .. 31 := [31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31],

    v$non_leap_year: [STATIC, READ, oss$mainframe_paged_literal] ARRAY [1 .. 12] OF
          1 .. 31 := [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];

  VAR
    v$leap_year_cummulative_days: [STATIC, READ, oss$mainframe_paged_literal] ARRAY [0 .. 12] OF
          0 .. 366 := [0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335, 366],

    v$non_leap_year_cummulat_days: [STATIC, READ, oss$mainframe_paged_literal] ARRAY [0 .. 12] OF
          0 .. 366 := [0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365];

?? FMT (FORMAT := OFF) ??
  VAR
    v$month_names: [STATIC, READ, oss$mainframe_paged_literal] ARRAY [1 .. 12] OF t$names_of_the_month :=
         [['January   ,       ',  9 ],
          ['February   ,      ', 10 ],
          ['March   ,         ',  7 ],
          ['April   ,         ',  7 ],
          ['May   ,           ',  5 ],
          ['June   ,          ',  6 ],
          ['July   ,          ',  6 ],
          ['August   ,        ',  8 ],
          ['September   ,     ', 11 ],
          ['October   ,       ',  9 ],
          ['November   ,      ', 10 ],
          ['December   ,      ', 10 ]];

  VAR
    v$character_equivalent: [STATIC, READ, oss$mainframe_paged_literal] ARRAY [0 .. 99] OF string ( 2 ) :=
         ['00', '01', '02', '03', '04', '05', '06', '07', '08', '09',
          '10', '11', '12', '13', '14', '15', '16', '17', '18', '19',
          '20', '21', '22', '23', '24', '25', '26', '27', '28', '29',
          '30', '31', '32', '33', '34', '35', '36', '37', '38', '39',
          '40', '41', '42', '43', '44', '45', '46', '47', '48', '49',
          '50', '51', '52', '53', '54', '55', '56', '57', '58', '59',
          '60', '61', '62', '63', '64', '65', '66', '67', '68', '69',
          '70', '71', '72', '73', '74', '75', '76', '77', '78', '79',
          '80', '81', '82', '83', '84', '85', '86', '87', '88', '89',
          '90', '91', '92', '93', '94', '95', '96', '97', '98', '99'];

?? FMT (FORMAT:=ON) ??
?? OLDTITLE ??
?? NEWTITLE := '[INLINE] convert_integer_to_rj_string', EJECT ??

  PROCEDURE [INLINE] convert_integer_to_rj_string
    (    intger: integer;
         fill_character: char;
     VAR strng: string ( * ));

    VAR
      int: integer,
      length: integer,
      i: integer;

    int := intger;
    length := STRLENGTH (strng);

    REPEAT
      IF (length <= 0) THEN
        strng := '*******';
        RETURN;
      IFEND;

      strng (length) := $CHAR ((int MOD 10) + $INTEGER ('0'));

      length := length - 1;
      int := int DIV 10;
    UNTIL (int = 0);

    FOR i := 1 TO length DO
      strng (i) := fill_character;
    FOREND;

  PROCEND convert_integer_to_rj_string;
?? OLDTITLE ??
?? NEWTITLE := 'format_compact_date', EJECT ??

  PROCEDURE format_compact_date
    (    date_time: ost$date_time;
     VAR date: ost$date);

    VAR
      convert_year: 0 .. 255, { same as year range in ost$date_time
      ordinal_date: 0 .. (1000 * c$max_years),
      p: 0 .. 63;

    CASE date.date_format OF
    = osc$ordinal_date =
      ordinal_date := 1900 + date_time.year;
      IF pmp$this_is_a_leap_year (ordinal_date) THEN
        ordinal_date := (ordinal_date * 1000) + v$leap_year_cummulative_days [date_time.month - 1] +
              date_time.day;
      ELSE
        ordinal_date := (ordinal_date * 1000) + v$non_leap_year_cummulat_days [date_time.month - 1] +
              date_time.day;
      IFEND;

      convert_integer_to_rj_string (ordinal_date, '0', date.ordinal);

    = osc$month_date =
      date.month := v$month_names [date_time.month].name;
      p := v$month_names [date_time.month].start_of_day;
      date.month (p, 2) := v$character_equivalent [date_time.day];
      convert_integer_to_rj_string ((date_time.year + 1900), ' ', date.month (p + 4, 4));
      IF date_time.day < 10 THEN
        date.month (p - 1, * ) := date.month (p, * );
        date.month (p - 1) := ' ';
      IFEND;

    = osc$mdy_date =
      date.mdy := '**/**/**';
      date.mdy (1, 2) := v$character_equivalent [date_time.month];
      date.mdy (4, 2) := v$character_equivalent [date_time.day];
      convert_year := date_time.year;
      WHILE convert_year > 99 DO
        convert_year := convert_year - 100;
      WHILEND;
      date.mdy (7, 2) := v$character_equivalent [convert_year];

    = osc$dmy_date =
      date.dmy := '**.**.**';
      date.dmy (1, 2) := v$character_equivalent [date_time.day];
      date.dmy (4, 2) := v$character_equivalent [date_time.month];
      convert_year := date_time.year;
      WHILE convert_year > 99 DO
        convert_year := convert_year - 100;
      WHILEND;
      date.dmy (7, 2) := v$character_equivalent [convert_year];

    ELSE { = osc$iso_date =
      date.iso := '****-**-**';
      convert_integer_to_rj_string ((date_time.year + 1900), '0', date.iso (1, 4));
      date.iso (6, 2) := v$character_equivalent [date_time.month];
      date.iso (9, 2) := v$character_equivalent [date_time.day];

    CASEND;

  PROCEND format_compact_date;
?? OLDTITLE ??
?? NEWTITLE := 'format_compact_time', EJECT ??

  PROCEDURE format_compact_time
    (    date_time: ost$date_time;
         time_form_string: clt$date_time_form_string;
     VAR time {input output} : ost$time);

    CASE time.time_format OF
    = osc$ampm_time =
      IF date_time.hour < 12 THEN
        time.ampm := ' *:** AM';
        IF date_time.hour = 0 THEN
          time.ampm (1, 2) := '12';
        ELSE
          time.ampm (1, 2) := v$character_equivalent [date_time.hour];
          IF (date_time.hour < 10) THEN
            time.ampm (1) := ' ';
          IFEND;
        IFEND;
      ELSE
        time.ampm := ' *:** PM';
        IF date_time.hour = 12 THEN
          time.ampm (1, 2) := '12';
        ELSE
          time.ampm (1, 2) := v$character_equivalent [date_time.hour - 12];
          IF ((date_time.hour - 12) < 10) THEN
            time.ampm (1) := ' ';
          IFEND;
        IFEND;
      IFEND;

      time.ampm (4, 2) := v$character_equivalent [date_time.minute];

    = osc$hms_time =
      time.hms := '**:**:**';
      time.hms (1, 2) := v$character_equivalent [date_time.hour];
      time.hms (4, 2) := v$character_equivalent [date_time.minute];
      time.hms (7, 2) := v$character_equivalent [date_time.second];

    ELSE { = osc$millisecond_time =
      IF time_form_string = 'ISOT' THEN
        time.millisecond := '**.**.**,** ';
        time.millisecond (1, 2) := v$character_equivalent [date_time.hour];
        time.millisecond (4, 2) := v$character_equivalent [date_time.minute];
        time.millisecond (7, 2) := v$character_equivalent [date_time.second];
        convert_integer_to_rj_string (date_time.millisecond DIV 10, '0', time.millisecond (10, 2));
      ELSE
        time.millisecond := '**:**:**.***';
        time.millisecond (1, 2) := v$character_equivalent [date_time.hour];
        time.millisecond (4, 2) := v$character_equivalent [date_time.minute];
        time.millisecond (7, 2) := v$character_equivalent [date_time.second];
        convert_integer_to_rj_string (date_time.millisecond, '0', time.millisecond (10, 3));
      IFEND;
    CASEND;

  PROCEND format_compact_time;
?? OLDTITLE ??
?? NEWTITLE := '[INLINE] validate_date_format', EJECT ??

  PROCEDURE [INLINE] validate_date_format
    (    date_format: ost$date_formats;
     VAR validated_date_format: ost$date_formats;
     VAR status: ost$status);

    status.normal := TRUE;

    CASE date_format OF
    = osc$ordinal_date, osc$month_date, osc$mdy_date, osc$dmy_date, osc$iso_date =
      validated_date_format := date_format;

    = osc$default_date =
      validated_date_format := osv$os_defaults.system_date_format.date_format;

    ELSE
      osp$set_status_condition (pme$invalid_date_format, status);
    CASEND;

  PROCEND validate_date_format;
?? OLDTITLE ??
?? NEWTITLE := '[INLINE] validate_time_format', EJECT ??

  PROCEDURE [INLINE] validate_time_format
    (    time_format: ost$time_formats;
     VAR validated_time_format: ost$time_formats;
     VAR format_string: clt$date_time_form_string;
     VAR status: ost$status);

    status.normal := TRUE;

    CASE time_format OF
    = osc$ampm_time =
      validated_time_format := time_format;
      format_string := 'AMPM';

    = osc$hms_time =
      validated_time_format := time_format;
      format_string := 'HMS';

    = osc$millisecond_time =
      validated_time_format := time_format;
      format_string := 'MS';

    = osc$default_time =
      validated_time_format := osv$os_defaults.system_time_format.time_format;
      format_string := osv$os_defaults.system_time_format.format_string;

    ELSE
      osp$set_status_condition (pme$invalid_time_format, status);
    CASEND;

  PROCEND validate_time_format;
?? OLDTITLE ??
?? NEWTITLE := '[XDCL, #GATE] pmp$date_time_compare', EJECT ??
*copy pmh$date_time_compare

  PROCEDURE [XDCL, #GATE] pmp$date_time_compare
    (    left_operand: ost$date_time;
         right_operand: ost$date_time;
     VAR comparison_result: pmt$comparison_result;
     VAR status: ost$status);

    pmp$verify_compact_date (left_operand, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    pmp$verify_compact_time (left_operand, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    pmp$verify_compact_date (right_operand, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    pmp$verify_compact_time (right_operand, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    comparison_result := pmc$equal;

    IF left_operand.year < right_operand.year THEN
      comparison_result := pmc$right_is_greater;
    ELSEIF left_operand.year > right_operand.year THEN
      comparison_result := pmc$left_is_greater;
    ELSEIF left_operand.month < right_operand.month THEN
      comparison_result := pmc$right_is_greater;
    ELSEIF left_operand.month > right_operand.month THEN
      comparison_result := pmc$left_is_greater;
    ELSEIF left_operand.day < right_operand.day THEN
      comparison_result := pmc$right_is_greater;
    ELSEIF left_operand.day > right_operand.day THEN
      comparison_result := pmc$left_is_greater;
    IFEND;

    IF (comparison_result = pmc$equal) THEN
      IF left_operand.hour < right_operand.hour THEN
        comparison_result := pmc$right_is_greater;
      ELSEIF left_operand.hour > right_operand.hour THEN
        comparison_result := pmc$left_is_greater;
      ELSEIF left_operand.minute < right_operand.minute THEN
        comparison_result := pmc$right_is_greater;
      ELSEIF left_operand.minute > right_operand.minute THEN
        comparison_result := pmc$left_is_greater;
      ELSEIF left_operand.second < right_operand.second THEN
        comparison_result := pmc$right_is_greater;
      ELSEIF left_operand.second > right_operand.second THEN
        comparison_result := pmc$left_is_greater;
      ELSEIF left_operand.millisecond < right_operand.millisecond THEN
        comparison_result := pmc$right_is_greater;
      ELSEIF left_operand.millisecond > right_operand.millisecond THEN
        comparison_result := pmc$left_is_greater;
      IFEND;
    IFEND;

  PROCEND pmp$date_time_compare;
?? OLDTITLE ??
?? NEWTITLE := '[XDCL, #GATE] pmp$format_compact_date', EJECT ??
*copy pmh$format_compact_date

  PROCEDURE [XDCL, #GATE] pmp$format_compact_date
    (    date_time: ost$date_time;
         format: ost$date_formats;
     VAR date: ost$date;
     VAR status: ost$status);

    pmp$verify_compact_date (date_time, status);

    IF status.normal THEN
      validate_date_format (format, date.date_format, status);

      IF status.normal THEN
        format_compact_date (date_time, date);
      IFEND;
    IFEND;

  PROCEND pmp$format_compact_date;
?? OLDTITLE ??
?? NEWTITLE := '[XDCL, #GATE] pmp$format_compact_time', EJECT ??
*copy pmh$format_compact_time

  PROCEDURE [XDCL, #GATE] pmp$format_compact_time
    (    date_time: ost$date_time;
         format: ost$time_formats;
     VAR time: ost$time;
     VAR status: ost$status);

    VAR
      time_form_string: string (clc$max_date_time_form_string);

    pmp$verify_compact_time (date_time, status);

    IF status.normal THEN
      validate_time_format (format, time.time_format, time_form_string, status);

      IF status.normal THEN
        format_compact_time (date_time, time_form_string, time);
      IFEND;
    IFEND;

  PROCEND pmp$format_compact_time;
?? OLDTITLE ??
?? NEWTITLE := '[XDCL, #GATE] pmp$get_compact_date_time', EJECT ??
*copy pmh$get_compact_date_time

  PROCEDURE [XDCL, #GATE] pmp$get_compact_date_time
    (VAR date_time: ost$date_time;
     VAR status: ost$status);

*IF NOT $true(osv$unix)
    pmp$get_date_time_at_timestamp (#FREE_RUNNING_CLOCK (0), pmc$use_system_local_time, date_time, status);
*ELSE
    VAR
      hour: integer,
      ignore_isdst: integer,
      ignore_wday: integer,
      ignore_yday: integer,
      mday: integer,
      min: integer,
      month: integer,
      sec: integer,
      wday: integer,
      yday: integer,
      year: integer;


    status.normal := TRUE;
    pmp_get_date_time (sec, min, hour, mday, month, year, wday, yday,
          ignore_isdst);

    date_time.millisecond := 0;
    date_time.second := sec;
    date_time.minute := min;
    date_time.hour := hour;
    date_time.day := mday;
    date_time.month := month + 1;
    date_time.year := year;

    pmp$verify_compact_date (date_time, status);
    IF status.normal THEN
      pmp$verify_compact_time (date_time, status);
    IFEND;

*IFEND

  PROCEND pmp$get_compact_date_time;
?? OLDTITLE ??
?? NEWTITLE := '[XDCL, #GATE] pmp$get_date', EJECT ??
*copy pmh$get_date

  PROCEDURE [XDCL, #GATE] pmp$get_date
    (    date_format: ost$date_formats;
     VAR date: ost$date;
     VAR status: ost$status);

    VAR
      date_time: ost$date_time;

    validate_date_format (date_format, date.date_format, status);

    IF status.normal THEN
      pmp$get_compact_date_time (date_time, status);

      IF status.normal THEN
        format_compact_date (date_time, date);
      IFEND;
    IFEND;

  PROCEND pmp$get_date;
?? OLDTITLE ??
*IF NOT $true(osv$unix)
?? NEWTITLE := '[XDCL, #GATE] pmp$get_date_time_at_timestamp', EJECT ??
*copy pmh$get_date_time_at_timestamp

  PROCEDURE [XDCL, #GATE] pmp$get_date_time_at_timestamp
    (    timestamp: integer;
         time_zone: pmt$use_time_zone;
     VAR date_time: ost$date_time;
     VAR status: ost$status);

    CONST
      c$ms_per_day = 24 * 60 * 60 * 1000;

    VAR
      base_system_time: ost$base_system_time,
      day: integer,
      days_in_the_month_p: ^ARRAY [1 .. 12] OF 1 .. 31,
      elapsed_time: integer,
      hour: -1 .. 47,
      minute: -30 .. 119,
      month: 1 .. 13,
      second: 0 .. 119,
      system_time_zone: ost$time_zone,
      year: 0 .. c$max_years;

    status.normal := TRUE;

    system_time_zone := osv$os_defaults.system_time_zone;
    base_system_time := osv$base_system_time;

    elapsed_time {ms} := (timestamp {us} - base_system_time.corresponding_microsecond_clock {us}) DIV 1000
          {us/ms};

    elapsed_time := elapsed_time + (base_system_time.hour * 3600 + base_system_time.minute *
          60 + base_system_time.second) * 1000;
    IF time_zone = pmc$use_universal_time THEN
      elapsed_time := elapsed_time - (system_time_zone.hours_from_gmt *
            3600 + system_time_zone.minutes_offset * 60) * 1000;
      IF system_time_zone.daylight_saving_time THEN
        elapsed_time := elapsed_time - 3600 * 1000;
      IFEND;
    IFEND;

    day := base_system_time.day + (elapsed_time DIV c$ms_per_day);
    elapsed_time := elapsed_time MOD c$ms_per_day;
    IF elapsed_time < 0 THEN
      elapsed_time := elapsed_time + c$ms_per_day;
      day := day - 1;
    IFEND;

    date_time.millisecond := elapsed_time {ms} MOD 1000 {ms} ;

    elapsed_time {sec} := elapsed_time {ms} DIV 1000 {ms/sec} ;
    date_time.second := elapsed_time {sec} MOD 60 {sec} ;

    elapsed_time {min} := elapsed_time {sec} DIV 60 {sec/min} ;
    date_time.minute := elapsed_time {min} MOD 60 {min} ;

    elapsed_time {hr} := elapsed_time {min} DIV 60 {min/hr} ;
    date_time.hour := elapsed_time {hr} MOD 24 {hr} ;

    month := base_system_time.month;
    year := base_system_time.year;

    IF pmp$this_is_a_leap_year (year) THEN
      days_in_the_month_p := ^v$leap_year;
    ELSE
      days_in_the_month_p := ^v$non_leap_year;
    IFEND;

    WHILE day < 1 DO
      IF month = 1 THEN
        month := 13;
        IF (year - 1 {yr} ) < LOWERVALUE (year) THEN
          osp$set_status_condition (pme$computed_year_out_of_range, status);
          RETURN;
        IFEND;
        year := year - 1;
        IF pmp$this_is_a_leap_year (year) THEN
          days_in_the_month_p := ^v$leap_year;
        ELSE
          days_in_the_month_p := ^v$non_leap_year;
        IFEND;
      IFEND;
      month := month - 1;
      day := day + days_in_the_month_p^ [month];
    WHILEND;

    WHILE day > days_in_the_month_p^ [month] DO
      day := day - days_in_the_month_p^ [month];
      month := month + 1 {mo} ;

      IF month > 12 {mo} THEN
        IF (year + 1 {yr} ) > UPPERVALUE (year) THEN
          osp$set_status_condition (pme$computed_year_out_of_range, status);
          RETURN;
        IFEND;

        month := 1 {mo} ;
        year := year + 1 {yr} ;

        IF pmp$this_is_a_leap_year (year) THEN
          days_in_the_month_p := ^v$leap_year;
        ELSE
          days_in_the_month_p := ^v$non_leap_year;
        IFEND;
      IFEND;
    WHILEND;

    date_time.day := day;
    date_time.month := month;
    date_time.year := year - 1900;

  PROCEND pmp$get_date_time_at_timestamp;
?? OLDTITLE ??
*IFEND
?? NEWTITLE := '[XDCL, #GATE] pmp$get_default_date_time_form', EJECT ??
*copy pmh$get_default_date_time_form

  PROCEDURE [XDCL, #GATE] pmp$get_default_date_time_form
    (VAR date_default: ost$default_date_format;
     VAR time_default: ost$default_time_format);

    date_default := osv$os_defaults.system_date_format;
    time_default := osv$os_defaults.system_time_format;

  PROCEND pmp$get_default_date_time_form;
?? OLDTITLE ??
?? NEWTITLE := '[XDCL, #GATE] pmp$get_legible_date_time', EJECT ??
*copy pmh$get_legible_date_time

  PROCEDURE [XDCL, #GATE] pmp$get_legible_date_time
    (    date_format: ost$date_formats;
     VAR date: ost$date;
         time_format: ost$time_formats;
     VAR time: ost$time;
     VAR status: ost$status);

    VAR
      date_time: ost$date_time,
      time_form_string: string (clc$max_date_time_form_string);

    validate_date_format (date_format, date.date_format, status);

    IF status.normal THEN
      validate_time_format (time_format, time.time_format, time_form_string, status);

      IF status.normal THEN
        pmp$get_compact_date_time (date_time, status);

        IF status.normal THEN
          format_compact_time (date_time, time_form_string, time);
          format_compact_date (date_time, date);
        IFEND;
      IFEND;
    IFEND;

  PROCEND pmp$get_legible_date_time;
?? OLDTITLE ??
*IF NOT $true(osv$unix)
?? NEWTITLE := '[XDCL] pmp$get_system_time', EJECT ??
*copy pmh$get_system_time

  PROCEDURE [XDCL] pmp$get_system_time
    (VAR system_time: pmt$system_time;
     VAR status: ost$status);

    VAR
      date_time: ost$date_time;

    system_time.free_running_clock := #FREE_RUNNING_CLOCK (0);
    pmp$get_date_time_at_timestamp (system_time.free_running_clock, pmc$use_system_local_time, date_time,
          status);
    IF status.normal THEN
      system_time.year := date_time.year + 1900;
      system_time.month := date_time.month;
      system_time.day := date_time.day;
      system_time.hour := date_time.hour;
      system_time.minute := date_time.minute;
      system_time.second := date_time.second;
      system_time.millisecond := date_time.millisecond;
    IFEND;

  PROCEND pmp$get_system_time;
?? OLDTITLE ??
*IFEND
?? NEWTITLE := '[XDCL, #GATE] pmp$get_time', EJECT ??
*copy pmh$get_time

  PROCEDURE [XDCL, #GATE] pmp$get_time
    (    time_format: ost$time_formats;
     VAR time: ost$time;
     VAR status: ost$status);

    VAR
      date_time: ost$date_time,
      time_form_string: string (clc$max_date_time_form_string);

    validate_time_format (time_format, time.time_format, time_form_string, status);

    IF status.normal THEN
      pmp$get_compact_date_time (date_time, status);

      IF status.normal THEN
        format_compact_time (date_time, time_form_string, time);
      IFEND;
    IFEND;

  PROCEND pmp$get_time;
?? OLDTITLE ??
?? NEWTITLE := '[XDCL, #GATE] pmp$get_time_zone', EJECT ??
*copy pmh$get_time_zone

  PROCEDURE [XDCL, #GATE] pmp$get_time_zone
    (VAR time_zone: ost$time_zone;
     VAR status: ost$status);

    status.normal := TRUE;
    time_zone := osv$os_defaults.system_time_zone;

  PROCEND pmp$get_time_zone;
?? OLDTITLE ??
*IF NOT $true(osv$unix)
?? NEWTITLE := '[XDCL, #GATE] pmp$get_universal_date_time', EJECT ??
*copy pmh$get_universal_date_time

  PROCEDURE [XDCL, #GATE] pmp$get_universal_date_time
    (VAR universal_date_time: ost$date_time;
     VAR status: ost$status);

    pmp$get_date_time_at_timestamp (#FREE_RUNNING_CLOCK (0), pmc$use_universal_time, universal_date_time,
          status);

  PROCEND pmp$get_universal_date_time;
?? OLDTITLE ??
*IFEND
?? NEWTITLE := '[XDCL, #GATE] pmp$verify_compact_date', EJECT ??

  PROCEDURE [XDCL, #GATE] pmp$verify_compact_date
    (    date: ost$date_time;
     VAR status: ost$status);

    status.normal := TRUE;

    IF (date.year < LOWERVALUE (date.year)) OR (date.year > UPPERVALUE (date.year)) THEN
      osp$set_status_condition (pme$invalid_year, status);
      osp$append_status_integer (osc$status_parameter_delimiter, date.year, 10, FALSE, status);
      RETURN;
    IFEND;

    IF (date.month < 1) OR (date.month > 12) THEN
      osp$set_status_condition (pme$invalid_month, status);
      osp$append_status_integer (osc$status_parameter_delimiter, date.month, 10, FALSE, status);
      RETURN;
    IFEND;

    IF pmp$this_is_a_leap_year (date.year + 1900 {yr} ) THEN
      IF (date.day < 1) OR (date.day > v$leap_year [date.month]) THEN
        osp$set_status_condition (pme$invalid_day, status);
        osp$append_status_integer (osc$status_parameter_delimiter, date.year, 10, FALSE, status);
        osp$append_status_integer (osc$status_parameter_delimiter, date.month, 10, FALSE, status);
        osp$append_status_integer (osc$status_parameter_delimiter, date.day, 10, FALSE, status);
        RETURN;
      IFEND;
    ELSE
      IF (date.day < 1) OR (date.day > v$non_leap_year [date.month]) THEN
        osp$set_status_condition (pme$invalid_day, status);
        osp$append_status_integer (osc$status_parameter_delimiter, date.year, 10, FALSE, status);
        osp$append_status_integer (osc$status_parameter_delimiter, date.month, 10, FALSE, status);
        osp$append_status_integer (osc$status_parameter_delimiter, date.day, 10, FALSE, status);
        RETURN;
      IFEND;
    IFEND;

  PROCEND pmp$verify_compact_date;
?? OLDTITLE ??
?? NEWTITLE := '[XDCL, #GATE] pmp$verify_compact_time', EJECT ??

  PROCEDURE [XDCL, #GATE] pmp$verify_compact_time
    (    time: ost$date_time;
     VAR status: ost$status);

    status.normal := TRUE;

    IF time.millisecond > 999 THEN
      osp$set_status_condition (pme$invalid_millisecond, status);
      osp$append_status_integer (osc$status_parameter_delimiter, time.millisecond, 10, FALSE, status);
      RETURN;
    IFEND;

    IF time.second > 59 THEN
      osp$set_status_condition (pme$invalid_second, status);
      osp$append_status_integer (osc$status_parameter_delimiter, time.second, 10, FALSE, status);
      RETURN;
    IFEND;

    IF time.minute > 59 THEN
      osp$set_status_condition (pme$invalid_minute, status);
      osp$append_status_integer (osc$status_parameter_delimiter, time.minute, 10, FALSE, status);
      RETURN;
    IFEND;

    IF time.hour > 23 THEN
      osp$set_status_condition (pme$invalid_hour, status);
      osp$append_status_integer (osc$status_parameter_delimiter, time.hour, 10, FALSE, status);
      RETURN;
    IFEND;
  PROCEND pmp$verify_compact_time;
?? OLDTITLE ??
MODEND pmm$system_time_requests;
