编辑DATE字段的一部分以组成日期值

时间:2019-03-07 12:31:50

标签: date rpgle

使用RPGLE的%date()函数时,我可以将通过'2019-01-01'%date('2019-01-01':*ISO)通过'20190202'显示日期的字符串“转换”为日期字段

%date('20190202':*ISO0)

在我当前的数据库中,日期值被分为3个(有时是4个)不同的字段,而不是存储在定义为“日期”的字段中:对于天,部分为On,一个月为1个或2个(取决于年龄)数据库文件的字段),以4位数字表示年份,或以2位数字表示一个字段,以2位数字表示一个字段(2019->存储为'2019'或'20'和'19')

在开始的时候,我努力将3个分区的日期字段与数据结构进行分组,并为我的dcl-s dateISO date(*ISO); dateISO = %date('2019-01-01':*ISO); dsply dateISO; dateISO = %date('20190202':*ISO0); dsply dateISO; DDS)或“使用日期”使用覆盖的“ date-subfield”。 我为自己“发现”了DATE字段的美妙之处,并且可以使用DSPF/PRTF BIF将代表完整日期的数据结构子字段转换为所需的日期字段。但是出于某种原因,我不想为每个“新”日期创建一个新的数据结构。

就像使用%date()来提取DATE或TIMESTAMP的一部分一样,我希望可以编辑DATE字段的一部分。

有人知道怎么做吗?

编辑:

对于所有想要获取部分日期的人:不,我只想编辑(如标题中所述)部分日期。就像我有这样的DDS PF定义:

%subdt()

我的“旧”方式是这样的:

 A          R TESTPFR
 A
 A            T1NUMB         6S 0       TEXT('Some number')
 A            T1TEXT        10A         TEXT('Some text')
 A            T1DTDD         2S 0       TEXT('Day part')
 A            T1DTMM         2S 0       TEXT('Month part')
 A            T1DTYY         4S 0       TEXT('Year part') 

我必须在每个新程序中定义一个数据结构,将PF字段放入子字​​段中并转换覆盖的子字段。在这种情况下,这没有那么多开销。但是,当DSPF涉及到用户在其中输入日期范围时,我不得不为FROM日期,TO日期和数据库中的日期编写一个DS。好的,我承认我可以像上面那样做,只需制作一个DS并将其用于三个日期即可。但是我希望我可以定义一个日期字段并像这样编写代码:

**free
ctl-opt decedit('0,') datedit(*dmy) dftactgrp(*no) option(*nodebugio:*srcstmt:*nounref);

dcl-f testpf disk; // Database File

dcl-ds dateDS qualified; // DS for "converting"
  date zoned(8) pos(1);
  day zoned(2) pos(1);
  month zoned(2) pos(3);
  year zoned(4) pos(5);
end-ds;
dcl-s dateISO date(*ISO); // Destination Date field
dcl-ds testpfrDS likerec(testpfr); // Record definition if the database file


read testpfr testpfrDS;
dow (not %eof(testpf));
  dateDS.day = testpfrDS.t1dtdd ; //t1dtdd is the day field
  dateDs.month = testpfrDS.t1dtmm; //t1dtdd is the month field
  dateDs.year = testpfrDS.t1dtyy; //t1dtdd is the year field

  dateISO = %date(dateDS.date:*EUR);
  dsply dateISO; // Work with the date

  read testpfr testpfrDS;
enddo;

*inlr = *on; 

因此,我不必每次都为日期转换构建DS。

但是,正如@jmarkmurphy回答的那样,我现在想出了一个解决方案,该解决方案具有一个包含三个/四个日期子字段和一个定义为DATE的重叠子字段的DS,因此我不必使用%subdt(dateISO:*day) = testpfrDS.t1dtdd; %subdt(dateISO:*month) = testpfrDS.t1dtmm; %subdt(dateISO:*year) = testpfrDS.t1dtyy;

3 个答案:

答案 0 :(得分:2)

没有允许您编辑日期,时间或时间戳字段的一部分的功能。但是正如您所说,您可以使用数据结构来实现。假设您不想仅出于设置多个日期字段的日值的目的而创建多个数据结构,则可以使用单个“基础”数据结构,如下所示:

dcl-ds DateIso    Qualified Based(%pDateIso);
  year            Signed(4:0) Pos(1);
  month           Signed(2:0) Pos(6);
  day             Signed(2:0) Pos(9);
end-ds;
dcl-s pDateIso    Pointer;

dcl-s startDate   Date(*iso);
dcl-s endDate     Date(*iso);

pDateIso = %addr(startDate);
DateIso.day = 1;

pDateIso = %addr(endDate);
pDateIso.month = 1;

您还可以利用RPGIV创建满足您需要的子过程。

dcl-proc SetDateDay;
  dcl-pi *n Date(*iso);
    date    Date const;
    day     Int(5) const;
  end-pi

  dcl-ds *n;
    dateIso       Date(*iso);
    dateday       Signed(2:0) Pos(9);
  end-ds;

  dateIso = date;
  dateday = day;
  return dateIso;
end-proc;

答案 1 :(得分:1)

我肯定会创建一组过程,以从各个部分创建日期,时间或时间戳。要处理年份可能分为两个部分的事实,请将第四个“ century”参数定义为OPTIONS(* NOPASS),如果未通过,则该过程将期望年份部分具有所有四个数字。

date = makeDate(dd : mm : yy);
or
date = makeDate(dd : mm : yy: cc);

如果您也不想创建一些过程,那么实际上有一种无需任何额外操作的方法:

   date = %date(cc * 1000000 + yy * 10000 + mm * 100 + dd); // untested

但这是一些讨厌的代码...

答案 2 :(得分:0)

您是否要问如何在RPG日期字段中添加或减去天,月,年等?我认为您可能想在这里仔细阅读RPGLE内置函数的列表: https://www.ibm.com/support/knowledgecenter/en/ssw_ibm_i_73/rzasd/bifs.htm

例如,如果您单击%DAYS,它将带您到以下示例:https://www.ibm.com/support/knowledgecenter/en/ssw_ibm_i_73/rzasd/bbmon.htm#bbmon__ebmonths