Java集成influxDB 默认UTC时区问题

这篇具有很好参考价值的文章主要介绍了Java集成influxDB 默认UTC时区问题。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

dd

我用的influxDB 1.8版本高版本我不清楚,因为1.x版本便于写sq语法。 

influxDB时序库默认使用 UTC时区,并且无法通过配置来修改这个时区,很多文档说在查询数据的时候加上  tz('Asia/Shanghai')。   

而这个在Windows环境下的influxdb会报错:

ERR: error parsing query: unable to find time zone Asia/Shanghai

首先我们来看下infulxdb数据库存储的time数据,我发现是以时间戳来存储的。

Java集成influxDB 默认UTC时区问题

但是我们Java查询出来的时间是UTC时间格式

Java集成influxDB 默认UTC时区问题

以上是问题描述,以下是解决思路。

pom文件

<!-- 时序库-->
<dependency>
    <groupId>org.influxdb</groupId>
    <artifactId>influxdb-java</artifactId>
    <version>2.15</version>
</dependency>

我发现influxdb提供了时间工具类。解决思路先将2023-05-26T08:47:03.6147144Z 这种UTC格式转成 时间戳  再赋值给Date()对象转成CST时区时间;

UTC时间字符串转时间戳
long time = TimeUtil.fromInfluxDBTimeFormat("2023-05-30T02:09:05.3138263Z");

SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
//这样就得到了  2023-05-30 11:01:23
String timeStr = simpleDateFormat.format(new Date(time));

粘一段获取到influxdb数据后映射给Java对象的代码。

 /**
     * 查询,返回对象的list集合
     *
     * @param query
     * @return
     */
    @SuppressWarnings({"rawtypes", "unchecked"})
    public <T> List<T> fetchResults(String query, Class<?> clasz) {
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

        List results = new ArrayList<>();
        QueryResult queryResult = influxDB.query(new Query(query, Configurations.DATABASE_NAME));
        queryResult.getResults().forEach(result -> {
            result.getSeries().forEach(serial -> {
                List<String> columns = serial.getColumns();
                int fieldSize = columns.size();
                serial.getValues().forEach(value -> {
                    Object obj = null;
                    try {
                        obj = clasz.newInstance();
                        for (int i = 0; i < fieldSize; i++) {
                            String fieldName = columns.get(i);
                            Field field = clasz.getDeclaredField(fieldName);
                            field.setAccessible(true);
                            Class<?> type = field.getType();

                            if (type == float.class) {
                                field.set(obj, Float.valueOf(value.get(i).toString()));
                            } else if (type == Long.class) {
                                field.set(obj, Long.valueOf(value.get(i).toString()));
                            } else if (type == Double.class) {
                                field.set(obj, Double.valueOf(value.get(i).toString()));
                            } else {
                                long time = TimeUtil.fromInfluxDBTimeFormat(value.get(i).toString());
                        

                                if ("time".equals(fieldName)) {
                                    field.set(obj, simpleDateFormat.format(new Date(time)));
                                } else {
                                    field.set(obj, value.get(i));
                                }

                            }

                        }
                    } catch (NoSuchFieldException | SecurityException | InstantiationException | IllegalAccessException e) {
                        e.printStackTrace();
                    }
                    results.add(obj);
                });
            });
        });
        return results;
    }

最后还有个问题,因为influxdb在插入数据的时候是按照纳秒计算的,那么我们转成毫秒后时间会有误差,所以我们在插入数据的时候手动给time字段赋值并设置按毫秒计算。

主要是这一段:

  //手动给time字段赋值,并按毫秒进行计算
  builder.time(times, TimeUnit.MILLISECONDS);
/**
     * 批量新增,方法一
     */
    public void insertBatchByRecords(List<?> records) {
        long times = System.currentTimeMillis();
        List<String> lines = new ArrayList<>();
        records.forEach(record -> {
            Class<?> clasz = record.getClass();
            //获取度量
            Measurement measurement = clasz.getAnnotation(Measurement.class);
            //构建
            Point.Builder builder = Point.measurement(measurement.name());
            Field[] fieldArray = clasz.getDeclaredFields();
            Column column = null;
            for (Field field : fieldArray) {
                try {
                    column = field.getAnnotation(Column.class);
                    //设置属性可操作
                    field.setAccessible(true);
                    if (column.tag()) {
                        //tag属性只能存储String类型
                        builder.tag(column.name(), field.get(record).toString());
                    } else {
                        //设置field
                        if (field.get(record) != null) {

                            Class<?> type = field.getType();
                            if (type == Long.class) {
                                builder.addField(column.name(), field.getLong(record));
                            } else if (type.equals(Double.class)) {
                                builder.addField(column.name(), Double.valueOf(field.get(record).toString()));
                            } else if (type == Float.class) {
                                builder.addField(column.name(), Float.valueOf(field.get(record).toString()));
                            } else {
                                builder.addField(column.name(), field.get(record).toString());
                            }
                        }
                    }
                } catch (IllegalArgumentException | IllegalAccessException e) {
                    e.printStackTrace();
                }
            }
            //手动给time字段赋值,并按毫秒进行计算
            builder.time(times, TimeUnit.MILLISECONDS);

            lines.add(builder.build().lineProtocol());
        });
        influxDB.write(lines);
    }

那么在查询的时候就可以用时间戳来做查询条件,因为时间戳是毫秒值,而influxdb存储的时候是用的纳秒,所以在查询的时候得 毫秒值 * 1000000

//构建查询语句,返回QueryResult
 StringBuilder querySql = new StringBuilder("select * from tracer_angle where 1=1 ");

 querySql.append(" and time >= ").append(startTime.getTime() * 1000000);
 querySql.append(" and time <= ").append(endTime.getTime() * 1000000);

如果查询的时候用 毫秒值 * 1000000,  那么在数据插入时序库的时候一定要用下面这个手动给time字段赋值。文章来源地址https://www.toymoban.com/news/detail-464674.html

  //手动给time字段赋值,并按毫秒进行计算
  builder.time(times, TimeUnit.MILLISECONDS);

到了这里,关于Java集成influxDB 默认UTC时区问题的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Linux 硬件时间(RTC time)、系统时间(UTC时间、Universal time)、本地时间(Local time)、时区(Time zone)与夏令时(DST)解析

    处理和管理时间是计算机科学的重要方面,但也是最复杂和容易混淆的方面之一。本文将详细介绍硬件时间、系统时间(UTC时间)、本地时间、时区和夏令时,希望能帮助读者更好地理解这些概念。 1.1 硬件时间简介 硬件时间,也被称为实时时钟(RTC),是指计算机主板上的

    2024年02月04日
    浏览(30)
  • 解决ros默认catkin_make编译用的是python2的问题,改成python3

    由于毕设是做ros机器人相关的上位机,因此本专题是做毕设所有过程的记录 学习资料参考内容如下: B站Autolabor初级教程教学 Autolabor初级教程教学文档 主要是想记录自己的踩过的所有坑,内容可能比较零散,想看比较系统完备的知识请去参考上面两个链接 默认你unbutu系统已

    2024年02月17日
    浏览(32)
  • Dockerfile打包镜像之修改默认时区

    目录 问题背景 总结 Ubuntu Centos Alphine 前一段时间项目上用dockerfile创建了应用镜像,等服务跑起来后,某些功能接口怎么都调不通,经过排查发现原来是镜像的时间不对。 打包镜像时使用的基础镜像基本上都是采用UTC(格林时间),与我们常用的北京(上海)时间(CST)相差8个

    2024年02月11日
    浏览(48)
  • macOS修改默认时区显示中国时间

    默认时区不是中国,显示时间不是中国时间 打开终端 ,删除旧区,并复制新时区到etcreb sudo -rm -rf /etc/localtime sudo ln -s /usr/share/zoneinfo/Asia/Shanghai /etc/localtime 重启系统后时间显示为中国时间

    2024年01月21日
    浏览(27)
  • 切换默认python版本(解决ROS中python默认版本为python2的问题)

    许多小伙伴在安装完ROS以后,需要基于python3写ROS程序(尤其是部署深度学习算法),但是ROS默认的python版本为python2,导致无法兼容一些基于python3写的算法。有的小伙伴会选择利用anaconda来创建python3虚拟环境,但是这样做法可能会导致虚拟环境和ROS默认的环境冲突,因此不推

    2024年02月11日
    浏览(29)
  • IDEA设置默认JDK、Maven版本问题汇总

    使用IDEA导入一个Maven多模块项目遇到关于JDK和Maven版本相关的问题,这里记录一下解决办法。 如何修改当前项目JDK和Maven的版本? 修改当前项目对应Maven版本: File - Setting - 搜索Maven 修改JDK版本,需要同时修改Project Structure的Project、Modlues设置和Setting设置: File - Project Structu

    2024年02月02日
    浏览(45)
  • Java获取当前的UTC时间

    java中如何获取utc时间,并转为Date对象,这是一个常见的问题。可能会找到如下代码的回答: 但是运行过后发现不能获取带UTC时间 那么为什么不能获取,如何正确获取utc时间呢? 分析一下上述代码为什么不能获取正确的UTC时间 看一下 Calendar.getTime() 方法 本质上是通过 getTi

    2024年02月05日
    浏览(30)
  • springboot集成ElasticSearch版本号问题

    1.本地安装es版本 2.spring-boot-starter-parent 版本2.2.13对应自动集成的elasticsearch包版本是6.8.15 springboot和es版本对应关系查询地址  https://docs.spring.io/spring-data/elasticsearch/docs/current/reference/html/#repositories故springboot junit测试时查询报错    解决方案 1.将springboot包版本下降到2.1.3RELEASE就

    2024年02月11日
    浏览(30)
  • 小程序微信支付V3版本Java集成

    相较于之前的微信支付API,主要区别是: 遵循统一的REST的设计风格 使用JSON作为数据交互的格式,不再使用XML 使用基于非对称密钥的SHA256-RSA的数字签名算法,不再使用MD5或HMAC-SHA256 不再要求携带HTTPS客户端证书(仅需携带证书序列号) 使用AES-256-GCM,对回调中的关键信息进

    2024年02月11日
    浏览(46)
  • ACDC:开箱即用的多租户数据集成平台

    新东方的一些核心业务存在单元写、中心入仓的场景,因此需要将数据从各单元的关系型数据库同步到中心,并异构存储到数据仓库之中。 技术团队最初使用 Apache Sqoop 以批的方式实现了这个能力。随着数据量的增长,这个方案很快暴露出了一些问题,如: 为了不影响业务,

    2023年04月16日
    浏览(31)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包