如何正确地处理时间

从URDF到Gazebo:一个完整的ROS2机械臂仿真项目实战与避坑指南 本文提供了一个完整的ROS2机械臂仿真项目实战指南,详细讲解了从URDF建模、ROS2 Control配置、MoveIt2集成到Gazebo仿真的全流程。文章重点分享了URDF惯性参数设置、Gazebo插件选择、MoveIt2配置修正等关键步骤的避坑经验,帮助开发者快速搭建可用的六轴机械臂仿真环境,实现从静态模型到物理仿真的跨越。 阅读详情

日期和时间在程序中应用广泛,每种程序开发语言都自带处理日期和时间的相关函数,很多开发者把日期和时间存入数据库中,但是,一旦涉及到跨时区的日期和时间的处理时,大多数开发者根本就不明白如何正确地处理日期和时间。

首先,我们来看大部分的程序都是这么创建当前时间并存入数据库的:

Date date = new Date();
store2db(date);

这么做的问题在于,数据库的DateTime类型没有时区(time zone)信息,因此,存入的是本地时间,并且丢掉了时区信息。如果你把数据库服务器的时区改了,或者把应用服务器的时区改了,读出来的日期和时间就是错误的。如果以Timestamp类型存储,各数据库的实现也不相同,有的进行了内部时区自动转换,而且,存储的时间不超过2037年。

如果应用服务器的时区和数据库服务器的时区不一致,你无法确定数据库驱动程序会不会自动帮你转换。

大多数开发者遇到这个问题不是去探索正确的解决方法,而是自作聪明地在存入数据库之前先来个“调整”,比如把当前时间减掉8小时,在显示的时候遇到不正确的时间时,又来个“调整”,以“负负得正”的方式来掩盖错误。在遇到夏令时的时区时,还需要写更复杂的代码来调整小时。

正确的做法是先理解时间和时区的概念。

时区的概念

之所以有时区的概念是因为住在地球上不同地方的人看到太阳升起的时间是不一样的。我们假设北京人民在早上8:00看到了太阳刚刚升起,而此刻欧洲人民还在夜里,他们还需要再过7个小时才能看到太阳升起,所以,此刻欧洲人民的手表上显示的是凌晨1:00。如果你强迫他们用北京时间那他们每天看到日出的时间就是下午3点。

也就是说,东8区的北京人民的手表显示的8:00和东1区欧洲人民手表显示的1:00是相同的时刻:

"2014-10-14 08:00 +8:00" = "2014-10-14 01:00 +1:00"

这就是本地时间的概念。

但是,在计算机中,如果用本地时间来存储日期和时间,在遇到时区转换的问题上,即便你非常清楚地知道如何转换,也非常麻烦,尤其是矫情的美国人还在采用夏令时。

所以我们需要引入“绝对时间”的概念。绝对时间不需要年月日,而是以秒来计时。当前时间是指从一个基准时间(1970-1-1 00:00:00 +0:00),到现在的秒数,用一个整数表示。

当我们用绝对时间表示日期和时间时,无论服务器在哪个时区,任意时刻,他们生成的时间值都是相等的。所有编程语言都提供了方法来生成这个时间戳,Java和JavaScript输出以毫秒计算的Long型整数,Python等输出标准的Unix时间戳,以秒计算的Float型浮点数,这两者转换只存在1000倍的关系。

实际上,操作系统内部的计时器也是这个标准的时间戳,只有在显示给用户的时候,才转换为字符串格式的本地时间。

正确的存储方式

基于“数据的存储和显示相分离”的设计原则,我们只要把表示绝对时间的时间戳(无论是Long型还是Float)存入数据库,在显示的时候根据用户设置的时区格式化为正确的字符串。

数据的存储和显示相分离是非常基本的设计原则,却常常被大多数开发人员忽略。举个例子,在Excel中编写一个表格,表格的数据可视为数据的存储格式,你可以把表格的数据以柱状图或饼图表示出来,这些不同的图表是数据的不同显示格式,存储数据的时候,我们应该存储表格数据,绝不应该存储柱状图等图片信息。

HTML和CSS也是数据的存储和显示相分离的设计思想。

所以,数据库存储时间和日期时,只需要把Long或者Float表示的时间戳存到BIGINT或REAL类型的列中,完全不用管数据库自己提供的DATETIME或TIMESTAMP,也不用担心应用服务器和数据库服务器的时区设置问题,遇到Oracle数据库你不必去理会with timezone和with local timezone到底有啥区别。

读取时间时,读到的是一个Long或Float,只需要按照用户的时区格式化为字符串就能正确地显示出来:

// Java:
long t = System.currentTimeMillis();
System.out.println("long = " + t);

// current time zone:
SimpleDateFormat sdf_default = new SimpleDateFormat("yyyy-MM-dd HH:mm");
System.out.println(sdf_default.format(t));

// +8:00 time zone:
SimpleDateFormat sdf_8 = new SimpleDateFormat("yyyy-MM-dd HH:mm");
sdf_8.setTimeZone(TimeZone.getTimeZone("GMT+8:00"));
System.out.println("GMT+8:00 = " + sdf_8.format(t));

// +7:00 time zone:
SimpleDateFormat sdf_7 = new SimpleDateFormat("yyyy-MM-dd HH:mm");
sdf_7.setTimeZone(TimeZone.getTimeZone("GMT+7:00"));
System.out.println("GMT+7:00 = " + sdf_7.format(t));

// -9:00 time zone:
SimpleDateFormat sdf_la = new SimpleDateFormat("yyyy-MM-dd HH:mm");
sdf_la.setTimeZone(TimeZone.getTimeZone("America/Los_Angeles"));
System.out.println("America/Los_Angeles = " + sdf_la.format(t));

输出:

long = 1413230086802
2014-10-14 03:54
GMT+8:00 = 2014-10-14 03:54
GMT+7:00 = 2014-10-14 02:54
America/Los_Angeles = 2014-10-13 12:54

基于绝对时间戳的时间存储,从根本上就没有时区的问题。时区只是一个显示问题。额外获得的好处还包括:

  • 两个时间的比较就是数值的比较,根本不涉及时区问题,极其简单;

  • 时间的筛选也是两个数值之间筛选,写出SQL就是between(?, ?);

  • 显示时间时,把Long或Float传到页面,无论用服务端脚本还是用JavaScript都能简单而正确地显示时间。

你唯一需要编写的两个辅助函数就是String->Long和Long->String。String->Long的作用是把用户输入的时间字符串按照用户指定时区转换成Long存进数据库。

唯一的缺点是数据库查询你看到的不是时间字符串,而是类似1413266801750之类的数字。


原文:http://www.liaoxuefeng.com/article/0014132675721847f569c3514034f099477472c73b5dee2000

python 实现一个完整的基于Python的多视角三维重建系统,包含特征提取与匹配、相机位姿估计、三维重建、优化和可视化等功能 本文介绍了一个基于Python的多视角三维重建系统的实现,涵盖了特征提取与匹配、相机位姿估计、三维重建、优化和可视化等功能。首先,系统通过安装必要的库(如OpenCV、NumPy等)并加载图像数据,初始化相机参数。接着,系统使用SIFT、SURF或ORB算法提取图像特征点,并通过FLANN或BF方法进行特征匹配,应用Lowe's ratio test筛选优质匹配。该系统为后续的相机位姿估计和三维重建奠定了基础,能够从多视角图像中恢复三维场景结构。 阅读详情

相关推荐

Win10局域网内文件共享+远程桌面控制保姆级教程(含常见问题解决)

本文提供Win10局域网内文件共享和远程桌面控制的详细教程,包括环境检查、共享文件夹设置、远程桌面连接步骤及常见问题解决方案。通过内置功能实现高效办公协作,提升多设备协同工作效率,特别适合需要频繁传输文件或远程控制场景的专业人士。

rose2的博客 777

(转)如何正确地处理时间

from: http://www.liaoxuefeng.com/article/0014132675721847f569c3514034f099477472c73b5dee2000 日期和时间在程序中应用广泛,每种程序开发语言都自带处理日期和时间的相关函数,很多开发者把日期和时间存入数据库中,但是,一旦涉及到跨时区的日期和时间的处理时,大多数开发者根本就不明白如何正确地处理日期和时间...

jackyrongvip的专栏 1089

uniapp自定义tabbar闪屏?3步搞定原生tabbar隐藏+自定义占位(附完整代码)

本文针对UniApp开发中自定义TabBar切换页面闪烁的痛点,提供了一套根治方案。通过隐藏原生TabBar并利用自定义组件进行视觉占位,巧妙结合原生切换的无闪烁优势与自定义设计的灵活性。文章详细解析了闪屏根源,并附上完整的page.json配置与代码实现,帮助开发者彻底解决此问题,提升小程序应用质感。

postgres8guard的博客 1529

不同时区时间转化为时间戳

不同时区的时间戳的转换

老衲的少女心i~ 4235

智能车轮腿组‘定点排雷’科目全解析:从雷区识别到姿态控制

本文深入解析了智能车竞赛轮腿穿越组‘定点排雷’科目的核心技术。从构建鲁棒的视觉识别系统,到融合编码器与IMU进行厘米级定位,再到实现框内高精度旋转的姿态控制,提供了一套完整的从感知到执行的闭环技术方案,助力参赛队伍攻克这一高难度科目。

weixin_29161719的博客 639

APK静态分析(取证角度)——理论部分

APP是指应用程序(Application),是指能够在手机、平板电脑、电脑等移动设备上运行的软件。APP可以帮助用户进行各种功能操作,如社交媒体、游戏、购物、学习、工作等。用户可以通过应用商店或者在线下载安装APP,然后在设备上使用它们。APP的种类非常丰富,能够满足用户不同的需求和兴趣。

currify的博客 3206

mysql5.7 默认值为CURRENT_TIMESTAMP 与实际时间相差8小时

mysql5.7 默认值为CURRENT_TIMESTAMP 与实际时间相差8小时1.写在前面2.正经解决问题 1.写在前面   老手看到这个问题描述应该就能一下子明白是什么原因,那肯定就是时区的问题啊,没错,博主遇到这个问题的时候,第一时间也定位到了问题所在,但是解决的时候,确实走了一点小弯路。 2.正经解决问题   定位到问题所在了,那就直接上手解决,既然是时区问题,那就直接上手。 set time_zone = '+08:00'; -- 刷新 立刻生效 flush privileges;   这么处

cheng137666的博客 4710

【Matlab深度学习】GPU加速实战:从环境配置到性能优化

本文详细介绍了如何在Matlab中为深度学习任务配置GPU加速环境并进行性能优化。文章从GPU加速的必要性讲起,手把手指导安装NVIDIA驱动、CUDA和cuDNN核心三件套,并验证环境。重点讲解了如何利用gpuArray将数据和模型迁移至GPU,以及通过内存优化、计算优化和多GPU并行等策略充分释放GPU算力,大幅缩短深度学习模型的训练时间。

weixin_29061465的博客 490

[ 案例分析 ] 数据库时间字段CURRENT_TIMESTAMP ON UPDATE导致时间错乱

一、问题描述 Mysql数据库CURRENT_TIMESTAMP时间字段在更新其他字段数据时发生变更(开始时间小于结束时间) 二、定位方法 1、判断项目部署服务器和数据库所在服务器是否是同一个服务器,如果不是,服务器间时间是否同步一致。 观察数据库脚本中出问题的时间字段的属性设置有什么特点。 2、观察数据库脚本中出问题的时间字段的属性设置有什么特点

架构探险之道 9596

详解AUTOSAR:DaVinci Configurator导入ARXML配置(拓展篇—2)

DaVinci Configurator导入ARXML配置。

不脱发的程序猿 3326

华为OD面试手撕真题 【合并相邻且相等的元素】多语言题解

华为OD面试高频手撕真题【合并相邻且相等的元素】,提供C语言、Java、C++、Python、Go、JavaScript源码实现,并提供完整思路讲解。

qq_45776114的博客 545

字符串日期转换时间戳

@SneakyThrows @Test public void testQuery(){ //存------年月日时分 Timepoji timepoji=new Timepoji(); timepoji.setDateF("2021-08-04"); timepoji.setHourF("10:20"); String s=timepoji.getDateF()+" "+timepoji.getHou...

weixin_52380943的博客 909

【八股】JUC并发编程篇

👉抽象队列同步器,就是一种锁,内部维护的是一个先进先出的双向队列,队列中存储的是排队的线程,用state来标识是否有线程获得锁【0是无锁状态】👉流程:当一个线程拿到锁后会修改state = 1,这时如果有其他线程访问则会进入队列进行排序,直到state变成0后,队头线程才会拿到锁。在对state进行修改时,用的是CAS操作,所以可以保证原子性。👉它可以实现公平锁或非公平锁【默认】,上述是一个公平锁。如果新线程和队头线程抢锁资源就是非公平锁。

qq_44768318的博客 551

Java如何正确地处理时间

前言 日期和时间在程序中应用广泛,每种程序开发语言都自带处理日期和时间的相关函数,很多开发者把日期和时间存入数据库中,但是,一旦涉及到跨时区的日期和时间的处理时,大多数开发者根本就不明白如何正确地处理日期和时间。 首先,我们来看大部分的程序都是这么创建当前时间并存入数据库的: //伪代码 Date date = new Date(); store2db(date); 这么做的问题在于,数据库的...

雨雾清影的个人博客 266

jdk-8u144-linux-x64.tar.gz.

该资源为搭建Linux系统Java环境用,资源的后缀为tar.gz格式的压缩包

蓝牙模块HM-10手册

蓝牙模块HM-10手册,该手册对蓝牙模块HM-10进行了详细的介绍和使用方法以及一些AT指令。

JAVA如何正确地处理时间/时区

日期和时间在程序中应用广泛,每种程序开发语言都自带处理日期和时间的相关函数,很多开发者把日期和时间存入数据库中,但是,一旦涉及到跨时区的日期和时间的处理时,大多数开发者根本就不明白如何正确地处理日期和时间。 首先,我们来看大部分的程序都是这么创建当前时间并存入数据库的: Date date = new Date(); store2db(date); 这么做的问题在于,数据库的DateTime类型没有时区(time zone)信息,因此,存入的是本地时间,并且丢掉了时区信息。如果你把数据库服务器的时区改了,或

qq_38322989的博客 610

STM32F407中文手册

STM32f407中文手册 本参考手册面向应用开发人员,提供有关使用 STM32F405xx/07xx、STM32F415xx/17xx、 STM32F42xxx 和 STM32F43xxx 微控制器存储器与外设的完整信息。STM32F405xx/07xx、STM32F415xx/17xx、STM32F42xxx 和 STM32F43xxx 构成一个微 控制器系列,各产品具有不同的存储器大小、封装和外设。有关订购信息以及器件的机械与电气特性,请参见数据手册。有关 ARM Cortex™-M4F 内核的信息,请参见《Cortex™-M4F 技术参考手册》。

【转】如何正确地处理时间

日期和时间在程序中应用广泛,每种程序开发语言都自带处理日期和时间的相关函数,很多开发者把日期和时间存入数据库中,但是,一旦涉及到跨时区的日期和时间的处理时,大多数开发者根本就不明白如何正确地处理日期和时间。 首先,我们来看大部分的程序都是这么创建当前时间并存入数据库的: Date date = new Date(); store2db(date); 这么做的问题在于,数据库的...

weixin_33716941的博客 96

时间处理逻辑,分和秒

输入tm=11 输出11:00 输入1输出 01:00 时间处理时分,没有秒 function makeTime(tm) { if(!tm){return ''} //let regTm=/^(?:(?:[0-2][0-3])|(?:[0-1][0-9])):[0-5][0-9]:[0-5][0-9]$/; let regTm=/^(?:(?:[0-...

jicai520的博客 317

JAVA 处理带"AM" 或 "PM"的时间

直接了当: SimpleDateFormat formatTime = new SimpleDateFormat("yyyy/MM/dd hh:mm:ss aa", Locale.ENGLISH); 注意:hh:mm:ss 不能是HH:mm:ss 如果是HH: 正确的结果应该是:2019-03-03 07:10:10 PM 反过来解析我们解析需要注意: 解析时需要使用 ...

qq_34926773的博客 8860

Python | 处理海洋2C 数据 | 非标准时间格式

最近,师弟在用Python读取某海洋2C数据时,突然冒出一个报错:“时间单位的参考日期无效,当前日期 00:00:00.0这让我回想起,似乎在很久很久以前,我处理SMAP和Argo数据时也遇到过类似的问题。为了不让未来的师弟师妹们再次被这种问题困扰,我决定在这里记录一下这个坑。希望未来再看到这条记录时,能少叹气、多微笑,毕竟已经知道怎么解决了嘛!

【更新于公众号 | 简谱学记】 1385

JDBC 时间处理

Java中用类java.util.Date对日期/时间做了封装,此类提供了对年、月、日、时、分、秒、毫秒以及时区的控制方法,同时也提供一些工具方法,比如日期/时间的比较,前后判断等。java.util.Date中采用一个long型的数来保存日期/时间,它表示从格林威治时间1970年1月1日00点00分00秒至今的毫秒数。JDBC中,在这个类的基础之上扩展了3个类:java.sql.D...

dbzv41255的博客 210

python 输入一个时间,获取这个时间的下一秒

输入一个时间,获取这个时间的下一秒 time1 =input("输入一个时间[HH:MM:SS]:") time1List = time1.split(":") time1List = [int(x) for x in time1List] shi = time1List[0] fen = time1List[1] miao = time1List[2] if miao==59: m...

l_d_56的博客 7644

Flink的时间(Time)机制

乱序问题 某数据源中的某些数据由于某种原因会有5秒的延迟,也就是在实际时间的第1秒产生的数据有可能5秒中产生的数据之后到来,如何让这个延迟的数据回到正确的顺序位置; Time类型: Time是Flink中重要概念之;关于Apache Flink中有如下三种时间类型: Processing Time : 处理时间,当前机器处理该事件的时间(即进入某个算子时的系统时间),有着最好的性能和最低的延迟...

weixin_44735572的博客 2351

(转)JDBC中日期时间的处理技巧

Java中用类java.util.Date对日期/时间做了封装,此类提供了对年、月、日、时、分、秒、毫秒以及时区的控制方法,同时也提供一些工具方法,比如日期/时间的比较,前后判断等。 java.util.Date中采用一个long型的数来保存日期/时间,它表示从格林威治时间1970年1月1日00点00分00秒至今的毫秒数。 JDBC中,在这个类的基础之上扩展了3个类:java.sql.Date,...

。 441

7. 输入一个时间(小时 : 分钟: 秒),输出该时间经过 5 分 30 秒后的时间

输入一个时间(小时 : 分钟: 秒),输出该时间经过 5 分 30 秒后的时间一、思路:   split的用法。二、代码:hour, minute, second = input('请输入一个时间( h:m:s): \n').split(':') hour = int(hour) minute = int(minute) second = int(second) second = second +...

CruiseZhang 1万+
上一篇: java在不同系统中处理换行符
下一篇: 如何在filter中拿到spring容器
hellocdw
博客等级 码龄15年 5粉丝 26原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值