I am re-posting the specifications to the news group as the earlier post
(posted on Friday 23 Jan 1997) did not show-up on the 3000-L, due to our
local server problem.
Kishore,
CSY, Bangalore.
.....................................
We would like to thank all of you who have provided feedback to us
(both in 3000-L and through e-mail) on the date intrinsic proposal.
We present the specifications for the new date intrinsics in this
proposal with a view to freeze them.
Some minor changes (syntactic and semantic) are made in the document.
There may still be some that might have eluded our eyes. Please keep
us posted if a major change is required. Some of the changes from the
earlier proposal include:
* An extra optional "cutoff" parameter is added to
HPDATECONVERT.
Through this parameter, the users can specify the year that
should be taken as base for the "split" method. This
parameter is useful *only* when converting the dates with
two-digit year format to those with four-digit year format.
The default value of the parameter is 50. i.e., two digit
years in the range 0..49 would translate to 2000..2049 and
those in the range 50..99 would be translated to 1950..1999.
If the user specifies the "cutoff" year as 70, the mapping
would be 0..69 ----> 2000..2069 and 70..99 ----> 1970..1999.
* The NEVER/UNKNOWN/EXPIRED/INVALID date values are defined
for date type 18 (integer YYYYMMDD) only. All other date
types have been in existence for a while and different
applications might have chosen different values for them.
The values proposed are:
INVALID 00000000
NEVER 00000001
EXPIRED 00000101
UNKNOWN 00000100
The INVALID value maps to ZERO as it is the default value to
which output date is initialized if an error is detected in
an intrinsic. Your suggestions would be most welcome in
choosing values for NEVER/EXPIRED/UNKNOWN dates. We would
like to restrict these values to map into YEAR `0000', which
does not exist.
* The Supported Formats list is not exhaustive. There are
many more formats used by application developers. Date
formats other than those listed in "Supported Formats" can
be added in future.
* The format specification for HPDATEFORMAT is extended to
include "Mon" and "Day" formatting elements.
* Though some of the supported date types (e.g., HPCALENDAR
format) can represent years beyond 9999, we treat years
beyond 9999 as an error case.
* All the intrinsics follow the Georgian calendar (The UNIX
`cal' command generated calendar).
* Error code values are currently being worked on. We would
post them as soon as they are designed.
* All the parameters to the intrinsics can be byte aligned.
* We have attempted to follow the MPE/iX Intrinsics Reference
Manual conventions in using the mnemonics for intrinsic
syntax statements.
We are looking forward to a lively discussion on these specifications.
PROPOSAL
========
The proposed date intrinsics can be broadly categorized as:
1 Intrinsic returning the dates a chosen supported format.
2 Conversion of dates from one supported format to another.
3 Intrinsic to determine the number of days that separate two given
dates.
4 Adding/subtracting an offset (days) to/from the given date.
5 Validating the given date for conformance to a supported date
format.
Supported Formats
=================
The various date types used in MPE/iX are presented in the table
below. These formats are planned to be supported with the date
intrinsics. The `Sorted' and `Y2K ready' fields answer the following
two questions:
1. Can the dates be sorted as they are?
2. Can the format be used to represent dates beyond 31 Dec 1999?
Table 1: Date types
====================
Date
Type Storage
Code Type #Bytes Explanation Sorted? Y2K ready?
----- ------- ------ ----------------------------------- ------- ----------
1 longint 8 MPE time-stamp (microseconds yes yes
since
1970-01-01)
2 integer 4 Upper 2 bytes: year yes yes
next byte: month of year
bottom byte: day of month
3 integer 4 Upper 2 bytes: year yes yes
bottom 2 bytes: day of year
4 integer 4 Upper 23 bits: year yes yes
bottom 9 bits: day of the year.
(analogous to the existing
CALENDAR format.)
10 integer 4 POSIX time-stamp (seconds since yes no
1970-01-01)
14 shortint 2 yyyddd (as defined by the yes yes***
CALENDAR intrinsic)
15 integer 4 YYMMDD date yes no
16 integer 4 MMDDYY date no no
17 integer 4 DDMMYY date no no
18 integer 4 YYYYMMDD date yes yes
25 ASCII 6 YYMMDD date yes no
26 ASCII 6 MMDDYY date no no
27 ASCII 6 DDMMYY date no no
35 ASCII 6 YYMMDD date YY:MM3000 date yes yes
36 ASCII 6 MMDDYY date YY:MM3000 date no no
37 ASCII 6 DDMMYY date YY:MM3000 date no no
38 ASCII 8 YYYYMMDD date yes yes
Notes:
"integer" and "longint" are binary values.
"ASCII" means ASCII character code.
Most of the supported date types are naturally sorted. This
means that if they are viewed as sequence of ASCII bytes, and
arranged in ascending alphabetic order, they are also in
ascending chronological order. An example of this kind of date
is YYMMDD dates.
*** The CALENDAR format is valid up to and including the year
2027. Users are encouraged to use HPCALENDAR instead of
CALENDAR.
User Desired Formats
====================
User desired formats (with restrictions) are allowed. The format
specification strings can have the following syntax:
[{FormatElement}{Punctuation}]+
The valid `FormatElement's are (Many of these elements are taken
from ALLBASE date formats):
CC Century (01 to 99)
YYYY Year (0001 to 9999)
YY Year of century (00 to 99)
ZYY Year of century with leading
zeros suppressed(0 to 99).
Q Quarter of the year (1 to 4)
MM Month of the Year (01 to 12).
ZMM Month of the Year with leading
zeros suppressed (0 to 12).
DD Day of the Month (01 to 31).
ZDD Day of the Month with leading
zero suppressed (1 to 31).
DDD Day of the Year (001 to 366).
ZDDD DDD with leading zeros
suppressed (1 to 366).
D Day of the week (1 to 7) (Monday - 1,
Tuesday - 2, ....).
WW Week of the year (01 to 53).
ZWW Week of the year with leading
zero suppressed (1 to 53).
Mon Month of the year in ASCII
format (ex., Jan, Feb, etc.).
Day Day of the week in ASCII
format (ex., Sun, Mon, etc.).
MON Month of the year in ASCII (uppercase)
format (ex., JAN, FEB, etc.).
DAY Day of the week in ASCII (uppercase)
format (ex., SUN, MON, etc.).
Valid `Punctuation' characters are :
`-' Hyphen
`/' Slash
`.' Dot
` ' Blank
`,' Comma
`' Null
Thus, `YYYY.MON.DAY', `YY/MM/DD', `DDMONYY', and `DD-ZMM-YYYY'
are valid date formats. The date "31 Jan 1997", when formatted
through `DD-ZMM-YYYY' would result in `31-1-1997'. The same date
when formatted through `YYYY.MON.DAY' would result in
`1997.JAN.FRI'.
NOTE: Mixing the NULL punctuation character with other
punctuation characters is *not* allowed. Thus, `YYYY/MM/DD' is a
valid format while `YYYYMM/DD' is not.
Description of New Proposed Intrinsics
======================================
HPCALENDAR
==========
The new HPCALENDAR intrinsic returns the date in the supported date
format 4 listed in Table 1.
SYNTAX
I32
date := HPCALENDAR ;
The upper 23 bits of the returned value represent the year relative to
the year 1900, and it is a signed 23 bit integer. The lower 9 bits
represent the day of the year as an unsigned 9 bit integer.
HPDATECONVERT
=============
This intrinsic would convert the dates from one supported format to
another. While converting dates with two digit year formats to those
with four digit year formats, if a valid optional parameter `cutoff'
is not provided, the century portion would be `19' if the year portion
is >= 50. It would be `20' otherwise.
I32V *V I32V * I32 I32V
HPDATECONVERT(inputcode,inputdate,outputcode,outputdate,status,cutoff)
PARAMETERS
inputcode It is 32 bit integer passed by value.
Its value should be one of the date
type codes listed in TABLE 1. This is
an input parameter.
inputdate The type of this variable depends on
`inputcode' parameter. the data types
for different input codes are listed
in Table listed in TABLE 1. This is
an input parameter.
outputcode This is a 32-bit integer passed by
value and its value should be one of
the date type codes listed in TABLE 1.
outputdate Returns the date as per the format
chosen by the `outputcode' parameter.
The type of this variable depends
`outputcode' parameter.
status The HPE_STATUS parameter through which
the error codes are returned.
cutoff This is an optional integer parameter
passed by value. The value provided
here is used in determining the
century portion of the `outputdate'
when the `inputdate' has a two digit
year and the `outputdate' has four
digit year. In all other cases, this
parameter is ignored. This
parameter's value should be in the
range 0..99. The default value of the
parameter is 50. i.e., two digit
years in the range 0..49 would
translate to 2000..2049 and those in
the range 50..99 would be translated
to 1950..1999. If the user specifies
the "cutoff" year as 70, the mapping
would be
0..69 ----> 2000..2069
and 70..99 ----> 1970..1999.
HPDATEFORMAT
============
This routine can be used to format the dates in ISO8601 format and
variants of it. The syntax is:
I32V CAV CA I32 I32
HPDATEFORMAT(date,formatspec,fmtdate,fmtdatelen,status)
PARAMETERS
date This is an integer parameter passed by
value. It holds the date to be
formatted as per `formatspec'. This
date should be in the format `18'
specified in Table 1.
formatspec This is a character array passed by
value. It should be a NULL terminated
string as per the syntax in the
section ``User Desired Formats''.
fmtdate This is a character array passed by
reference. Its size should be at
least that of formatspec. On return,
it would contain the `date' formatted
as per the `formatspec'.
fmtdatelen This is an integer passed by
reference. On return, it would
contain the number of characters in
`fmtdate' that are filled-in by the
intrinsic.
status The HPE_STATUS parameter through which
the error codes are returned.
Example
=======
{ This is how you might include the date intrinsics }
$standard_level 'modcal'$
$sysintr 'sysintr.pub.sys'$ { date intrinsics would be in `sysintr' itself}
Program test(input,output);
VAR
date1, temp_date : integer;
date2_str : packed array [1..20] of char;
fmt_str : packed array [1..20] of char;
print_str : packed array [1..20] of char;
fmt_len,prt_len : integer;
status : hpe_status;
date1_15,
date2_15 : integer;
begin
date2_str := '960121'; { The YYMMDD date in Supported format `25'. }
date1 := 230196; { The DDMMYY date in Supported format `17'. }
{ Convert `date1' to the YYMMDD integer format.}
HPDATECONVERT(17,date1,15,date1_15,status);
{ Check the `status' appropriately. }
{ Convert the `date2_str' to a YYMMDD integer format.}
HPDATECONVERT(25,date2_str,15,date2_15,status);
{ Check the `status' appropriately. }
{ Let us compare the two dates now.}
temp_date := date1_15 - date2_15;
if( temp_date < 0) then
writeln(date2_str,' is later compared to',date1)
else if (temp_date > 0) then
writeln(date1,' is later compared to',date2_str)
else
writeln(date1,' is same as ',date2_str);
HPDATECONVERT(15,date2_15,18,date2_18,status);
{ Let us use the flexibility in converting the date to
a string. }
fmt_str := 'YY.ZMM.ZDD'#0; { Null terminated string. }
HPDATEFORMAT(date2_18,fmt_str,print_str,print_len,status);
{ Check status appropriately. }
{ print_len would be:7 }
writeln('The converted date is: ',print_str);
{The example is done.}
end.
The expected output from the program is:
230196 is later compared to 960121
The converted date is : 96.1.23
HPDATEDIFF
==========
This intrinsic can be used to determine the number of days that separate
two given dates.
SYNTAX
I32V I32V I32 I32
HPDATEDIFF(firstdate,seconddate,diffindays,status)
PARAMETERS
firstdate The first input date. This is an
integer parameter passed by value.
The date should be in the format `18'
specified in TABLE 1.
seconddate The second input date. This is an
integer parameter passed by value.
The date should be in the format `18'
specified in TABLE 1.
diffindays This is a signed integer parameter
passed by reference. If `firstdate'
is later compared to `seconddate', the
number of days to be added to
`seconddate' to reach `firstdate' is
returned through this parameter. If
`seconddate' is later compared to the
`firstdate', the number of days to be
subtracted from `seconddate' to reach
`firstdate' is returned as a negative
number.
status The HPE_STATUS parameter through which
the error codes are returned.
Example
=======
{ To add. }
date1 := 19970101; { 01 Jan 1997 }
date2 := 19961220; { 20 Dec 1996 }
HPDATEDIFF(date1,date2,delta,status);
{ `delta' will be: +12 }
HPDATEDIFF(date2,date1,delta,status);
{ `delta' will be: -12 }
HPDATEDIFF(date1,date1,delta,status);
{ `delta' is ZERO. }
HPDATEOFFSET
============
This intrinsic can be used to add/subtract a specified offset to/from
the given date.
SYNTAX
I32V I32V I32 I32
HPDATEOFFSET(inputdate,offset,outputdate,status)
PARAMETERS
inputdate The input date is a signed integer and
should be in the format `18' specified
in TABLE 1.
offset A signed integer parameter carrying
the number of days to be added to the
input date. A negative value would
result in a subtraction. This
parameter is passed by value.
outputdate The result of the date addition
operation. It would be in the format
`18' specified in Table 1.
status The HPE_STATUS parameter through which
the error codes are returned.
Example
=======
{ Adding offset. }
date1 := 19960101; { 01 Jan 1996 }
offset := 60; { 60 days. }
HPDATEOFFSET(date1,offset,result1,status);
{ Month of Feb has 29 days in 1996. }
{ The result would be: 19960301 (01 March 1996) }
{ Subtracting offset. }
date1 := 19960121; { 21 Jan 1996 }
offset := -45; { What is the date 45 days earlier. }
HPDATEOFFSET(date1,offset,result2,status);
{ `result2' would be : 19951207 (7 Dec 1995) }
HPFMTCALENDAR
=============
This a new routine to handle HPCALENDAR format. It does the same job
as FMTCALENDAR except that it accepts the 32-bit integer returned by
HPCALENDAR intrinsic. The syntax is:
SYNTAX
I32V CA
HPFMTCALENDAR(date,formatdate)
PARAMETERS
date This is an integer parameter passed by
value. It holds the calendar date, in
the same format as the HPCALENDAR
intrinsic.
formatdate Returns the formatted calendar date in
a 17-character array. If the day of
the month is less than 10, a blank
precedes it, for example,
FRI, JAN 6, 1989
HPNLFMTCALENDAR
===============
This is a new routine to handle HPCALENDAR format. This intrinsic
would be same as the NLFMTCALENDAR except that it accepts the 32-bit
integer returned by the HPCALENDAR intrinsic.
HPNLFMTLONGCAL
==============
This is a new routine to handle HPCALENDAR format. This intrinsic
would be same as the NLFMTLONGCAL except that it accepts the 32-bit
integer returned by the HPCALENDAR intrinsic.
HPDATEVALIDATE
==============
This procedure can be used to check the validity of the given date
with respect to the supported formats given in Table 1.
I32 I32V *V
result := HPDATEVALIDATE(inputcode,inputdate)
PARAMETERS
inputcode It is 32 bit integer passed by value.
Its value should be one of the date
type codes listed in TABLE 1. This is
an input parameter.
inputdate The type of this variable depends on
`inputcode' parameter. the data types
for different input codes are listed
in Table listed in TABLE 1. This is
an input parameter passed by value.
result This is a signed integer returned.
Its value would be `0' if the
`inputdate' conforms to the date
format represented by `inputcode'. If
it is not so, its value would be
positive. If an error has occurred in
evaluating the conformance, its value
would be negative.
Example
=======
var
date1 : packed array [1..20] of char;
poor_date : integer;
result : integer;
date1 := '19961205';
result := HPDATEVALIDATE(38,date1); { result would be `0'. }
date1 := '961205';
result := HPDATEVALIDATE(38,date1); { result would be +ve. (invalid!)}
result := HPDATEVALIDATE(38,poor_date);{ result would be -ve. (error!)}
Before we freeze, we would like to ask the question again:
"Would these intrinsics be meeting your requirements fairly well?"
--
With Best Regards,
Kishore,
CSY R&D India.
mailto:[log in to unmask]
|