Introduction

Oracle GoldenGate 23ai is a powerful solution for real-time data replication, offering seamless handling of date and timestamp data types in heterogeneous environments. While GoldenGate manages these data types by default, specific use cases may require custom manipulation.

GoldenGate 23ai provides robust column-conversion functions — @DATE, @DATEDIFF, @DATENOW, and the new @DBFUNCTION to transform and process date and time data. This article explores these functions with practical examples, highlighting their application in Oracle GoldenGate 23ai’s Microservices Architecture.

Overview of Date Functions

Oracle GoldenGate 23ai offers four key functions for working with dates and timestamps:

  • @DATE: Converts and formats date or time data based on specified input and output formats.
  • @DATEDIFF: Calculates the difference between two dates or timestamps, returning results in days or seconds.
  • @DATENOW: Retrieves the current date and time of the target system.
  • @DBFUNCTION: Invokes database functions or stored procedures during replication, enabling dynamic data manipulation.

To demonstrate these functions, we’ll use a sample Oracle source table defined as:

CREATE TABLE source_schema.dt (
    col_rownum    NUMBER(38),
    col_unix_time NUMBER(38),
    col_date      DATE,
    col_timestamp TIMESTAMP(6),
    PRIMARY KEY (col_rownum)
);

The Oracle GoldenGate 23ai Extract configuration (using Microservices Architecture) is:

EXTRACT epdborcl
USERIDALIAS ggalias
EXTTRAIL as
LOGALLSUPCOLS
REPORTCOUNT EVERY 5 MINUTES, RATE
TABLE dbcsash_pdb1.source_schema.*;

 Note: GoldenGate 23ai no longer supports Classic Architecture; Microservices Architecture is required.

 

Using @DATENOW and @DATEDIFF

@DATENOW

The @DATENOW function returns the current date and time in the format YYYY-MM-DD HH:MI:SS, adjusted for local time and Daylight-Saving Time. It requires no arguments and is invoked as @DATENOW().

@DATEDIFF

The @DATEDIFF function computes the difference between two dates or timestamps, returning results in days (DD) or seconds (SS). Its syntax is:

@DATEDIFF(‘DD | SS’, ‘date1’, ‘date2’)

Here, date1 and date2 can be static dates, timestamps, or @DATENOW().

Example:

We’ll replicate data to a target table defined as:

CREATE TABLE target_schema.dt_tgt1 (
    col_rownum      NUMBER(38),
    col_date        DATE,
    col_timestamp   TIMESTAMP(6),
    gg_datenow      TIMESTAMP(6),
    gg_datediff_ss  NUMBER(15),
    gg_datediff_dd  NUMBER(15),
    PRIMARY KEY (col_rownum)
);

 The Replicat configuration is:

REPLICAT rtpcc
USERIDALIAS ggalias
SOURCECATALOG dbcsash_pdb1
MAP source_schema.dt, TARGET target_schema.dt1,
COLMAP (
    USEDEFAULTS,
    gg_datenow = @DATENOW(),
    gg_datediff_ss = @DATEDIFF(‘SS’, ‘1933-01-05’, @DATENOW()),
    gg_datediff_dd = @DATEDIFF(‘DD’, ‘1933-01-05’, @DATENOW())
);

Insert a source row:

INSERT INTO source_schema.dt
VALUES (1, 1499794843, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP);
COMMIT;

 Query the target table:

SQL> select * from target_schema.dt_tgt1;

COL_ROWNUM COL_DATE   COL_TIMESTAMP                  GG_DATENOW                      GG_DATEDIFF_SS   GG_DATEDIFF_DD
———- ———- —————————— ——————————  ————–   ————–
         1 07-MAY-25  07-MAY-25 02.34.46.574743 PM   07-MAY-25 03.17.15.000000 PM        2913895035            33725

Explanation:

  • COL_ROWNUM, COL_DATE, and COL_TIMESTAMP is directly replicated from the source table.
  • GG_DATENOW captures the target server’s date and time when the Replicat processes the record from the Oracle GoldenGate trail.
  • GG_DATEDIFF_SS and GG_DATEDIFF_DD calculate the difference between January 5, 1933 (the start of Golden Gate Bridge construction) and the current server date and time, in seconds and days, respectively.
  • The @DATEDIFF calculation for days (DD) excludes the end day (e.g., it uses May 6, 2025, as the end date). To include the end day, modify the COLMAP statement in the Replicat configuration as follows: gg_datediff_dd =  @datediff (‘DD’, ‘1933-01-05’, @DATENOW () + 1)
  • When using seconds (SS) in @DATEDIFF, the computation is based on timestamps.

For example:

Start date: 1933-01-05 00:00:00

End date:   2025-05-07 03:17:15 PM

 

Using @DATE

The @DATE function transforms date or time data into various formats, converts inputs to valid SQL dates, extracts date components, or computes numeric timestamps. Its syntax is:

@DATE(‘output_format’, ‘input_format’, source_column)

For format descriptors, refer to the Oracle GoldenGate 23ai Documentation.

Example

We’ll use a target table with multiple date-derived columns:

CREATE TABLE target_schema.dt_tgt2 (
    col_rownum      CHAR(38),
    col_date        DATE,
    col_timestamp   TIMESTAMP(6),
    gg_ts_unix_time TIMESTAMP(6),
    gg_century      CHAR(2),
    gg_yyyy         CHAR(4),
    gg_mm           CHAR(2),
    gg_mmm          CHAR(3),
    gg_dd           CHAR(2),
    gg_ddd          CHAR(3),
    gg_dowa         CHAR(3),
    gg_hh           CHAR(2),
    gg_mi           CHAR(2),
    gg_ss           CHAR(2),
    gg_ff           CHAR(6),
    gg_jts          CHAR(11),
    gg_jul          CHAR(5),
    PRIMARY KEY (col_rownum)
);

The Replicat configuration is:

REPLICAT rtpcc
USERIDALIAS ggalias
SOURCECATALOG dbcsash_pdb1
MAP source_schema.dt, TARGET target_schema.dt_tgt2,
COLMAP (
    USEDEFAULTS,
    gg_ts_unix_time = @DATE(‘YYYY-MM-DD HH:MI:SS.FFFFFF’, ‘CDATE’, col_unix_time),
    gg_century = @DATE(‘CC’, ‘YYYY-MM-DD’, col_date),
    gg_yyyy = @DATE(‘YYYY’, ‘YYYY-MM-DD’, col_date),
    gg_mm = @DATE(‘MM’, ‘YYYY-MM-DD’, col_date),
    gg_mmm = @DATE(‘MMM’, ‘YYYY-MM-DD’, col_date),
    gg_dd = @DATE(‘DD’, ‘YYYY-MM-DD’, col_date),
    gg_ddd = @DATE(‘DDD’, ‘YYYY-MM-DD’, col_date),
    gg_dowa = @DATE(‘DOWA’, ‘YYYY-MM-DD’, col_date),
    gg_hh = @DATE(‘HH’, ‘YYYY-MM-DD HH:MI:SS.FFFFFF’, col_timestamp),
    gg_mi = @DATE(‘MI’, ‘YYYY-MM-DD HH:MI:SS.FFFFFF’, col_timestamp),
    gg_ss = @DATE(‘SS’, ‘YYYY-MM-DD HH:MI:SS.FFFFFF’, col_timestamp),
    gg_ff = @DATE(‘FFFFFF’, ‘YYYY-MM-DD HH:MI:SS.FFFFFF’, col_timestamp),
    gg_jts = @DATE(‘JTS’, ‘YYYY-MM-DD HH:MI:SS.FFFFFF’, col_timestamp),
    gg_jul = @DATE(‘JUL’, ‘YYYY-MM-DD HH:MI:SS.FFFFFF’, col_timestamp)
);

Insert source data:

INSERT INTO source_schema.dt

VALUES (2, 1499871217, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP);

COMMIT;

Query the target table for col_rownum = 2:

SELECT * FROM target_schema.dt_tgt2 WHERE col_rownum = ‘2’;

pic1

Explanation:

  • GG_TS_UNIX_TIME converts col_unix_time to a timestamp.
  • Columns like GG_YYYY, GG_MMM, and GG_DOWA extract specific date components.
  • GG_JTS and GG_JUL provide Julian timestamp representations.

 

Using @DBFUNCTION

Introduced in GoldenGate 23ai, @DBFUNCTION allows invoking database functions or stored procedures during replication, enabling dynamic data processing. This is helpful for applications that are tracking the database timestamp, time-sensitive operations, or ETL loads where the Apply Time of the DML operation within the database is needed.

For more information, refer to the Oracle GoldenGate 23ai Documentation.

Example

We’ll use @DBFUNCTION to apply this formatting in the target table:

CREATE TABLE target_schema.dt_tgt3 (
    col_rownum                NUMBER(38),
    col_date                  DATE,
    col_timestamp             TIMESTAMP(6),
    col_datenow               TIMESTAMP(6),
    col_systemtimestamp       TIMESTAMP(6),
    col_systemtimestamp_char  NUMBER(38),
    PRIMARY KEY (col_rownum)
);

The Replicat configuration is:

 

REPLICAT rtpcc
USERIDALIAS ggalias
SOURCECATALOG dbcsash_pdb1
MAP source_schema.dt, TARGET target_schema.dt_tgt3,
COLMAP (
    USEDEFAULTS,
    COL_DATENOW = @DATENOW(),
    COL_SYSTEMTIMESTAMP = @DBFUNCTION(‘SYSTIMESTAMP’),
    COL_SYSTEMTIMESTAMP_CHAR = @DBFUNCTION(‘TO_CHAR(SYSTIMESTAMP,”YYYYMMDDHHMISSFFFFFF”)’)
);

Insert a source row:

INSERT INTO source_schema.dt VALUES (3, 1499871164, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP);

COMMIT;

Query the target table:

SELECT * FROM target_schema.dt_tgt3;

Output:

COL_ROWNUM

COL_DATE

COL_TIMESTAMP

COL_DATENOW

COL_SYSTEMTIMESTAMP

COL_SYSTEMTIMESTAMP_CHAR

3

07-May-25

07-MAY-25 05.11.46.729429 PM

08-MAY-25 06.18.56.000000 AM

08-MAY-25 06.18.56.477147 AM

20250508061856477147477147477147

Explanation:

  • With @DBFUNCTION(‘SYSTIMESTAMP’) you can get precise timestamp for the system
  • Also use Database function TO_CHAR to convert system time to number format

 

Real-World Example

Consider a customer requiring three additional columns in the target table, leveraging 23ai’s features:

CREATE TABLE target_schema.dt_tgt (
    col_rownum    NUMBER(38),
    col_unix_time NUMBER(38),
    col_date      DATE,
    col_timestamp TIMESTAMP(6),
    create_date   NUMBER(14),
    update_date   NUMBER(14),
    update_ts     TIMESTAMP(6),
    PRIMARY KEY (col_rownum)
);

Requirements:

  • For inserts, populate create_date with the current timestamp in YYYYMMDDHHMISS format (as a number).

  • For all operations, populate update_date with the current timestamp in YYYYMMDDHHMISS format (as a number)..
  • For all operations, populate update_ts with the Julian timestamp of the target server.

Solution:

The Replicat configuration is:

replicat rtpcc
useridalias ggalias
sourcecatalog dbcsash_pdb1
MAP source_schema.dt, TARGET target_schema.dt_tgt,
colmap (usedefaults,

— If the operation is an insert, take the current date and convert it to a number
— with a format of yyyymmddhhmiss
create_date = @CASE (
@GETENV (‘GGHEADER’, ‘OPTYPE’), ‘INSERT’, @NUMSTR (
@STRCAT (
@STREXT (@DATENOW(),1,4),
@STREXT (@DATENOW(),6,7),
@STREXT (@DATENOW(),9,10),
@STREXT (@DATENOW(),12,13),
@STREXT (@DATENOW(),15,16),
@STREXT (@DATENOW(),18,19)
)),
@COLSTAT (MISSING)
),

— For all operations, take the current date and convert it to a number
— with a format of yyyymmddhhmiss
update_date = @NUMSTR ( @STRCAT (
@STREXT (@DATENOW(),1,4),
@STREXT (@DATENOW(),6,7),
@STREXT (@DATENOW(),9,10),
@STREXT (@DATENOW(),12,13),
@STREXT (@DATENOW(),15,16),
@STREXT (@DATENOW(),18,19)
)
),
update_ts = @date (‘YYYY-MM-DD HH:MI:SS.FFFFFFFFF’, ‘JTS’, @getenv(‘JULIANTIMESTAMP’) )
);

Insert and update source data:

 

INSERT INTO source_schema.dt VALUES (4, 1499871164, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP);
COMMIT;
UPDATE source_schema.dt SET col_unix_time = 1499871217, col_timestamp = CURRENT_TIMESTAMP WHERE col_rownum = 4;
COMMIT;

Output (example):

COL_ROWNUM

COL_UNIX_TIME

COL_DATE

COL_TIMESTAMP

CREATE_DATE

UPDATE_DATE

UPDATE_TS

4

1499871164

08-May-25

08-MAY-25 10.53.09.786765 AM

20250508105316

20250508105316

08-MAY-25 10.53.16.921234921 AM

             
             

COL_ROWNUM

COL_UNIX_TIME

COL_DATE

COL_TIMESTAMP

CREATE_DATE

UPDATE_DATE

UPDATE_TS

4

1499871217

08-May-25

08-MAY-25 10.54.33.523181 AM

20250508105316

20250508105439

08-MAY-25 10.54.39.967529967 AM

 

Alternative: Use @DBFUNCTION

Replicat configuration:

REPLICAT rtpcc
USERIDALIAS ggalias
sourcecatalog dbcsash_pdb1
MAP source_schema.dt, TARGET target_schema.dt_tgt,
COLMAP (
    USEDEFAULTS,
    create_date = @CASE(
        @GETENV(‘GGHEADER’, ‘OPTYPE’), ‘INSERT’,
        @DBFUNCTION (‘TO_CHAR(SYSTIMESTAMP, ”YYYYMMDDHHMISS”)’),
        @COLSTAT(MISSING)
    ),
    update_date = @DBFUNCTION (‘TO_CHAR(SYSTIMESTAMP, ”YYYYMMDDHHMISS”)’),
    update_ts = @DBFUNCTION(‘TO_CHAR(SYSTIMESTAMP,”YYYYMMDDHHMISSFFFFFF”)’)
);

Insert source data:

INSERT INTO source_schema.dt VALUES (6, 1499871164, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP);
COMMIT;

UPDATE source_schema.dt SET col_unix_time = 1499871217, col_timestamp = CURRENT_TIMESTAMP WHERE col_rownum = 6;
COMMIT;

This approach minimizes complexity using @DBFUNCTION.

Output (example):

COL_ROWNUM

COL_UNIX_TIME

COL_DATE

COL_TIMESTAMP

CREATE_DATE

UPDATE_DATE

UPDATE_TS

6

1499871164

08-May-25

08-MAY-25 12.09.20.197742 PM

20250508120925

20250508120925

08-MAY-25 12.09.25.346415346 PM

             
             

COL_ROWNUM

COL_UNIX_TIME

COL_DATE

COL_TIMESTAMP

CREATE_DATE

UPDATE_DATE

UPDATE_TS

6

1499871217

08-May-25

08-MAY-25 12.09.37.188526 PM

20250508120925

20250508120942

08-MAY-25 12.09.42.365727365 PM

 

Conclusion

Oracle GoldenGate 23ai’s @DATE, @DATEDIFF, @DATENOW, and @DBFUNCTION functions provide flexible tools for date and timestamp manipulation.

For more resources, visit the Oracle GoldenGate 23ai Documentation.