Java集成influxDB 默认UTC时区问题

news2024/10/7 20:35:35

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查询出来的时间是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);
    }

那么在查询的时候我们也可以通过工具类将从前端拿到的时间参数转成 UTC时间格式的字符串来进行sql查询。

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

querySql.append("and time >= '").append(TimeUtil.toInfluxDBTimeFormat(startTime.getTime())).append("' ");
querySql.append("and time <= '").append(TimeUtil.toInfluxDBTimeFormat(endTime.getTime())).append("' ");

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/587742.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【youcans动手学模型】AlexNet模型CIFAR10图像分类

欢迎关注『youcans动手学模型』系列 本专栏内容和资源同步到 GitHub/youcans 【youcans动手学模型】AlexNet模型CIFAR10图像分类 1. AlexNet 卷积神经网络模型1.1 论文简介1.2 AlexNet 的主要贡献1.3 AlexNet 网络1.4 模型的运行结果 2. 在 PyTorch 中定义 AlexNet 模型类2.1 按…

Qt编写视频监控系统77-Onvif组件支持非正常时间的设备

一、前言 在经历了大量的现场设备测试&#xff0c;至少几十种厂家、几百种设备&#xff0c;遇见过奇奇怪怪的问题&#xff0c;一个个想方设法解决&#xff0c;发现有个问题是在下发鉴权的时候&#xff0c;需要带上设备的时间&#xff0c;而不是发送端的时间&#xff0c;如果带…

LeetCode 1110. 删点成林

【LetMeFly】1110.删点成林 力扣题目链接&#xff1a;https://leetcode.cn/problems/delete-nodes-and-return-forest/ 给出二叉树的根节点 root&#xff0c;树上每个节点都有一个不同的值。 如果节点值在 to_delete 中出现&#xff0c;我们就把该节点从树上删去&#xff0c…

MySQL 系统信息函数

文章目录 系统信息函数1. 查看当前 MySQL 数据库版本号2. 查看当前使用的数据库3. 查看当前服务器连接次数 系统信息函数 当我们需要知道当前 MySQL 数据库的一些基本信息和使用情况的时候&#xff0c;可以使用系统信息函数来获取相关信息&#xff0c;以随时掌握数据库的使用情…

【C++系列P2】引用——背刺指针的神秘刺客(精讲一篇过!)

前言 大家好吖&#xff0c;欢迎来到 YY 滴 C系列 &#xff0c;热烈欢迎&#xff01;如标题所示&#xff0c;本章主要内容主要来侃侃“引用”这个刺客&#xff01;如下就是大纲啦~ 一.引用 1.含义与特点 引用&#xff0c;即取别名。它的最大特点是编译器不会为引用变量而开辟空间…

Segment Anything——图像分割的基础模型介绍

人工智能中的基础模型变得越来越重要。这个术语开始在 NLP 领域加快步伐,现在,随着 Segment Anything Model 的出现,他们也慢慢进入了计算机视觉领域。Segment Anything是 Meta 的一个项目,旨在为图像分割的基础模型构建起点。在本文中,我们将了解 Segment Anything 项目最…

Python:Python编程:从入门到实践__超清版:线程

Python线程与安全 实现线程安全有多重方式&#xff0c;常见的包括&#xff1a;锁&#xff0c;条件变量&#xff0c;原子操作&#xff0c;线程本地存储等。 &#x1f49a; 1. 锁2. 条件变量3. 通过 join 阻塞当前线程4. 采用 sleep 来休眠一段时间5. 原子操作5.1 使用 threading…

HTTP请求中token、cookie、session有什么区别

cookie HTTP无状态的&#xff0c;每次请求都要携带cookie,以帮助识别身份服务端也可以向客户端set-cookie,cookie大小4kb默认有跨域限制&#xff1a;不可跨域共享&#xff0c;不可跨域传递cookie&#xff08;可通过设置withCredential跨域传递cookie&#xff09; cookie本地存…

【EXata】5.4 连接到互联网

目录 5.4 连接到互联网 5.4.1 Windows 互联网网关配置 5.4.3 验证互联网网关配置 5.4 连接到互联网 EXata 允许在操作主机上运行的基于 Internet 的应用程序通过模拟网络连接到 Internet。这使得即时通讯、流媒体视频、VoIP 等应用程序可以像在现实世界中一样在 EXata 上运行。…

理解Java关键字volatile

原文链接 理解Java关键字volatile 在Java中&#xff0c;关键字volatile是除同步锁以外&#xff0c;另一个同步机制&#xff0c;它使用起来比锁要简单方便&#xff0c;但是却很容易被忽略&#xff0c;或者被误用。这篇文章就来详细讲解一下volatile它的作用&#xff0c;它的原理…

【图像水印 2022 ACM】PIMoG

【图像水印 2022 ACM】PIMoG 论文题目&#xff1a;PIMoG: An Effective Screen-shooting Noise-Layer Simulation for Deep-Learning-Based Watermarking Network 中文题目&#xff1a;PIMoG:深度学习水印网络中一种有效的截屏噪声层仿真 论文链接&#xff1a;https://dl.acm.o…

Redis-- 缓存预热+缓存雪崩+缓存击穿+缓存穿透

Redis-- 缓存预热缓存雪崩缓存击穿缓存穿透**加粗样式** 一 面试题引入二 缓存预热三 缓存雪崩3.1 问题现象3.2 预防解决 四 缓存穿透4.1 定义4.2 解决方案4.2.1 空对象缓存或者缺省值4.2.2 Google布隆过滤器Guava解决缓存穿透 五 缓存击穿5.1 定义5.2 危害5.3 解决 六 总结 一…

Excel·VBA统计多部门多商品销售量前10%的商品

如图&#xff1a;根据表中唯一的货品ID&#xff0c;有m个事业部中分别有n种货品&#xff0c;统计各事业部销量前10%的货品名称&#xff0c;生成统计表&#xff08;以下为2种统计方式&#xff09; 目录 仅统计货品ID方法1&#xff1a;字典嵌套字典结果 方法2&#xff1a;自定义函…

【LED子系统】十、详细实现流程(番外篇)

个人主页&#xff1a;董哥聊技术 我是董哥&#xff0c;高级嵌入式软件开发工程师&#xff0c;从事嵌入式Linux驱动开发和系统开发&#xff0c;曾就职于世界500强公司&#xff01; 创作理念&#xff1a;专注分享高质量嵌入式文章&#xff0c;让大家读有所得&#xff01; 文章目录…

Hive ---- 文件格式和压缩

Hive ---- 文件格式和压缩 1. Hadoop压缩概述2. Hive文件格式1. Text File2. ORC3. Parquet3. 压缩1. Hive表数据进行压缩2. 计算过程中使用压缩 1. Hadoop压缩概述 为了支持多种压缩/解压缩算法&#xff0c;Hadoop引入了编码/解码器&#xff0c;如下表所示&#xff1a; Hadoo…

CodeForces..李华和迷宫.[简单].[找规律]

题目描述&#xff1a; 题目解读&#xff1a; 存在矩阵迷宫nm&#xff0c;&#xff08;r&#xff0c;c&#xff09;表示从顶部开始的第r行和左起第c列。 如果两单元格共享一个边&#xff0c;则是相邻的。路径是相邻空单元格的序列。 每个单元格初始状态都为空。对于从&#x…

代码随想录额外题目——图论部分

记录一下代码随想录中额外题目的图论部分 841.钥匙和房间 有 n 个房间&#xff0c;房间按从 0 到 n - 1 编号。最初&#xff0c;除 0 号房间外的其余所有房间都被锁住。你的目标是进入所有的房间。然而&#xff0c;你不能在没有获得钥匙的时候进入锁住的房间。 当你进入一个…

山海大模型亮相,云知声交出AGI第一份答卷

有人说&#xff0c;AI大模型是少数巨头才能玩得转的游戏。 截至目前&#xff0c;认同此观点的人不在少数。自从ChatGPT去年迅速火遍全球之后&#xff0c;忽如一夜春风来&#xff0c;AI大模型遍地开。Google、Amazon、阿里、百度等巨头们纷纷加入AI大模型的“军备竞赛”&#x…

【数据分享】1929-2022年全球站点的逐日平均气温数据(Shp\Excel\无需转发)

气象数据是在各项研究中都经常使用的数据&#xff0c;气象指标包括气温、风速、降水、湿度等指标&#xff0c;其中又以气温指标最为常用&#xff01;说到气温数据&#xff0c;最详细的气温数据是具体到气象监测站点的气温数据&#xff01;本次我们为大家带来的就是具体到气象监…

大数据分析案例-基于决策树算法构建世界杯比赛预测模型

&#x1f935;‍♂️ 个人主页&#xff1a;艾派森的个人主页 ✍&#x1f3fb;作者简介&#xff1a;Python学习者 &#x1f40b; 希望大家多多支持&#xff0c;我们一起进步&#xff01;&#x1f604; 如果文章对你有帮助的话&#xff0c; 欢迎评论 &#x1f4ac;点赞&#x1f4…