Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Creating and comparing dates inside CosmosDB stored procedures

There is limited guidance for CosmosDB stored procedures and their handling of new Date() and the comparison of dates.

The following code is a CosmosDB stored procedure to 'freeze' the writing of documents after a given time. The property currentDoc.FreezeDate is in ISO-8601 format, e.g. '2017-11-15T13:34:04Z'.

Note: this is an example of the situation I'm trying to understand. It is not production code.

function tryUpdate(newDoc) {
  __.queryDocuments(
    __.getSelfLink(),
    { /* query to fetch the document */ },
    (error, results) => {
      var currentDoc = results[0]; // doc from the database
      // fail if the document is still locked
      if (new Date(currentDoc.FreezeDate) < new Date()) {
        getContext().getResponse().setBody({ success: false });
        return;
      }
      // else update the document
      /* snip */
    }
  );
}

My question is: within CosmosDB stored procedures, is new Date() affected by timezones, especially given that the database may be in a different region than the invoking code? Is the date comparison code here valid in all situations?

like image 403
Squiggle Avatar asked Nov 15 '17 13:11

Squiggle


People also ask

How do I create a stored procedure in Cosmos database?

Create Simple Stored ProcedureIn the Data Explorer section, expand the NutritionDatabase database node and then expand the FoodCollection container node. Within the FoodCollection node, select the Items link. Select the New Stored Procedure button (two gears icon) at the top of the Data Explorer section.

Can we write stored procedure in Cosmos DB?

Azure Cosmos DB provides language-integrated, transactional execution of JavaScript that lets you write stored procedures, triggers, and user-defined functions (UDFs).

Can we update data in Cosmos DB?

Change feed in Azure Cosmos DB listens to a container for any changes and then outputs documents that were changed. Using change feed, you see all updates to documents including both partial and full document updates.


1 Answers

As far as I can see, CosmosDB is storing DateTime values without the corresponding Timezone, aka. not as DateTimeOffset. This means it should not matter where the code is executed, since it is always normalized to something like this:

  "2014-09-15T23:14:25.7251173Z"

Javascript Date object are timestamps - they merely contain a number of milliseconds since the epoch. There is no timezone info in a Date object. Which calendar date (day, minutes, seconds) this timestamp represents is a matter of the interpretation (one of to...String methods).

(taken from Parse date without timezone javascript)

In other words, no matter where you are in the world, new Date() will always have the same value internally.

If you want to remove uncertainty in exchange for readability, I would recommend only storing the seconds or milliseconds since the epoch (Unix Time). This is also what is used internally by date (new Date().value - milliseconds). Incidentally, the internal cosmos document field _ts is also a timestamp in epoch format.

Be aware that the value of new Date() might by off the 'correct global time` by a couple of minutes - I don't know if Azure/Cosmos guarantees a certain deviation window.

like image 178
Alex AIT Avatar answered Nov 07 '22 07:11

Alex AIT