jwadhams / json-logic-js

Build complex rules, serialize them as JSON, and execute them in JavaScript
MIT License
1.26k stars 140 forks source link

[Feature] support dates #6

Closed robmurtha closed 7 years ago

robmurtha commented 7 years ago

The general idea is to support the usage of date variables passed in as strings with some form of operator/type specifier to identify them as dates. The primary goal is to support comparison operators.

Example: {"<":[{"date": "2016-10-01T03:24:00.000Z"}, {"date": "2016-10-15T03:24:00.000Z"}]}

Prototype:

"date" : function(a) {
        return(new Date(a));
    }

Example with var - works with date function in place: rule: {"<":[{"date":{"var":"submitDate"}}, {"date":{"var": "dueDate"}}]} data: {"submitDate":"2016-10-01T03:24:00.000Z","dueDate":"2016-10-15T03:24:00.000Z"}

robmurtha commented 7 years ago

When I first tried dates I did not use this format - noting here that with the JSON format the dates compare as strings so the test does not fail and we may not need a date type just for comparison operators if all timezones are equal, but with information stored in different timezones there could be an issue: {"<":["2016-10-01T03:24:00.000Z", "2016-10-15T03:24:00.000Z"]}

jwadhams commented 7 years ago

Interesting edge case, hadn't considered that. I mostly use epoch seconds (or occasionally milliseconds) internally.

If I can finally get around to importing libraries, you could use Date or Moment.js or something to parse the date string, basically the same as your prototype function?

jwadhams commented 7 years ago

I still need to write some documentation, but I added the method jsonLogic.add_operation yesterday and I think it can solve this case. Here's an example where string comparison does the wrong thing for two ISO 8601 dates (one Zulu time, the other Pacific time) and then using Date.parse to compare them correctly.

jsonLogic.add_operation('Date', Date);

jsonLogic.apply(
  {"<":[
    "2016-10-01T03:24:00.000Z",
    "2016-10-01T03:24:00.000-0800"
  ]}
); //false

jsonLogic.apply(
  {"<":[
    {"Date.parse" : "2016-10-01T03:24:00.000Z"},
    {"Date.parse" : "2016-10-01T03:24:00.000-0800"}
  ]}
); //true

And of course it works with vars too:

jsonLogic.add_operation('Date', Date);

var data = {
  gmt : "2016-10-01T03:24:00.000Z",
  pst : "2016-10-01T03:24:00.000-0800"
};

jsonLogic.apply(
  {"<":[
    {"var":"gmt"},
    {"var":"pst"}
  ]},
  data
);//false

jsonLogic.apply(
  {"<":[
    {"Date.parse" : {"var":"gmt"} },
    {"Date.parse" : {"var":"pst"} }
  ]},
  data
); //true

And it's user's choice whether they want to use the built-in Date or they need something heavier duty like moment.js.

Does this do what you need it to?

jwadhams commented 7 years ago

BTW, by "yesterday" I mean "v1.0.9" which was on Bower yesterday but didn't go up on NPM until this morning.

jwadhams commented 7 years ago

Documentation is up! One of them is using Date support in a very different way, just calling methods on a new Date()

http://jsonlogic.com/add_operation.html

robmurtha commented 7 years ago

That should work thanks!

On 28 October 2016 at 12:17, Jeremy Wadhams notifications@github.com wrote:

BTW, by "yesterday" I mean "v1.0.9" which was on Bower yesterday but didn't go up on NPM until this morning.

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/jwadhams/json-logic-js/issues/6#issuecomment-256963561, or mute the thread https://github.com/notifications/unsubscribe-auth/ABgg8qoZ2jZwDFxAMrfUXfqN4POd1evhks5q4iA0gaJpZM4KU7ev .

Rob Murtha 302-359-5943

http://www.linkedin.com/in/robmurtha http://www.twitter.com/robmurtha