Acrel IoT Docs Help

夏令时

概述

夏令时(Daylight Saving Time,DST)指的是部分国家/地区在夏季将时钟调快,并在秋季调回正常时间。夏令时主要北美、欧洲、澳洲和南美部分地区在使用,目的是使大家早睡早起,充分利用光资源,减少照明时间,节约照明用电。

亚洲和非洲纬度较低,基本不用,中国实行过一段时间,1992年停用。

下面举2个国家为例:

  • 美国:开始时,凌晨2点将时钟拨为3点;结束时,凌晨3点将时钟拨为2点;

  • 英国:开始时,凌晨1点将时钟拨为2点;结束时,凌晨2点将时钟拨为1点;

大部分夏令时国家/地区都如同美国(例如:德国、法国、意大利、荷兰、澳洲部分地区),是在凌晨2点调时,英国比较特殊。

实行夏令时的地区大多是调快60分钟,少数地区(澳大利亚部分地区)只调整30分钟。

夏令时方案必须解决几个问题:

  • 夏令时必须可以提前设置,到时自动切换;

  • 夏令时偏移不一定是1小时,必须支持设置时钟偏移,精确到30分钟;

  • 平台要支持按照项目等维度,批量设置夏令时。

协议

对时

平台上设置夏令时后,可以通过对时命令回复给设备,设备在接入或重启后,可以收到平台回复的夏令时设置。
设备发出Topic:sys/dev/{productKey}/{sn} { "msgid": 568, "method": "time", "sn": "1234567890123", "timezone": "8", "timezoneMin": "30", "devicesend": 1638869990 } 平台回复Topic:sys/server/{productKey}/{sn} { "msgid": 568, "method": "time", "sn": "1234567890123", "timezone": "8", "timezoneMin": "30", "devicesend": 1638869990, "serverreceive": 1638870000, "serversend": 1638870001, /* 以下是夏令时信息 */ // 是否启用夏令时,1-启用,0-禁用 "dstEnable": 1, // 夏令时开始、结束时间 "dstStart": 1710957600, "dstEnd": 1729447200, // 夏令时的偏移,通常为30或60,单位:分钟 "dstOffset": 30 }

操作指令

  • 设置夏令时

平台发出Topic:indicate/server/{productKey}/{sn} { "msgid": 628131887239491584, "method": "operate", "sn": "1234567890123", "timestamp": 1638869990, "payload ": { "method": "SET_DST", // 是否启用夏令时,1-启用,0-禁用 "dstEnable": 1, // 夏令时开始、结束时间 "dstStart": 1710957600, "dstEnd": 1729447200, // 夏令时的偏移,通常为30或60,单位:分钟 "dstOffset": 30, // 时区也一起设置 "timezone": "-4", "timezoneMin": "30", } } 设备回复Topic:indicate/dev/{productKey}/{sn} { "msgid": 628131887239491584, "method": "operate", "sn": "1234567890123", "res": 1, "timestamp": 1638869990 }
  • 读取夏令时设置

平台发出Topic:indicate/server/{productKey}/{sn} { "msgid": 628131887239491584, "method": "operate", "sn": "1234567890123", "timestamp": 1638869990, "payload ": { "method": "READ_DST", } } 设备回复Topic:indicate/dev/{productKey}/{sn} { "msgid": 628131887239491584, "method": "operate", "sn": "1234567890123", "res": 1, "timestamp": 1638869990, "payload": { "dstEnable": 1, "dstStart": 1710957600, "dstEnd": 1729447200 "dstOffset": 30, "timezone": "-4", "timezoneMin": "30", } }
  • 实时数据

设备必须在实时数据中上报当前是否处于夏令时,需要注意, isDst并不代表仪表是否启用了夏令时的功能,而是启用夏令时的仪表,当前时钟是否处于夏令时范围内。

设备发出:data/up/{productKey}/{sn} { "method": "report", "reported": { "source": "REALTIME", "meters": [ { "addr": "sub_dev_1", "state": "ONLINE", // 当前处于夏令时范围内 "isDst": "1", "U": 220.0, ... }, { "addr": "sub_dev_1_1", "state": "ONLINE", // 当前处于夏令时范围内 "isDst": "1", "U": 220.0, ... } ] }, "msgid": 123, "timestamp": 1638869890, "sn": "1234567890123", "sendtime": 1638869890, "version": 1 }

开发注意事项

设备侧

设备侧设置夏令时相关参数后,需要注意如下问题:

  1. 由于中台报文中使用的是时间戳,而不是本地时间,不管设备安装在全球哪个时区和是否启用夏令,同一时刻的时间戳应当是相同的;

  2. 设备上报的实时数据/报警/事件中,部分属性可能涉及当地时间,例如最大需量发生时间,需要同时加上时区偏移和夏令时偏移;

  3. 在进夏令时或进冬令时的那个时间点,必须上报一条实时数据,不要重复上报,因为时钟虽然改变,但是报文里的时间戳是一致的;

  4. 时控策略需要根据具体业务需求来判断是否受夏令时影响,或者可以设置是否受夏令时影响:

    • 是:如按照日光明暗设置照明开关灯,原来6点日升关灯,夏令时后就要变成7点关灯;

    • 否:如办公室的照明是跟随上下班时间,那就不需要加上考虑夏令时偏移,原来7点上班开灯,夏令时之后仍旧是7点上班开灯;

  5. 设备进入冬令时的时间,要考虑到夏令时的偏移,例如设置夏令时起止时间:

{ "msgid": 628131887239491584, "method": "operate", "sn": "1234567890123", "timestamp": 1638869990, "payload ": { /* * 下面2个时间是当地标准时间,当进入夏令时后,设备上的时钟拨快30分钟, * 那么设备进入冬令时的时间,在设备端看来应该是10月21日2点30分,而不是2点, * 此处设置的夏令时偏移是30分钟,不是1小时 */ // 功能:设置夏令时 "method": "SET_DST", // 启用夏令时:1-启用,0-禁用 "dstEnable": 1, // 夏令时开始:UTC时间2024-03-21 02:00:00 "dstStart": 1710957600, // 夏令时结束:UTC时间2024-10-21 02:00:00 "dstEnd": 1729447200, // 夏令时偏移:30分钟 "dstOffset": 30, // 时区也一起设置 "timezone": "-4", "timezoneMin": "30", } }

平台侧

平台侧如需保存本地时间,推荐采用如下方案:

  • 修改本地时间计算逻辑

    原本是:

    报文timestamp + timezone → 当地时间

    要改为,根据报文timestamp判断是否处于夏令时范围内,如果是,则要加上夏令时偏移:

    报文timestamp + timezone + 夏令时偏移 → 当地时间

  • 修改保存格式

    建议将时间格式化为yyyyMMddHHmmss ,并且保存为Long类型并加上索引,而不是String类型,这样在查询时收到前端传入的起止时间后,可以按照时间范围进行查询。

    例如: timelong: 20240212030815

    采用此方案可以有效避免受到服务器时区、docker容器时区、数据库时区的影响,导致时间发生偏移的问题。

Last modified: 18 四月 2025