Gen EDGE

 View Only

  • 1.  CURRENT_TIMESTAMP in C Code

    Posted Feb 27, 2026 08:57 AM

    The CURRENT_TIMESTAMP function in C code in Gen is the only deployment language that still only supports retrieving the timestamp down to millisecond precision (i.e. 3 digits in the sub second portion of the timestamp).  All other supported languages - COBOL, JAVA, C# - retrieve the CURRENT_TIMESTAMP with microsecond precision - 6 digits.   I've created an idea to update the CURRENT_TIMESTAMP function to return microsecond precision like for the other supported languages.  While I wait to see if that idea gets prioritized into a PTF, we will look at changing all of our existing code base replacing the CURRENT_TIMESTAMP Gen function with a view variable that is set using inline code.  Not ideal as it negates one of the benefits of using Gen which is the portability of action diagram code from one architecture to another.

    I thought I'd ask in the community if anyone had already written this C inline code to retrieve the current date and time to microsecond precision in Windows and would be willing to share that code.  We can do the research and find a solution but thought I'd check here first.

    Thanks !



    ------------------------------
    Thanks
    ------------------------------


  • 2.  RE: CURRENT_TIMESTAMP in C Code

    Posted Mar 31, 2026 05:43 PM

    For anyone that needs it ............... We had a developer who figured out the C code needed to return the current timestamp value down to the microsecond into a timestamp attribute view.    The following is the INLINE code we are using for this.  It compiles and runs as both 32 bit and 64 bit code for Windows, C, IEFAE implementation.   It returns the value into an Export Workset view named  DATE_ATTRIBUTES_WORK  and the attribute name is WORK_DATE_TIME

    /* ---- BEGIN DECLARATIONS ---- */
    /* Minimal WinAPI types & prototypes to avoid <windows.h> inside inline code */

    typedef unsigned long DWORD;
    typedef long          LONG;
    typedef unsigned short WORD;
    typedef void*         PVOID;
    typedef void*         HMODULE;

    typedef struct _FILETIME { DWORD dwLowDateTime; DWORD dwHighDateTime; } FILETIME;
    typedef struct _SYSTEMTIME {
      WORD wYear; WORD wMonth; WORD wDayOfWeek; WORD wDay;
      WORD wHour; WORD wMinute; WORD wSecond; WORD wMilliseconds;
    } SYSTEMTIME;

    /* Import core APIs (stdcall) */
    __declspec(dllimport) HMODULE __stdcall GetModuleHandleA(const char*);
    __declspec(dllimport) PVOID   __stdcall GetProcAddress(HMODULE, const char*);
    __declspec(dllimport) void    __stdcall GetSystemTimeAsFileTime(FILETIME*);
    __declspec(dllimport) int     __stdcall FileTimeToLocalFileTime(const FILETIME*, FILETIME*);
    __declspec(dllimport) int     __stdcall FileTimeToSystemTime(const FILETIME*, SYSTEMTIME*);

    /* Optional: mscrt formatting (reduces warnings) */
    #include <stdio.h>

    /* Pointer type for Windows precise system time */
    typedef void (__stdcall *PFN_GetSTPAFT)(FILETIME*);

    /* ---- END DECLARATIONS ---- */


    /* ---- BEGIN EXECUTABLE STATEMENTS ---- */

    FILETIME ftUTC;
    HMODULE hKernel = GetModuleHandleA("kernel32.dll");
    PFN_GetSTPAFT pPrecise = NULL;
    if (hKernel) {
        pPrecise = (PFN_GetSTPAFT)GetProcAddress(hKernel, "GetSystemTimePreciseAsFileTime");
    }
    if (pPrecise) {
        pPrecise(&ftUTC);  /* Windows 8+ precise clock (~1µs resolution) */
    } else {
        GetSystemTimeAsFileTime(&ftUTC); /* Fallback (~15.6ms granularity on older systems) */
    }

    /* Compute microseconds within the second from 100ns ticks */

    unsigned long long t100ns = (((unsigned long long)ftUTC.dwHighDateTime << 32) | ftUTC.dwLowDateTime);
    const unsigned long long EPOCH_DIFF_100NS = 116444736000000000ULL;
    unsigned long long unix100ns = t100ns - EPOCH_DIFF_100NS;

    /* microseconds in the current second */

    long t_usec = (long)((unix100ns % 10000000ULL) / 10ULL);

    /* Convert UTC FILETIME to local SYSTEMTIME for date/time fields */

    FILETIME ftLocal;
    SYSTEMTIME stLocal;
    (void)FileTimeToLocalFileTime(&ftUTC, &ftLocal);
    (void)FileTimeToSystemTime(&ftLocal, &stLocal);

    /* Format: YYYY-MM-DD-HH.MM.SS.ffffff, TEXT TIMESTAMP */

    char ts[40];

    /* sprintf(ts, "%04u-%02u-%02u-%02u.%02u.%02u.%06ld",
            (unsigned)stLocal.wYear, (unsigned)stLocal.wMonth, (unsigned)stLocal.wDay,
            (unsigned)stLocal.wHour, (unsigned)stLocal.wMinute, (unsigned)stLocal.wSecond,
            t_usec); */

    /* Format: YYYYMMDDHHMMSSffffff */

    sprintf(ts, "%04u%02u%02u%02u%02u%02u%06ld",
            (unsigned)stLocal.wYear, (unsigned)stLocal.wMonth, (unsigned)stLocal.wDay,
            (unsigned)stLocal.wHour, (unsigned)stLocal.wMinute, (unsigned)stLocal.wSecond,
            t_usec);

    /* Assign Timestamp to CA Gen Export Attribute */

    strcpy(##EXPORT.DATE_ATTRIBUTES_WORK.WORK_DATE_TIME##, ts);

    /* ---- END EXECUTABLE STATEMENTS ---- */



    ------------------------------
    Thanks
    ------------------------------