1
votes

I have this document:

{
   paymentDate: '2015-08-08T23:41:23.909Z'
}

my local time is GMT+7 hence the date above is 2015-08-09 6:41:23 in my local time. I want to send this query below, and receive above document

{
   date: '2015-08-09',
   offset: '+7'
}

What is the best way to achive that in AQL ?

2

2 Answers

1
votes

as can be read in the documentation about dates, ArangoDBs native format JSON doesn't know a special date format, and thus its suggested to store dates as strings. Best practice is to store UTC in the Database and convert it into the users timezone in the application.

Therefore a query would use FILTER and string comparison to select ranges:

arangosh> db._create("exampleTime");
[ArangoCollection 729616498254, "exampleTime" (type document, status loaded)]
arangosh> var timestamps = ["2014-05-07T14:19:09.522","2014-05-07T21:19:09.522","2014-05-08T04:19:09.522","2014-05-08T11:19:09.522","2014-05-08T18:19:09.522"];
arangosh> for (i = 0; i < 5; i++) db.exampleTime.save({value:i, ts: timestamps[i]})
arangosh> db._query("FOR d IN exampleTime FILTER d.ts > '2014-05-07T14:19:09.522' and d.ts < '2014-05-08T18:19:09.522' RETURN d").toArray()
[ 
  { 
    "value" : 2, 
    "ts" : "2014-05-08T04:19:09.522", 
    "_id" : "exampleTime/729617284686", 
    "_rev" : "729617284686", 
    "_key" : "729617284686" 
  }, 
  { 
    "value" : 1, 
    "ts" : "2014-05-07T21:19:09.522", 
    "_id" : "exampleTime/729617088078", 
    "_rev" : "729617088078", 
    "_key" : "729617088078" 
  }, 
  { 
    "value" : 3, 
    "ts" : "2014-05-08T11:19:09.522", 
    "_id" : "exampleTime/729617481294", 
    "_rev" : "729617481294", 
    "_key" : "729617481294" 
  } 
]
1
votes

If your local time in timezone GMT+7 is 2015-08-09 6:41:23, the JavaScript code new Date().toISOString() would return "2015-08-08T23:41:23.000Z" in that moment. As you can see, it returns UTC time. Your computer needs to have the correct date, time and timezone configured of course.

If you want to query for a date in the past or future, and that date is in local time, you can construct an ISO8601 string with timezone offset specified. Let's say we want to know what 2011-01-01 2:00:00 in GMT+7 is in UTC time:

// timezone offset: 07 hours, 00 minutes (+0700)
new Date("2011-01-01T02:00:00+0700").toISOString()
// result: "2010-12-31T19:00:00.000Z"

The same works in AQL:

RETURN DATE_ISO8601("2011-01-01T02:00:00+0700")
// result: "2010-12-31T19:00:00.000Z"

If you already have a datetime string without timezone offset (2011-01-01T02:00:00), but want to assume it's your local time, you can do the following in JS to append the timezone offset:

// Should return -420 for your timezone GMT+7.
// You can supply an offset in minutes manually as well of course.
var offset = new Date().getTimezoneOffset()

var offsetHours = offset / 60 | 0
var offsetMinutes = Math.abs(offset % 60)

var offsetStr = ((offsetHours < 0) ? "+" : "-") + // GMT + or -?
    ((Math.abs(offsetHours) < 10) ? "0" : "") + // leading zero for single digit
    Math.abs(offsetHours) + // hour portion
    ((offsetMinutes < 10) ? "0" : "") + // leading zero for single digit
    offsetMinutes // minute portion

var dateStr = "2011-01-01T02:00:00" + offsetStr
console.log(dateStr)
console.log(new Date(dateStr).toISOString())
// on a GMT+7 machine, result should be:
// "2011-01-01T02:00:00+0700"
// "2010-12-31T19:00:00.000Z"

If the date string is in local time, but Zulu timezone offset was somehow added, you could correct it by 7 hours like this:

// It should had been +0700 and not +0000
var d = new Date("2015-08-09T06:41:23Z").getTime() - 7 * 60 * 60 * 1000
// result: 1439077283000, which is 2015-08-08T23:41:23.000Z

// or in a really hacky way:
new Date("2015-08-09T06:41:23Z".replace("Z", "+0700"))

//edit this seems to work too:

var d = new Date("2015-08-09T06:41:23Z")
d.setHours(d.getHours() - 7)

This seems to work reliably even if you cross start or end datetime of DST, at least in Firefox. There was a bug in Chrome however, which led to completely off date calculations: https://code.google.com/p/v8/issues/detail?id=3116