关于多堆栈应用程序中夏令时的另一个问题

Another question about daylight saving time in multi stack app

我需要帮助来解决夏令时问题。

申请流程:

  1. A python 脚本在 esp32(同一网络)上每 5 分钟读取一些传感器值,并将该值添加 'acktime'(我读取值时的数据和时间)发送到 laravel api (托管)与 post 方法,这将添加 olso 同步时间(我在数据库中写入值时的数据和时间)
  2. Laravel cronjob 给我创建一份每日报告,其中包含来自传感器的最大最小平均值

以后python总是每5分钟读取一次值,但是会将值存储在本地数据库中并每30分钟同步一次值,这样我就不会丢失值由于互联网连接丢失,我添加了“synctime”只是为了看看发生了什么以及是否发生了

cron 作业的问题:

我的命令按天对数据库中的所有行进行分组:

        $weatherdata = rawData::all()
                    ->groupBy(function (RawData $item) {
                        return $item->acktime->format('Y-m-d');
                    })
                    ->each(function (Collection $day) {
                        foreach ($day as $value){
                              Log::info($value);
                        }
                        Log::info('NEXT DAY');
                    });

它似乎工作正常,但是阅读日志我遇到了这个问题:

{"acktime":"2021-10-30T22:56:45.000000Z",
NEXT DAY  
{"acktime":"2021-10-30T23:01:47.000000Z",

对他来说,在法定时间,这一天提前一小时结束,这不是唯一的问题。

如果我将行分组为小时而不是天:

NEXT HOUR  
{"acktime":"2021-10-31T02:02:54.000000Z","temperatur..."}  
..other 23 values when hour is 2 (not ok,total is 24 values)
NEXT HOUR  
{"acktime":"2021-10-31T03:03:58.000000Z","temperatur..."}  
..other 11 values (it's ok,total should be maximum 12)
NEXT HOUR

它把 2:00-3:00 归为一组,就好像我们只经历过一次那样,但实际上我们 2:00-3:00 经历了两次..所以我预计:

NEXT HOUR  
{"acktime":"2021-10-31T02:02:54.000000Z","temperatur..."}  
..other 11 value (it's ok,total 12)
NEXT HOUR  
{"acktime":"2021-10-31T03:03:58.000000Z","temperatur..."}  
..other 11 value (it's ok,total 12)
NEXT HOUR
{"acktime":"2021-10-31T02:02:54.000000Z","temperatur.."}  
..other 11 value (it's ok,total 12)

我的app.php设置为它应该是:

    'timezone' => 'Europe/London',

我的模型class:

class rawData extends Model
{
    use HasFactory;
  
    protected $fillable = [
        'acktime',
        'temperature',
        'humidity',
        ..other data..
        'synctime'
    ];
    /**
    * The attributes that should be mutated to dates.
    *
    * @var array
    */
    protected $dates = ['acktime','synctime'];
    public $timestamps = false;
}

注意:我昨天才添加了受保护的 acktime 和 synctime $dates

Python 脚本:

python 脚本,在读取传感器值后直接将值发送到我的 api,但也许问题是我如何获取数据时间:

from datetime import datetime

def writeData(data):
 data['acktime'] = datetime.now()
 http post

MySql配置 acktime和synctime是datatime类型,UTC为+1 运行 SHOW GLOBAL VARIABLES LIKE 'time_zone'; 我得到系统 我不知道如何将时区存储在数据时间行中

最后一题

我以后怎样才能避免这个问题?? 如何恢复已存储的数据时间值??

我找到的唯一方法是将时间处理为 UTC。

UTC时间不受夏令时影响,这样我就没有排序问题了。

所以第一步是将 Lavarvel 时区设置为 UTC:

配置>app.php

'timezone' => 'UTC',

这是个好方法,但如果你需要使用 Carbon::now() 操作,你必须提醒现在将在服务器时区提供服务,所以你需要将现在的日期时间设置为“UTC” !

Carbon::now('UTC')

使用UTC作为基准时间,引入另一个“问题”,但问题有解决方案:

做每日报告我不能直接使用 Carbon startofDay() end endofDay() 函数,但我需要用我当地的时区创建一个日期,获取一天的开始和结束,然后将每个日期转换为 UTC时区:

        $day = new Carbon($SingleDay);
        $day->setTimezone('Europe/Rome');
        $startTime = $day->copy()->startOfDay();
        $endTime = $day->copy()->endOfDay();
        $startTime->setTimezone('UTC');
        $endTime->setTimezone('UTC');

并且phyton脚本olso被改变,返回UTCnow日期时间来存储数据

datetime.utcnow()

为了从数据库中恢复数据,我做了一个查询,从一天中删除了一两个小时,这是一项帮助我恢复所有数据的简短工作