Skip to main content
Level 2
April 29, 2026
Question

Best Practice for Storing and Displaying LocalDateTime When AEP Only Accepts UTC, Store Dual Fields or Use Conversion Functions?

  • April 29, 2026
  • 4 replies
  • 110 views

Hi Community,

I'm looking for guidance on handling datetime values in Adobe Experience Platform where the source data is in local datetime but AEP's datetime datatype only stores values in UTC.

The scenario:

We ingest event data that includes timestamps originally in local datetime. Since AEP schemas require the datetime datatype to be in UTC format, the local time context is lost upon ingestion.

However, when we use this data downstream for example, in personalization templates or email rendering we need to display the datetime back in the original local datetime format for the end user.

My questions:

  1. Dual storage approach — Is it a recommended practice to store both a string field (preserving the original local datetime as-is) and a datetime field (in UTC) in the schema? This way, the string field can be used for display purposes and the datetime field for any time-based logic or segmentation. 

  2. Conversion functions — Are there any built-in helper functions that can convert a UTC datetime value back to a specific local datetime at the point of rendering? If so, how would that work — would we also need to store the timezone/offset alongside the UTC value?

  3. Timezone handling — If conversion functions exist, do they require a separate field storing the timezone identifier (e.g., America/Chicago+05:30) to perform the conversion from UTC back to local time?

Would appreciate any best practices or patterns the community has used to solve this. Thanks in advance!

4 replies

Level 3
April 30, 2026

Hey  ​@ShriyaRe 

My suggestion would be to go for dual-storage approach where you can store both the timestamp field and the locale timezone instead. There are helper functions in AJO (both in conditional expressions and email personalization) where it is possible to convert from UTC to any timezone format. 

  • The following expression can be used within conditional expressions within any conditional nodes/custom action inputs: 
    • Input: updateTimeZone( toDateTime("2019-08-28T08:15:30.123-07:00"), "Europe/Paris"))
    • Output: 2019-08-28T17:15:30.123+02:00.

  • This following expression can be used for in-email personalization. 

    • Input: {%=convertZonedDateTime(stringToDate("2019-02-19T08:09:00Z"), "Asia/Tehran")%}
    • Output: 2019-02-19T11:39+03:30[Asia/Tehran]

By this way, you can leverage this additional timezone value for calculation of current time with respect to the profiles as well. Hope this helps! I’m looking forward to hear others suggestions as well. 

 

Regards, 
Ganesh Kumar

ShriyaReAuthor
Level 2
May 4, 2026

Hi Ganesh, thank you for the response!

I wanted to share more context about our specific setup to see if your suggestion still applies or if there's a better approach.

Our situation:

  • We are using AJO → ACC transactional email flow
  • The source eventvcontains localDateTime as in this format e.g. "2025-09-01T21:55:00" — this is already the local time, (we are preferring to store it as string)
  • We map this via a custom action payload to ACC's transactional event schema as a string field under rtEvent.ctx
  • In the ACC email template, we need to display it in a human-readable format like Mon 01 September 2025 21:55

Our confusion:

  • Since localDateTime is already the correct local time (not UTC), we don't think we need timezone conversion but we are not 100% sure
  • We are not sure if there is any built-in function in ACC's email template scripting (<% %>) that can handle this formatting
  • Currently we are manually parsing the string using JavaScript logic in the template, but we are unsure if this is the right/recommended approach or if we are overcomplicating it

Is manually parsing the ISO string in the ACC template the right way to go here? Or is there a cleaner approach we are missing? Any guidance would be really helpful!

DavidKangni
Community Advisor
Community Advisor
May 4, 2026

@ShriyaRe 

if you’re passing the localDateTime, you should be good. just make sure that AJO interprets it a datetime.

In ACC, you have the formatDate function too. formatDate

 

Thanks,
david

David Kangni
DavidKangni
Community Advisor
Community Advisor
May 1, 2026

Hi ​@ShriyaRe 

 

Can you please elaborate the local datetime? AEP will not convert the time but save it as is. 

As example I’m in EST, if I ingest this data today may 1st 2026 at 2 PM local time, it will show in AEP as 05/01/2026 2:00 PM except if you are using now during your ingestion.

  • if you’re not using now(), then you should be good to use the datetime you’re ingesting
  • if you’re using now(), you can use formatDate in personalization. 

Here is an example {% let currentDate = formatDate(convertZonedDateTime(getCurrentZonedDateTime(),"America/New_York"),"MMMM d, yyyy", "en_US") %}

Date Time functions library | Adobe Journey Optimizer

Thanks,

David

David Kangni
Imbalakumar
Adobe Champion
Adobe Champion
May 5, 2026

HI ​@ShriyaRe I'm sure you can handle this in the data Mapping steps while ingest the data, keep the source date format in one attribute as string data type and convert the time zone if you wish to keep in another time zone using the "Calculated Field” in AEP data mapping steps,

Refer the below screen, also you write the code here if you wanted to display the time as April 1st 2026 or 5th May 2026 or any way you would like to display while calling this attributes for the personalization field,

 

 

The calculated field "Functions" provides lot of flexibility to play around the date and time, let me know if this helps.

 

If you handle these kind of data formate while ingest the data, that will help you in many ways and avoid your other dependencies to convert the fields using custom codes in AJO while calling these attributes for personalizations.

 

Thanks,

Bala

Balakumar Saravanavel
Level 3
May 12, 2026

Hi ​@ShriyaRe ,

Great question and the replies above cover the core options well. Let me add a practical recommendation based on your specific AJO to ACC transactional flow.

Since your localDateTime is already the correct local time stored as a string like “2025-09-01T21:55:00” and you’re passing it through a custom action payload to ACC under rtEvent.ctx, you actually have the cleanest possible setup for display purposes. The string already has the correct time you just need to format it for human readability in the email template.


For your three questions directly:


On dual storage yes this is a recommended pattern and worth doing even in your case. Keep your string field for display and add a UTC datetime field for segmentation, journey conditions, and any time-based logic in AEP. The string field gives you display flexibility, the datetime field gives you query and segmentation accuracy. Trying to use one field for both purposes is where teams run into problems.


On conversion functions in ACC you don’t need timezone conversion since your string is already local time. What you need is date parsing and formatting. In ACC email templates using the JST scripting layer you can parse your ISO string and reformat it. The cleanest approach is to use the formatDate helper that David mentioned, but since you’re passing it as a string not a native datetime you need to convert it first using toDate() before formatDate can work with it. Something like formatDate(toDate(rtEvent.ctx.yourField), “EEE dd MMMM yyyy HH:mm”) will give you “Mon 01 September 2025 21:55”.

On timezone identifier storage since your string already carries the local time you don’t need a separate timezone field for display. You would only need it if you wanted to convert from UTC to local at render time, which isn’t your case. Store the timezone identifier only if you anticipate needing it for journey conditions or future segmentation logic.

The JavaScript manual parsing approach you’re currently using works but formatDate with toDate() is cleaner and more maintainable across template updates.