Lavachart Datatable-> toJson为x轴上具有不同时区的日期提供了f列和v列

时间:2018-09-20 11:04:07

标签: laravel datetime google-visualization

版本:“ khill / lavacharts”:“ 3.1。*”,

控制器提供碳日期对象,数据表如下所示;

在PHP代码中

  $dataTable = \Lava::DataTable();
    $formatter  = \Lava::DateFormat([
        'pattern' => 'MMM d, HH:mm',
        //'timeZone' => '', //same results without timezone parameter or with 'timeZone' => 2,
    ]);

  $DataTable->addDateColumn('closing hour', $formatter)
            ->addNumberColumn('closing price')
            ->addNumberColumn('product evaluation')
            ->setDateTimeFormat('Y-m-d H:i:s')
            ->setTimezone('UTC') ; //added but no effect

for (...){
           //$hour_start-->toIso8601String() ==  2018-09-07T17:00:00+00:00 6430.4420188271
            $dataTable->addRow([$hour_start->toDateTimeString(), $hourly_closing_price ,$hourly_value]);
}

 **return $dataTable->toJson();//added after answer of WhiteHat**
 Log::info(' dataTable '.$dataTable->toJson());

但是,当记录数据表的php json时,如下所示,对于每一行:

  

{“ c”:[{“ v”:“ Date(2018,8,7,17​​,0,0)”},{“ v”:6430.442018827109} ...

在ajax调用我的Laravel控制器后的javascript中,收到的json是下面的一个

  

{“ c”:[{“ v”:“ 2018-09-07T15:00:00.000Z”,“ f”:“ Sep 7,17:00”},{“ v”:6430.442018827109},{ “ v”:0}]}。

f列(我的UTC日期)和v列(我的UTC日期减去2h)之间存在2小时的差异。

我更改了浏览器的本地时区以进行测试,但没有效果。 提供的数据以UTC表示,服务器以UTC表示,图表上设置的时区为UTC,但在Google图表中的某处应用了2小时的时差。

似乎Google服务器不会将发送的日期视为UTC时间,而是在保持f格式值的同时更改v值

使用

  $formatter  = \Lava::DateFormat([
            'pattern' => 'MMM d, HH:mm',
            'timeZone' => 0,
        ]);

=>在同一时区的f和v列,但更改为好像输入日期不是UTC(而是UTC + 2)

  

{“ c”:[{“ v”:“ 2018-09-07T15:00:00.000Z”,“ f”:“ 9月7日,   15:00“},{” v“:6430.442018827109},{” v“:0}]}

有线索吗?

2 个答案:

答案 0 :(得分:0)

我不熟悉Lavacharts,
但是我会质疑数据实际到达浏览器时的格式。
是否,实际上是json格式。

不确定addRow在这里做什么,但它似乎正在加载一个简单的数组,
不是json对象。

addRow([$hour_start->toDateTimeString(), $hourly_closing_price ,$hourly_value]);

在javascript中,当您从字符串创建日期时,
在大多数情况下,会针对时区进行调整。
在此处查看此答案以获取更多信息。 -> Why does Date.parse give incorrect results?

但是,Google的json date string representation会得出确切的日期,
无需调整时区。

看下面的例子,
在第一行中,使用google的json日期字符串。
第二,我们使用格式化字符串中的new Date()构造函数。

您会发现浏览器没有更改第一行的时区,
但在第二个。

google.charts.load('current', {
  packages: ['table']
}).then(function () {

  var data = new google.visualization.DataTable({
    cols: [
      {type: 'datetime'}
    ],
    rows: [
      {c:[{v: 'Date(2018,8,7,17,0,0)'}]},
      {c:[{v: new Date('2018-09-07T17:00:00+00:00')}]}
    ]
  });
  
  var formatDate = new google.visualization.DateFormat({
    pattern: 'MM/dd/yyyy HH:mm:ss'
  });
  formatDate.format(data, 0);
  
  var table = new google.visualization.Table(document.getElementById('table'));
  table.draw(data);
  
  document.getElementById('test-date0').innerHTML = data.getValue(0, 0);
  document.getElementById('test-date1').innerHTML = data.getValue(1, 0);

});
div {
  margin-bottom: 6px;
}
<script src="https://www.gstatic.com/charts/loader.js"></script>
<div>Google table chart</div>
<div id="table"></div>
<div>raw data</div>
<div id="test-date0"></div>
<div id="test-date1"></div>


编辑

一个选项可能是使用数据视图通过浏览器上的时区偏移量来调整日期,
这应该将日期恢复为从服务器发送的原始值...

请参阅以下工作片段...

google.charts.load('current', {
  packages: ['table']
}).then(function () {

  var data = new google.visualization.DataTable({
    cols: [
      {type: 'datetime'}
    ],
    rows: [
      {c:[{v: 'Date(2018,8,7,17,0,0)'}]},
      {c:[{v: new Date('2018-09-07T17:00:00+00:00')}]}
    ]
  });
  
  var formatDate = new google.visualization.DateFormat({
    pattern: 'MM/dd/yyyy HH:mm:ss'
  });

  // create data view
  var view = new google.visualization.DataView(data);
  view.setColumns([{
    calc: function (dt, row) {
      // one minute in milliseconds
      var oneMinute = (60 * 1000);

      // get date from data table
      var rowDate = dt.getValue(row, 0);

      // Adjust date for timezone
      rowDate = new Date(rowDate.getTime() + (oneMinute * rowDate.getTimezoneOffset()));

      // return new value and formatted value
      return {
        v: rowDate,
        f: formatDate.formatValue(rowDate)
      };
    },
    type: data.getColumnType(0)
  }]);

  var table = new google.visualization.Table(document.getElementById('table'));
  table.draw(view);
  
  document.getElementById('test-date0').innerHTML = view.getValue(0, 0);
  document.getElementById('test-date1').innerHTML = view.getValue(1, 0);

});
div {
  margin-bottom: 6px;
}
<script src="https://www.gstatic.com/charts/loader.js"></script>
<div>Google table chart</div>
<div id="table"></div>
<div>raw data</div>
<div id="test-date0"></div>
<div id="test-date1"></div>

答案 1 :(得分:0)

正如WhiteHat解释的那样,这是关于我的浏览器和googleChart如何将包含带有utc日期的google dataTable的json解释为本地日期的问题。

1) 我的浏览器将日期设置为:new Date(2018,8,7,6,0,0):

console.log('time2 '+ new Date(2018,8,7,6,0,0)) ->Fri Sep 07 2018 06:00:00 GMT+0200 (Romance Daylight Time)

我想要什么:

console.log('time1'+ new Date(Date.UTC(2018,8,7,6,0,0))) ->Fri Sep 07 2018 08:00:00 GMT+0200 (Romance Daylight Time)

请参阅要点2。

2)我确实需要以这种格式检索json utc日期:new Date(2018,8,7,6,0,0)

对Google图表的JavaScript调用更改了json中本地日期格式为[{“的接收到的服务器utc日期(例如:{” v“:” Date(2018,8,7,17​​,0,0)“}) v“:” 2018-09-07T15:00:00.000Z“,” f“:” Sep 7,17:00“},所以我需要在更改字符串日期之前先对其进行拦截

 var dataTable
$.getJSON('/chart', function (dataJson) {
   // dataTable dataJson on format : "v":"Date(2018,7,31,19,0,0)"
   dataTable = dataJson
   dataToLoad = $.extend(true,{},dataJson); //clone it as the object dataToLoad  will be modified by google chart when loaded per lava

   lava.loadData('chart', dataToLoad , function (data) {
         console.log('data'+JSON.stringify(dataToLoad )) //dataTable dates are put on format : "v":"2018-08-31T16:00:00.000Z","f":"Aug 31, 18:00"           
    });
})

use dataTable...

//To get the right timezone on my dates, i did something like:

  string_timestamp ; string_timestamp = datatable.data['rows'][item.row]['c'][0]['v'] //this is my received UTC date formatted as "Date(2018,8,7,17,0,0)" in dataTable 
  temp=(string_timestamp.replace("Date(","")).replace(")","")                          
  str1= temp.split(',');
  date2=new Date(Date.UTC(str1[0],str1[1],str1[2],str1[3],str1[4],str1[5]))