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?
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.
Azure Cosmos DB provides language-integrated, transactional execution of JavaScript that lets you write stored procedures, triggers, and user-defined functions (UDFs).
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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With