Skip to Content

Working with OData Dates and Times

When consuming Gateway services in JavaScript the task of working with dates and times is made even harder because of the different representations the objects take. In this blog I will highlight how Gateway OData dates and times are represented in both JSON and JavaScript and show by example how to use these values in SAPUI5 with the JavaScript Date Object and the Class sap.ui.core.format.DateFormat.

TLDR: You can use sap.ui.core.format.DateFormat to format and parse date and time objects when working with Gateway services, see http://jsbin.com/irewuq/9/edit for an example.

Below is the formatted JSON representation of Gateway Entity, similar to what you get using the Flight Service in the Demo Gateway system. eg http://gw.esworkplace.sap.com/sap/opu/odata/IWBEP/RMTSAMPLEFLIGHT_2/FlightCollection?$format=json

"FlightConnectionID": "0017",
"FlightDate": "/Date(1354665600000)/",
"FlightDetails": {
    "ArrivalInDays": 0,
    "ArrivalTime": "PT14H01M00S",
          "DepartureAirPort": "JFK",
          "DepartureCity": "new york",
          "DepartureCountryCode": "US",
          "DepartureTime": "PT11H00M00S",
          "DestinationAirPort": "SFO",
          "DestinationCity": "SAN FRANCISCO",
          "DestinationCountryCode": "US",
          "Distance": "2572.0000",
          "DistanceUnit": "SMI",
          "FlightTime": 361,
          "FlightType": "",
          "__metadata": {
                "type": "RMTSAMPLEFLIGHT_2.FlightDetails"
    }

Highlighted below are Date and Time passed in this service

"FlightDate": "/Date(1354665600000)/",  - JSON Date Object
"DepartureTime": "PT11H00M00S", - XSD Duration

FlightDate is represented as a JSON Date object, the value is the date in milliseconds since Unix Epoch.

Unix EPOCH time = Date(0) = Thu Jan 01 1970 00:00:00 GMT, this value is handy to know if your going to work with dates. http://en.wikipedia.org/wiki/Unix_time

DepartureTime is represented as an XSD:Duration Date Type

The letters in PT11H00M00 P: Period, T: Time, H: Hours, M: Minutes see http://www.w3schools.com/schema/schema_dtypes_date.asp

Luckily if you use the ODataModel, datajs the OData library SAPUI5 uses has regular expressions and code logic which parses these values into JavaScript for us. Below is how this Entity looks parsed to JavaScript.

/wp-content/uploads/2013/04/odata_date1_210048.png

ODataModel values highlighted

FlightDate : Wed Dec 05 2012 11:00:00 GMT+1100 (AUS Eastern Daylight Time) 
DepartureTime : { __edmtype: "Edm.Time", ms: 39600000}  

FlightDate looks like a string, it is in fact the string representation of a JavaScript Date Object

The JavaScript Date Object supports the following ways for instantiating a date, if you are in the AEDT timezone then the following values will be equal.

var a = new Date('Wed Dec 05 2012 11:00:00 GMT+1100 (AUS Eastern Daylight Time)');
var b = new Date(1354665600000);
var c = new Date('2012/12/05');
a.getTime()===b.getTime()&& a.getTime()===c.getTime()

date.getTime() returns the number of milliseconds since Epoch.

Important to note is the Timezone offset when comparing dates, was +1100 AEDT in December, today its +1000 due to daylight savings.

new Date( )  = Sun Apr 28 2013 14:05:52 GMT+1000 (AUS Eastern Standard Time)

To get a consistent Timezone offset use the one from Epoch

var TimezoneOffset = new Date(0).getTimezoneOffset(); // -660 minutes

DepartureTime is a millisecond value wrapped in a edmtype object.

39600000/3600000 = 11 hours 00 min  // 3600000 is the number of milliseconds in an hour 60 minutes *60 seconds *1000 milliseconds

We can use the value in a javascript date object and it will give us the time since Epoch

new Date(39600000).toUTCString() = Thu, 01 Jan 1970 11:00:00 GMT
new Date(39600000).getUTCHours() = 11


SAPUI5 provides the Class sap.ui.core.format.DateFormat that can be used with JavaScript Date Objects for formatting and parsing dates and times.

The example i’ll give is formatting dates and times to formats you may want to use in a mobile application. eg

/wp-content/uploads/2013/04/date1_210365.png /wp-content/uploads/2013/04/time1_210366.png

There is not much to it if you handle everything in UTC milliseconds, to do this we add the timezone offset when formatting and remove it when parsing.

// SAPUI5 formatters
var dateFormat = sap.ui.core.format.DateFormat.getDateInstance({pattern : "dd/MM/yyyy" });
var timeFormat = sap.ui.core.format.DateFormat.getTimeInstance({pattern: "KK:mm:ss a"});       
// timezoneOffset is in hours convert to milliseconds
var TZOffsetMs = new Date(0).getTimezoneOffset()*60*1000;
// format date and time to strings offsetting to GMT
var dateStr = dateFormat.format(new Date(FlightDate.getTime() + TZOffsetMs)); //05-12-2012
var timeStr = timeFormat.format(new Date(DepartureTime.ms + TZOffsetMs));  //11:00 AM
//parse back the strings into date object back to Time Zone
var parsedDate = new Date(dateFormat.parse(dateStr).getTime() - TZOffsetMs); //1354665600000  
var parsedTime = new Date(timeFormat.parse(timeStr).getTime() - TZOffsetMs); //39600000

*Note to SAPUI5 developers DateFormat.format has a to UTC flag, DateFormat.parse could use a from UTC flag.

The following is a list of the pattern elements in the DateFormat class, use them to derive the date and time formats you need.

/**
 * Pattern elements
 */
sap.ui.core.format.DateFormat.prototype.oStates = {
          "G": "era",
          "y": "year",
          "Y": "weekYear",
          "M": "month",
          "w": "weekInYear",
          "W": "weekInMonth",
          "D": "dayInYear",
          "d": "day",
          "F": "dayOfWeekInMonth",
          "E": "dayNameInWeek",
          "u": "dayNumberOfWeek",
          "a": "amPmMarker",
          "H": "hour0_23",
          "k": "hour1_24",
          "K": "hour0_11",
          "h": "hour1_12",
          "m": "minute",
          "s": "second",
          "S": "millisecond",
          "z": "timezoneGeneral",
          "Z": "timezoneRFC822",
          "X": "timezoneISO8601"
};

I have shown you the JSON and JavaScript representations Gateway services have for date and time, given an overview of how to use some of the functions of the JavaScript Date Object, shown an example of how I use the sap.ui.core.format.DateFormat Class to format values for a mobile application which integrates with Gateway services. All that’s left is to share working code http://jsbin.com/irewuq/9/edit.

31 Comments
You must be Logged on to comment or reply to a post.
    • Hi John

      Einstein said “If you can’t explain it simply, you don’t understand it well enough”.

      I say “If you can’t explain it simply, include code”, hoping my code is simple enough for a child to understand :-).

      Cheers

      John P

  • Well explained John! Thanks.

    In fact, i was struggling with dates couple of months back and ended up sending a string from the gateway service.

    I was able to “recieve” the date in the JavaScript date object, however, it did not work with CVOM charts. And i doubt if the proposed solution would work either.Did you try this scenario?

    Thanks

    Jayant

    • Hi Kumar

      And i doubt if the proposed solution would work either.

      I don’t use the CVOM charts, but if your using a FlattenedDataset you could try and use a value formatter like

      var dataset = new sap.viz.ui5.data.FlattenedDataset({

          dimensions : [ {

               axis : 1,

               name : 'date',

               value : { path: "OrderDate", formatter: function(fValue){

                          // see also ui5 docu: http://.../sapui5/wiki/Documentation/AdvancedTopics/DataBinding/TypeSystem#Isitpossibletousethedatatypeswithoutdatabinding

                          jQuery.sap.require("sap.ui.core.format.DateFormat");

                          var oDateFormat = sap.ui.core.format.DateFormat.getDateTimeInstance({pattern: "yyyy-MM-dd"});

                          return oDateFormat.format(new Date(fValue));

                          }

      If that doesnt work maybe you should post a question.

      Cheers

      JSP

      • Hi John,

        My response wasnt intended to lower anyones confidence 🙂

        In fact I had this issue for quite sometime and spoke to product owners on this via the “official” channel. It was difficult to believe that date formatting was not possible in CVOM charts. At that time we had the SP 0002 add-on.

        However, i just tried it now(SP 0004) and it works perfect. Without having to change anything on the gateway side.

        Thanks again for your blog!

        Regards,

        Jayant

  • Hello John,

    This was very helpful blog and we tried, but I have one clarification.

    We choose a date on the UI and pass it (via the gateway odata) to be saved in the R3 backend.

    If we don’t use the code, we get incorrect dates (sometimes one day gets added and sometimes subtracted, depending on the locale).

    But, if we use the code, we get the same date in the backend as we pass from the UI (which is great) but one day difference happens on the UI itself before passing it on.

    Can you please suggest?

    Thanks and Regards,

    Arpita

  • var date = new Date(‘Thu Sep 25 2014 17:41:01 GMT-0400 (Eastern Daylight Time)’);

    when i try to use the Date function with this format I get “Invalid Date”

    how can this be?

  • Hallo guys 🙂

    Any ideas on how to get the time difference between 2 sap.m.DateTimeInput’s? I’m looking for something that would return i.e. 02:32 or 4 hours 20 minitus etc, anything!

    I’ve tried:

    var vTotalTime = new sap.m.DateTimeInput({value: (vStopTime.getDateValue() – vStartTime.getDateValue()), type: “Time”});

    But die above returns the following:

    LOG: Start: Thu Jan 1 15:41:00 UTC+0200 1970

    LOG: Stop: Thu Jan 1 17:41:00 UTC+0200 1970

    LOG: Total: Wed Dec 1 00:00:00 UTC+0200 7199

    Regards

    Antonette

  • Hello all,

    weekInYear won’t work..

    Workaround is there:

    jQuery.sap.require("sap.ui.core.format.DateFormat");

    //define getWeek function
    Date.prototype.getWeek = function () {
      var d = new Date(+this);
      d.setHours(0, 0, 0);
      d.setDate(d.getDate() + 4 - (d.getDay() || 7));
      return Math.ceil((((d - new Date(d.getFullYear(), 0, 1)) / 8.64e7) + 1) / 7);
    };
    var oDateFormat = sap.ui.core.format.DateFormat.getDateInstance({
      pattern: "w y"
    });
    var oDatePicker = new sap.m.DatePicker({
      dateValue: new Date(),
      displayFormat: "w y"
    })

    http://jsbin.com/biraxisaxa/3/edit?html,output

  • Hey John,

    I might be bumping an old blog but how can a duration type be assigned to a point in time.

    To my mind the 8601 Duration format is for well … durations. For example,  the flight was PH13 Long or your appointment will be PM45.

    To say your departure time is PH1100 seems a little incongrous to me… but perhaps I am reading 8601 wrong … xkcd: ISO 8601

    • Please create a new Discussion marked as a Question.  The Comments section of a Blog (or Document) is not the right vehicle for asking questions as the results are not easily searchable.  Once your issue is solved, a Discussion with the solution (and marked with Correct Answer) makes the results visible to others experiencing a similar problem.  If a blog or document is related, put in a link.

      NOTE: Getting the link is easy enough for both the author and Blog.  Simply MouseOver the item, Right Click, and select Copy Shortcut.  Paste it into your Discussion.  You can also click on the url after pasting.  Click on the A to expand the options and select T (on the right) to Auto-Title the url.

      Thanks, Mike (Moderator)

      SAP Technology RIG

  • Very nice blog, it just helped me to fix some problems here.. Thanks! 😉

    Got one addition:

    In The Netherlands we have daylight saving time, and when I used your code I ran into the following problem:

    1. var TZOffsetMs = new Date(0).getTimezoneOffset()*60*1000;

    This line of code creates a new date (01-01-1970) and calculates the timezone offset, but at the first of January in 1970, the daylight savings was different than it is today.


    So instead of using Date(0) I would recommend others to use Date(), so the CURRENT timezone offset will be checked.


    If I overlooked anything or what Im saying is incorrect, please let me know.

    For the rest, keep up the good work and thanks for the help!

    Greets,

    Caspar

  • Hey John,

    Brilliant blog and thanks for the same.
    Just one correction that i would like to point out :

    // timezoneOffset is in hours convert to milliseconds
    var TZOffsetMs = new Date(0).getTimezoneOffset()*60*1000;

    Note: timezoneOffset returns value in minutes and not hours. Here it’s a typo i believe.

    Thanks,
    Harshit

     

  • Hey John ,

     

    Nice blog!! It helped a lot .

    I have a question here If we are getting time from different systems which are in different timezone .For example test system might be in CET and Development system in UTC , in this case our code will be same across both the system so how would we set timezone offset ?

    Thanks

    Shishir

  • Hi John,

    Can you help me? I have a problem with handle field time  the following scenario:

    The following code, is the structure that I receive from the oData service:

    When i send the data, the oData service will retrive me the message error “Property ‘UPTBG’ at offset ‘1.122’ is invalid”.

    Controlling the request, the UPTBG format is:

    What should I do?

     

    Thanks
    Attilio

  • This was helpful and informative when I started learning UI5. Thanks for this post John Patterson!

    For anyone who came to this post by googling how to deal with date/time from OData; SAP has added the following documentation topic:

    Date and Time Related Controls: Data Binding

    The topic explains how to add values of type Edm.Time, Edm.DateTime, and Edm.DateTimeOffset to the UI using sap.ui.model.odata.type.* in the binding info. The type also provides UTC: true/false within the formatOptions (see API reference). E.g.: If UTC is enabled, the application displays the time in UTC, otherwise in their local time which is the default and also the preferred setting. In model, however, the application stores the time always in UTC as data shouldn’t be locale constrained.

    For other explanation and samples, see How to Add Date / Time from OData Service Correctly to UI.