【问题标题】:Query date with offset in AQL在 AQL 中查询带有偏移量的日期
【发布时间】:2015-08-09 00:04:58
【问题描述】:

我有这份文件:

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

我的当地时间是 GMT+7,因此上面的日期是我当地时间的 2015-08-09 6:41:23。 我想在下面发送这个查询,并接收上面的文档

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

在 AQL 中实现这一目标的最佳方法是什么?

【问题讨论】:

    标签: arangodb aql


    【解决方案1】:

    可以在the documentation about dates 中阅读,ArangoDB 的原生格式 JSON 不知道特殊的日期格式,因此建议将日期存储为字符串。 最佳做法是将 UTC 存储在数据库中,并将其转换为应用程序中的用户时区。

    因此,查询将使用 FILTER 和字符串比较来选择范围:

    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" 
      } 
    ]
    

    【讨论】:

    • 谢谢,我确实将我的日期存储在 UTC+0 中(日期后面的 Z 是 zulu/utc+0)但是有没有其他方法可以在不修改查询日期的情况下进行过滤。我的意思是这样的:` ... FILTER DATE_ADD(d.ts, 7) > '2014-05-07' ...` .
    • 不,目前这是不可能的。您必须在客户端中执行此操作。
    【解决方案2】:

    如果您在 GMT+7 时区的当地时间是 2015-08-09 6:41:23,则 JavaScript 代码 new Date().toISOString() 将在那个时刻返回 "2015-08-08T23:41:23.000Z"。如您所见,它返回 UTC 时间。当然,您的计算机需要配置正确的日期、时间和时区。

    如果您想查询过去或未来的日期,并且该日期是本地时间,您可以构造一个指定时区偏移量的 ISO8601 字符串。假设我们想知道 GMT+7 中的 2011-01-01 2:00:00 是 UTC 时间:

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

    在 AQL 中也是如此:

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

    如果您已经有一个没有时区偏移的日期时间字符串 (2011-01-01T02:00:00),但想假设它是您的本地时间,您可以在 JS 中执行以下操作来附加时区偏移:

    // 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"
    

    如果日期字符串是本地时间,但以某种方式添加了 Zulu 时区偏移量,您可以像这样将其纠正 7 小时:

    // 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"))
    

    //编辑 这似乎也有效:

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

    即使您跨越 DST 的开始或结束日期时间,这似乎也能可靠地工作,至少在 Firefox 中是这样。然而,Chrome 中存在一个错误,导致计算完全过期:https://code.google.com/p/v8/issues/detail?id=3116

    【讨论】:

      猜你喜欢
      • 2014-07-26
      • 1970-01-01
      • 1970-01-01
      • 2019-04-07
      • 1970-01-01
      • 1970-01-01
      • 2015-12-21
      • 2012-05-30
      • 1970-01-01
      相关资源
      最近更新 更多