Handling datetime functions and Investigate likely issues with datetime

refs: https://dgraphlabs.slack.com/archives/G9SRXDGN5/p1553868274082100

This came up after discussing with @amanmangal I had never explored much datetime before. And as Aman noted, there is not much documentation on datetime.

Investigate

We have only one test for datetime context dgraph/query0_test.go at db65dc80459b570b74dc93d568050ec1abd039c8 · dgraph-io/dgraph · GitHub

We need more tests on date time. To predict different behaviors using datetime.
We need to know (Never trust, verify! xD) if the “since (…)” function will always align the Timezone offset for example. Thus ensures that function math(since(date)/(60*60)) is always in line with real world queries.

Me and @amanmangal are searching by issues with Timezone/datetime. So If we find something concrete, we fill up an issue.

Ideas for datetime functions

In geolocation we have near, within, contains, intersects. And datetime has no interesting functions except “since (pred)”. So here I want to propose some of them.

neo4j has some material on this
Temporal functions - instant types - Neo4j Cypher Manual
Temporal functions - duration - Neo4j Cypher Manual

duration ( )

duration(pred, pred2) #return in seconds
duration(val(A), val(B)) #return in seconds
{
    q(...) { 
      A as somepred { B as someother }
}
   me () {
     duration(val(A), val(B)) #return in seconds
    }
}

Duration between two predicates - or time difference between two nodes.
e.g: How long it took between creating an account and using it again. “create_at”, “last_visit”. Or even how long it took to create an account and send a message. Obviously there are many other utilities for this function.

duration(pred, pred2, pred3) #return average in seconds

If you use more than one predicate it will be “average time”

We can do this with “since()” and “math()” but it’s not friendly…

Now ( )

now() #Return local time in RFC3339 format
currentDate : now() #can be used just to display the current time on Dgraph
now(+03:00) 
# Return local time in RFC3339 format and solve Timezone based 
# on dgraph instance (alpha or zero) timezone.

Usage:

Based on @gus txn work - using “now()” func with facet.

txn {
  query {
    me(func: eq(email, "someone@gmail.com")) {
      v as uid
      T as user.Timezone
    }
   me2(func: eq(email, "otherperson@gmail.com")) {
      F as uid
    }
  }

  mutation {
    set {
      uid(v) <friend> uid(F) (since=now(T)) . 
      # so it will have a time related to the commit moment.
    }
  }
}

or a simple mutation

{
set {
      <0x32f> <friend> <0x55b> (since=now(T)) . 
      # so it will have a time related to the commit moment.
      <0x32f> <last_visit> now() . #during a login
    }
}

Range functions

Must of it can be done by Dgraph using Inequality - By could be more friendly.

@filter(today(created_at, ["13:00:00", "22:00:00"], "+03:00")) #have hour indexing with optional Timezone
@filter(thismonth(created_at, ["22", "31"])) #have day indexing
@filter(thisyear(created_at, ["02", "12"])) #have month indexing

Please discuss about it.

Seems that we don’t have a test predicting TimeZone