DateTimeDiff precision issues in Architect expressions for same-day comparisons

How should I properly to handle date comparisons in Architect when the target logic requires distinguishing between events that occurred earlier today versus those from previous days?

I am building a Data Action that needs to flag messages received within the last 24 hours differently from older messages. The standard approach seems to be using DateTimeDiff, but I am hitting a wall with precision.

My current expression looks like this:

{
 "expression": "DateTimeDiff(TimestampOfMessage, Now(), 'hours') < 24"
}

The problem is that DateTimeDiff appears to return an integer value representing the completed difference. If a message was sent 23 hours and 59 minutes ago, DateTimeDiff returns 23, which passes the check. However, if I need to compare against a specific time of day-say, ensuring a message isn’t older than the current calendar day regardless of hour-the integer truncation causes logic failures.

I tried using GetDayOfWeek to check if the day matches, but that only helps with day-of-week logic, not day-of-month or specific date boundaries. For example:

{
 "expression": "GetDayOfWeek(TimestampOfMessage) == GetDayOfWeek(Now())"
}

This fails completely when the message was sent yesterday but it is still the same day of the week (e.g., two Mondays apart).

Is there a hidden function or a specific format string I can pass to DateTimeDiff to get sub-day precision, or should I be parsing the timestamp into components manually using DatePart? I want to avoid complex nested IF statements if possible. The documentation is sparse on whether DateTimeDiff supports decimal returns or if it is strictly integer-based.

Precision matters here. We are seeing false negatives in our routing logic because of this truncation. Any examples of robust date comparison patterns in Architect that handle same-day versus next-day boundaries cleanly?

The documentation actually says DateTimeDiff returns an integer count of the specified unit, which truncates sub-unit precision. This causes logic failures when comparing timestamps within the same day if you rely on hours without accounting for the remainder.

Stop using string-based date parsing in Architect. It is brittle and slow. Switch to epoch milliseconds for deterministic comparison. It avoids timezone conversion errors inherent in DateTimeDiff.

Use this Data Action configuration:

{
 "operation": "set",
 "target": "isRecent",
 "value": "{{ currentTimeMillis - eventTimestampMillis < 86400000 }}"
}

86400000 is exactly 24 hours in milliseconds. This boolean check is atomic. It handles same-day edge cases correctly because it compares absolute values, not formatted strings. I run k6 load tests against endpoints using this pattern. The latency is consistently under 5ms. Architect expression evaluation overhead drops significantly when you remove regex or date formatting functions. Do not trust DateTimeDiff for high-precision logic. Use milliseconds. It is the only reliable way to handle 24-hour windows in a distributed system like Genesys Cloud.

To fix this easily, this is to abandon DateTimeDiff for high-precision same-day logic. As noted in the previous suggestion, truncation causes false negatives when the difference is less than one full unit. Since you are dealing with message timestamps, precision is non-negotiable.

I handle this by converting timestamps to epoch milliseconds directly in the Data Action. This mirrors how I process webhook payloads for WhatsApp message status updates, where sub-second accuracy matters for delivery receipts.

  1. Create a Data Action that accepts the current timestamp and the target timestamp as inputs.
  2. Use the ConvertToNumber function on both timestamp strings to get epoch milliseconds.
  3. Perform a simple subtraction to get the difference in milliseconds.
  4. Compare the result against 86400000 (24 hours in ms).

This approach avoids timezone ambiguity entirely. Architect’s date functions often struggle with local vs. UTC shifts, but epoch math is deterministic.

Here is the expression logic for the comparison step:

// Inputs: currentTs (string), msgTs (string)
// Output: isRecent (boolean)

let currentMs = ConvertToNumber(currentTs);
let msgMs = ConvertToNumber(msgTs);
let diffMs = currentMs - msgMs;

// Check if difference is less than 24 hours (86,400,000 ms)
isRecent = (diffMs > 0 && diffMs < 86400000);

This method is robust for HSM template validations where time-bound opt-ins expire exactly at a certain hour. It also scales better than string parsing. If you are processing high-volume interactions, the overhead of number conversion is negligible compared to the risk of logic errors from date parsing.

The root of the issue is that DateTimeDiff performs integer division on the time delta, effectively dropping the remainder which kills precision for sub-unit comparisons. Relying on hours or minutes will always fail when the actual difference is less than 1.0 of that unit. The suggestion to switch to epoch milliseconds is correct because it converts the comparison into a simple integer subtraction, bypassing the truncation logic entirely. In your Data Action, you should parse the ISO 8601 timestamp string into a number using DateTimeParse and then subtract the current epoch. If the result is less than 86400000 (24 hours in milliseconds), the message is fresh. Here is the exact expression pattern to use in your condition:

let msgEpoch = DateTimeParse(Transfer.To("ISO8601"), "2006-01-02T15:04:05.000Z");
let nowEpoch = DateTimeNow();
let diffMs = nowEpoch - msgEpoch;
diffMs < 86400000

This avoids timezone shifts and ensures deterministic logic for same-day routing without the overhead of complex date formatting strings.

this looks like a solid approach using epoch milliseconds. however, be careful with the now() function in architect data actions. it returns a string, not a number. you must wrap it in parseint() to avoid type errors during subtraction. also, ensure your inbound message timestamp is iso 8601 before converting, otherwise the math breaks silently.