Skip to main content

Command Palette

Search for a command to run...

Easy Date Handling in JavaScript with apex.date

Published
3 min read
Easy Date Handling in JavaScript with apex.date
J
Hi, thanks for stopping by! I am focused on designing and building innovative solutions using AI, the Oracle Database, Oracle APEX, and Oracle REST Data Services (ORDS). I hope you enjoy my blog.

Working with dates and times in pure JavaScript is painful, to say the least. In Oracle APEX 21.2, the APEX team introduced the apex.date JavaScript API. The apex.date API provides several easy-to-use utility functions that make formatting, parsing, comparing, and performing calculations on dates in JavaScript a breeze. What I like about these functions is that many mirror SQL and PL/SQL functions and operators we know and love. In this APEX 🩳, I will demonstrate three examples.

Example 1 - Date Calculations

The first example demonstrates a typical scenario where users must enter a start and end date. Whenever the user changes the start date, we want to default the end date to the start date plus seven days. Screenshot showing APEX Items for apex.date Example In this scenario, P70_START_DATE is the 'Start Date', and P70_END_DATE is the 'End Date'. We have an 'Execute JavaScript Code' Dynamic Action on P70_START_DATE that triggers whenever the value changes and sets the appropriate value in P70_END_DATE. Screenshot showing Dynamic Action to Default End date using apex.date

Here is the complete code for the Dynamic Action:

/* Set dateFormat with the Date Format String for the APEX Session.
   Note: apex.date does not support all Oracle Format Strings 
     (see the documentation for details)
*/
const dateFormat   = apex.locale.getDateFormat();
// Set the number of days to add to the start date.
const addDays      = 7;
// Get the string value of the start date APEX Item.
var   startDateStr = apex.item("P70_START_DATE").getValue();
// Use apex.date.parse to convert the string date value to 
// a date value understood by apex.date
var   startDate    = apex.date.parse(startDateStr, dateFormat);
var   endDateStr   = "";
// Add 7 days to the startDate.
apex.date.add(startDate, addDays, apex.date.UNIT.DAY);
// Convert date back to a String using the date format of the session.
endDateStr = apex.date.format( startDate, dateFormat);
// Set the End Date value in the APEX Item.
apex.item( "P70_END_DATE" ).setValue(endDateStr);

The final parameter of apex.date.add identifies the unit (DAY,HOUR,YEAR, etc.). I am adding days in my example, so the unit is DAY. See the documentation for a complete list. We can also use apex.date.subtract to subtract date/time values.

By changing the type of Dynamic Action from 'Execute JavaScript Code' to 'Execute Server-side Code', we could have used PL/SQL to achieve the same thing.

The benefit of the JavaScript approach is that we avoid a round trip to the database in order to do this simple calculation.

Example 2 - Date Comparisons

In this example, we are checking to make sure the end date is greater than the start date. The javascript below uses apex.date.isAfter to achieve this.

const dateFormat   = apex.locale.getDateFormat();
var   startDateStr = apex.item("P70_START_DATE").getValue();
var   endDateStr   = apex.item("P70_END_DATE").getValue();
var   startDate    = apex.date.parse(startDateStr, dateFormat);
var   endDate      = apex.date.parse(endDateStr, dateFormat);
// Clear any existing errors on the page
apex.message.clearErrors();
// apex.date.isAfter compares the two dates down to the second.
if (apex.date.isAfter( startDate, endDate, apex.date.UNIT.SECOND))
{

  apex.message.showErrors([
      {
          type:       "error",
          location:   ["inline" ],
          pageItem:   "P70_END_DATE",
          message:    "End Date must be after Start Date"
      }
  ]);
}

Screenshot showing result of apex.date End Date Before Start date

There are other comparison functions available in apex.date, including isBefore, isBetween, isSame, isSameOrAfter, etc.

Example 3 - Since

You may have encountered the APEX PL/SQL function APEX_UTIL.GET_SINCE. It returns a string describing the elapsed time between a date and time variable and the current date and time. In this example, we use apex.date.since to achieve the same thing as APEX_UTIL.GET_SINCE.

const dateFormat   = 'MM/DD/YYYY HH:MIpm'
var   startDateStr = '07/04/2022 5:00pm';
var   startDate    = apex.date.parse(startDateStr, dateFormat);
var   sinceString = apex.date.since( startDate );
console.log('Since String: ' + sinceString);

Output from the above snippet: Since String: 13 minutes ago

Conclusion

This blog post was just a taste of the utilities available in apex.date. I encourage you to explore the documentation to find out more.

🔗 Read More

S
Sam2y ago

Hello John

Thanks for writing this document its been very helpful I am in the process of trying to get a constant line or marker to appear on selected dates on a gantt chart. So far are ive been able to display selected dates but unable to select an extended period, multiple weekends or an entire month. Could you please advise on how to do this?

J
Jon Dixon2y ago

Hi Sam, Sorry I do not know enough about the APEX Gantt chart to know how to do this.

A

Hi John, To be able to select an extended period, multiple weekends or an entire month. You have to use you can leverage the customGridLines property. This property allows you to add custom grid lines to the Gantt chart, effectively creating markers on specific dates. You can use a for loop through these dates and it will be displayed on your chart. This is a code sample to achieve this

// Assume you have an array of selected dates var selectedDates = ["2023-11-15", "2023-11-22", "2023-12-01"];

// Loop through the selected dates and add custom grid lines for (var i = 0; i < selectedDates.length; i++) { apex.jQuery("#GANTT_CHART_ID").ganttChart("addCustomGridLine", { value: selectedDates[i], label: "Selected Date", style: { stroke: "red", // You can customize the line color "stroke-width": 2 } }); } Replace "GANTT_CHART_ID" with the actual ID of your Gantt chart region.

Let me know if you need further clarification on this

E

Hi Jon,

I think in example 2 the code

apex.message.clearErrors();

should be executed outside the if condition. Because if the user fixes the error, the message will go away.

Thank you for your time.

Eric

J
Jon Dixon3y ago

Hi Eric, You are quite right, I have fixed it. Thanks for letting me know.