今天来好好学习一下postgresql涉及时间的字段类型和一些时间的转换函数
一、时间类型:
名字 存储空间 描述 最低值 最高值 分辨率
timestamp [ (p) ] [without time zone] 8字节 包括日期和时间 4713 BC 5874897 AD 1 毫秒 / 14 位
timestamp [ (p) ] with time zone 8字节 日期和时间,带时区 4713 BC 5874897 AD 1 毫秒 / 14 位
interval [ (p) ] 12字节 时间间隔 -178000000 年 178000000 年 1 毫秒 / 14 位
date 4字节 只用于日期 4713 BC 32767 AD 1 天
time [ (p) ] [ without time zone ] 8字节 只用于一日内时间 00:00:00 24:00:00 1 毫秒 / 14 位
time [ (p) ] with time zone 12字节 只用于一日内时间,带时区 00:00:00+1359 24:00:00-135 1 毫秒 / 14 位
说明:
1、time ,timestamp 和interval 接受一个可选的精度值 p,这个精度值声明在秒域后面小数点之后保留的位数。 缺省的时候在精度上是没有明确的绑定的, p 有用的范围对 timestamp和 interval 是从 0 到大约 6
2、对于date和timestamp 数值而言, 是自1970-01-01 00:00:00以来的秒数(结果可能是负数);对于interval数值而言,它是时间间隔的总秒数。
二、当前时间:
test=# select now(),current_timestamp,current_date,current_time;
now | now | date | timetz
-------------------------------+-------------------------------+------------+--------------------
2016-01-11 17:22:25.263468+08 | 2016-01-11 17:22:25.263468+08 | 2016-01-11 | 17:22:25.263468+08
(1 row)
说明:
1、current_timestamp和now()查询结果一致
2、.263468+08 前面是精度p(6),后面是时区+08
补充:
1、去精度
test=# select current_timestamp(0);
timestamptz
------------------------
2016-01-11 17:43:19+08
(1 row)
2、改变精度
test=# select current_timestamp(2);
timestamptz
---------------------------
2016-01-11 17:45:06.26+08
(1 row)
3、去时区
test=# select current_timestamp(0)::timestamp without time zone;
timestamp
---------------------
2016-01-11 17:43:50
(1 row)
4、使用cast函数做类型转换去掉时区
test=# select cast(current_timestamp(0) as timestamp without time zone);
timestamp
---------------------
2016-01-11 17:44:10
(1 row)
三、标准格式
1)日期输入格式
January 8, 1999 在任何datestyle输入模式下都无歧义
1999-01-08 ISO-8601 格式,任何方式下都是1999年1月8号
1/8/1999 歧义,在MDY下是一月八号;在 DMY 模式下读做八月一日
1/18/1999 在MDY模式下读做一月十八日,其它模式下被拒绝
01/02/03 MDY 模式下的2003年一月2日; DMY 模式下的 2003 年 2月 1日; YMD 模式下的2001年二月三日;
1999-Jan-08 任何模式下都是一月8日
Jan-08-1999 任何模式下都是一月8日
08-Jan-1999 任何模式下都是一月8日
99-Jan-08 在 YMD 模式下是一月8日,否则错误
08-Jan-99 一月八日,除了在 YMD 模式下是错误的之外
Jan-08-99 一月八日,除了在 YMD 模式下是错误的之外
19990108 ISO-8601; 任何模式下都是1999年1月8日
990108 ISO-8601; 任何模式下都是1999年1月8日
1999.008 年和年里的第几天
J2451187 儒略日
January 8, 99 BC 公元前99年
由此可见,date最好是使用1999-01-08、Jan-08-1999、19990108这三类格式,比较通用。
2)时间输入格式
04:05:06.789 ISO 8601
04:05:06 ISO 8601
04:05 ISO 8601
040506 ISO 8601
04:05 AM 与04:05一样;AM不影响数值
04:05 PM 与16:05一样;输入小时数必须 <= 12
04:05:06.789-8 ISO 8601
04:05:06-08:00 ISO 8601
04:05-08:00 ISO 8601
040506-08 ISO 8601
time时间最常用的是04:05:06、04:05:06.789-8(加精度和时区)
3)时区输入格式
PST 太平洋标准时间(Pacific Standard Time)
America/New_York 完整时区名称
PST8PDT POSIX风格的时区
-8:00 ISO-8601与PST的偏移
-800 ISO-8601与PST的偏移
-8 ISO-8601与PST的偏移
zulu 军方对UTC的缩写
z zulu的缩写
4)timestamp时间戳输入格式
时间戳类型的有效输入由一个日期和时间的联接组成,后面跟着一个可选的时区(以上三者的结合)因此,1999-01-08 04:05:06和1999-01-08 04:05:06 -8:00都是有效的数值。
5)interval时间间隔输入格式
microseconds 微秒
milliseconds 毫秒
second 秒
minute 分钟
hour 小时
day 天
week 星期
month 月
year 年
decade 十年
century 世纪
millennium 千年
或这些单位的缩写或复数。
interval格式举例:
1-2 SQL标准格式:一年两个月
3 4:05:06 SQL标准格式:3天4小时5分6秒
1 year 2 months 3 days 4 hours 5 minutes 6 seconds 传统Postgres格式: 1年2个月3天4小时5分钟6秒
P1Y2M3DT4H5M6S ISO 8601 "带标识符格式": 1年2个月3天4小时5分钟6秒
P0001-02-03T04:05:06 ISO 8601 "缩写格式": 1年2个月3天4小时5分钟6秒
四、各种时间类型举例
test=# create table t1(id serial not null,name varchar(20),rtime date,stime timestamp,utime timestamp with time zone,wtime interval);
NOTICE: CREATE TABLE will create implicit sequence "t1_id_seq" for serial column "t1.id"
CREATE TABLE
test=# insert into t1(name,rtime,stime,utime,wtime) values('nana','1/6/2015','2015-06-01 00:02:35','2015-06-01 00:02:35+08','1 day');
ERROR: date/time field value out of range: "1/6/2015"
---报错:date类型不支持1/6/2015,因为会产生歧义
^
HINT: Perhaps you need a different "datestyle" setting.
test=# insert into t1(name,rtime,stime,utime,wtime) values('nana','2015-06-01','2015-06-01 00:02:35','2015-06-01 00:02:35+08','1 day');
INSERT 0 1
test=# insert into t1(name,rtime,stime,utime,wtime) values('tina','2015-11-01','2015-11-01 02:04:00','2015-11-01 02:04:00','6 days 3 hours 35 minutes');
INSERT 0 1
test=# insert into t1(name,rtime,stime,utime,wtime) values('lili','2014-12-24','2014-12-24 15:23:12','2014-12-24 15:23:12+08','1y3m5d');
INSERT 0 1
test=# select * from t1;
id | name | rtime | stime | utime | wtime
----+------+------------+---------------------+------------------------+------------------------
1 | nana | 2015-06-01 | 2015-06-01 00:02:35 | 2015-06-01 00:02:35+08 | 1 day
2 | tina | 2015-11-01 | 2015-11-01 02:04:00 | 2015-11-01 02:04:00+08 | 6 days 03:35:00 ---utime自动添加了时区
3 | lili | 2014-12-24 | 2014-12-24 15:23:12 | 2014-12-24 15:23:12+08 | 1 year 5 days 00:03:00 ---3m 被自动判定为分钟minutes,而不是月months,因此还是写具体一点比较好
(3 rows)
类型只写time相当于time with out time zone
五、相关函数
PostgreSQL格式化函数提供一套有效的工具用于把各种数据类型(日期/时间、integer、floating point和numeric)转换成格式化的字符串
以及反过来从格式化的字符串转换成指定的数据类型。
5.1 转换函数 返回类型 描述 例子
to_char(timestamp, text) text 把时间戳转换成字串 to_char(current_timestamp, 'HH12:MI:SS')
to_char(interval, text) text 把时间间隔转为字串 to_char(interval '15h 2m 12s', 'HH24:MI:SS')
to_char(int, text) text 把整数转换成字串 to_char(125, '999')
to_char(double precision, text) text 把实数/双精度数转换成字串 to_char(125.8::real, '999D9')
to_char(numeric, text) text 把numeric转换成字串 to_char(-125.8, '999D99S')
to_date(text, text) date 把字串转换成日期 to_date('05 Dec 2000', 'DD Mon YYYY')
to_timestamp(text, text) timestamp 把字串转换成时间戳 to_timestamp('05 Dec 2000', 'DD Mon YYYY')
to_timestamp(double) timestamp 把UNIX纪元转换成时间戳 to_timestamp(200120400)
to_number(text, text) numeric 把字串转换成numeric to_number('12,454.8-', '99G999D9S')
实例:
postgres=# select current_timestamp,to_char(current_timestamp, 'YYYY-MM-DD HH24:MI'); ---时间戳转换成标准日期格式
now | to_char
-------------------------------+------------------
2016-01-12 17:18:17.993226+08 | 2016-01-12 17:18
postgres=# select to_char(interval '1 years 2months 5days 7hours 8minutes 9seconds', 'YYYY-MM-DD HH24:MI'); ---时间间隔转换成时间戳
to_char
------------------
0001-02-05 07:08
postgres=# select to_char(125,'999'); ---数字125转换成字符串'125'
to_char
---------
125
postgres=# select to_char(125.88,'999'); ---双精度转换成字符串,要注意精度
to_char
---------
126
postgres=# select to_char(125.88,'999D9');
to_char
---------
125.9
postgres=# select to_char(125.88,'999D99');
to_char
---------
125.88
postgres=# select to_char(-125.88,'999D99');
to_char
---------
-125.88
postgres=# select last_record_time from t_sfa_sample_tmp t limit 1;
last_record_time
------------------
1442627263
postgres=# select to_timestamp(last_record_time) from t_sfa_sample_tmp limit 1;
to_timestamp
------------------------
2015-09-19 09:47:43+08
postgres=# select to_number('-12,345.67','99G999D99');
to_number
-----------
-12345.67
5.2 用于日期/时间格式化的模式:
模式 描述
HH 一天的小时数(01-12)
HH12 一天的小时数(01-12)
HH24 一天的小时数(00-23)
MI 分钟(00-59)
SS 秒(00-59)
MS 毫秒(000-999)
US 微秒(000000-999999)
AM 正午标识(大写)
Y,YYY 带逗号的年(4和更多位)
YYYY 年(4和更多位)
YYY 年的后三位
YY 年的后两位
Y 年的最后一位
MONTH 全长大写月份名(空白填充为9字符)
Month 全长混合大小写月份名(空白填充为9字符)
month 全长小写月份名(空白填充为9字符)
MON 大写缩写月份名(3字符)
Mon 缩写混合大小写月份名(3字符)
mon 小写缩写月份名(3字符)
MM 月份号(01-12)
DAY 全长大写日期名(空白填充为9字符)
Day 全长混合大小写日期名(空白填充为9字符)
day 全长小写日期名(空白填充为9字符)
DY 缩写大写日期名(3字符)
Dy 缩写混合大小写日期名(3字符)
dy 缩写小写日期名(3字符)
DDD 一年里的日子(001-366)
DD 一个月里的日子(01-31)
D 一周里的日子(1-7;周日是1)
W 一个月里的周数(1-5)(第一周从该月第一天开始)
WW 一年里的周数(1-53)(第一周从该年的第一天开始)
5.3 用于数值格式化的模板模式:
模式 描述
9 带有指定数值位数的值
0 带前导零的值
.(句点) 小数点
,(逗号) 分组(千)分隔符
PR 尖括号内负值
S 带符号的数值
L 货币符号
D 小数点
G 分组分隔符
MI 在指明的位置的负号(如果数字 < 0)
PL 在指明的位置的正号(如果数字 > 0)
SG 在指明的位置的正/负号
5.4 日期/时间函数:
函数 返回类型 描述 例子 结果
age(timestamp, timestamp) interval 减去参数,生成一个使用年、月的"符号化"的结果 age('2001-04-10', timestamp '1957-06-13') 43 years 9 mons 27 days
age(timestamp) interval 从current_date减去得到的数值 age(timestamp '1957-06-13') 43 years 8 mons 3 days
date_part(text, timestamp) double 获取子域(等效于extract) date_part('hour', timestamp '2001-02-16 20:38:40') 20
date_part(text, interval) double 获取子域(等效于extract) date_part('month', interval '2 years 3 months') 3
date_trunc(text, timestamp)
extract(field from timestamp) double 获取子域 extract(hour from timestamp '2001-02-16 20:38:40') 20
extract(field from interval) double 获取子域 extract(month from interval '2 years 3 months') 3
extract,date_part函数支持的
域 描述 例子 结果
CENTURY 世纪 EXTRACT(CENTURY FROM TIMESTAMP '2000-12-16 12:21:13'); 20
DAY (月分)里的日期域(1-31) EXTRACT(DAY from TIMESTAMP '2001-02-16 20:38:40'); 16
DECADE 年份域除以10 EXTRACT(DECADE from TIMESTAMP '2001-02-16 20:38:40'); 200
DOW 每周的星期号(0-6;星期天是0) EXTRACT(DOW FROM TIMESTAMP '2001-02-16 20:38:40'); 5
DOY 一年的第几天(1 -365/366) EXTRACT(DOY from TIMESTAMP '2001-02-16 20:38:40'); 47
HOUR 小时域(0-23) EXTRACT(HOUR from TIMESTAMP '2001-02-16 20:38:40'); 20
MICROSECONDS 秒域,包括小数部分,乘以 1,000,000 EXTRACT(MICROSECONDS from TIME '17:12:28.5'); 28500000
MILLENNIUM 千年 EXTRACT(MILLENNIUM from TIMESTAMP '2001-02-16 20:38:40'); 3
MILLISECONDS 秒域,包括小数部分,乘以 1000 EXTRACT(MILLISECONDS from TIME '17:12:28.5'); 28500
MINUTE 分钟域(0-59) EXTRACT(MINUTE from TIMESTAMP '2001-02-16 20:38:40'); 38
MONTH 对于timestamp数值,它是一年里的月份数(1-12);
对于interval数值,它是月的数目,然后对12取模(0-11) EXTRACT(MONTH from TIMESTAMP '2001-02-16 20:38:40'); 2
QUARTER 该天所在的该年的季度(1-4) EXTRACT(QUARTER from TIMESTAMP '2001-02-16 20:38:40'); 1
SECOND 秒域,包括小数部分(0-59[1]) EXTRACT(SECOND from TIMESTAMP '2001-02-16 20:38:40'); 40
WEEK 该天在所在的年份里是第几周。 EXTRACT(WEEK from TIMESTAMP '2001-02-16 20:38:40'); 7
YEAR 年份域 EXTRACT(YEAR from TIMESTAMP '2001-02-16 20:38:40'); 2001
date_trunc 函数
在概念上和用于数字的trunc 函数类似。
date_trunc('field', source)
source 是类型 timestamp 的值表达式(类型 date 和 time 的数值都分别自动转换成timestamp或者interval)。
用 field 选择对该时间戳数值 选用什么样的精度进行截断)。 返回的数值是 timestamp 类型或者interval,
所有小于选定的 精度的域都设置为零(或者一,如果是日期和月份域的话)。
例子:
postgres=# SELECT date_trunc('hour', TIMESTAMP '2001-02-16 20:38:40');
date_trunc
---------------------
2001-02-16 20:00:00
postgres=# SELECT date_trunc('year', TIMESTAMP '2001-02-16 20:38:40');
date_trunc
---------------------
2001-01-01 00:00:00
5.5 除了这些函数以外,还支持 SQL 操作符 overlaps
(start1, end1 ) overlaps ( start2, end2)
(start1, length1 ) overlaps ( start2, length2)
这个表达式在两个时间域(用它们的终点定义)重叠的时候生成真值。终点可以以一对日期,时间,或者时间戳来声明;
或者是一个后面跟着一个时间间隔的 日期,时间,时间戳。
postgres=# select (date '2001-02-16', date '2001-12-21') overlaps (date '2001-10-30', date '2002-10-30'); ---两个时间范围重叠
overlaps
----------
t
postgres=# select (date '2001-02-16', interval '100 days') overlaps (date '2001-10-30', date '2002-10-30'); ---两个时间范围未重叠
overlaps
----------
f
六、时间的加减操作
操作 结果
date '2001-09-28' + integer '7' date '2001-10-05'
date '2001-09-28' + interval '1 hour' timestamp '2001-09-28 01:00'
date '2001-09-28' + time '03:00' timestamp '2001-09-28 03:00'
interval '1 day' + interval '1 hour' interval '1 day 01:00'
timestamp '2001-09-28 01:00' + interval '23 hours' timestamp '2001-09-29 00:00'
time '01:00' + interval '3 hours' time '04:00'
date '2001-10-01' - date '2001-09-28' integer '3'
date '2001-10-01' - integer '7' date '2001-09-24'
date '2001-09-28' - interval '1 hour' timestamp '2001-09-27 23:00'
time '05:00' - time '03:00' interval '02:00'
time '05:00' - interval '2 hours' time '03:00'
timestamp '2001-09-28 23:00' - interval '23 hours' timestamp '2001-09-28 00:00'
interval '1 day' - interval '1 hour' interval '23:00'
timestamp '2001-09-29 03:00'-timestamp '2001-09-27 12:00' interval '1 day 15:00'
interval '1 hour' * double precision '3.5' interval '03:30'
interval '1 hour' / double precision '1.5' interval '00:40'
七、时区
AT TIME ZONE 构造允许把时间戳转换成不同的时区。
zone 可以声明为文本串(如'PST')或者一个时间间隔 (比如,INTERVAL '-08:00')。
postgres=# select current_timestamp ,current_timestamp at time zone 'MST';
now | timezone
-------------------------------+----------------------------
2016-01-13 10:29:04.426086+08 | 2016-01-12 19:29:04.426086
(1 row)
postgres=# select current_timestamp ,current_timestamp at time zone 'UTC';
now | timezone
-------------------------------+----------------------------
2016-01-13 10:29:21.187276+08 | 2016-01-13 02:29:21.187276
(1 row)
postgres=# select current_timestamp ,current_timestamp at time zone 'PST';
now | timezone
-------------------------------+----------------------------
2016-01-13 10:29:39.482202+08 | 2016-01-12 18:29:39.482202
(1 row)
postgres=# select current_timestamp ,current_timestamp at time zone 'CCT'; ----UTC+8
now | timezone
-------------------------------+----------------------------
2016-01-13 10:34:19.882214+08 | 2016-01-13 10:34:19.882214
MST(UTC-7)
PST(UTC-8)
EST(UTC-5)
CCT 中国时间 (UTC+8)
八、补充:日常中研发很多时候会把时间字段设置成整型,存储时间戳,但是查询时又需要显示成可读的字符串,因此常常需要转换。
1、时间戳转换成字符串:
postgres=# select current_date,cast(extract(epoch FROM current_date) as integer);
date | date_part
------------+------------
2016-01-12 | 1452556800
postgres=# select timestamp without time zone 'epoch' + 1442627263 * interval '1 second'; --不带时区
?column?
---------------------
2015-09-19 01:47:43
postgres=# select timestamp with time zone 'epoch' + 1442627263 * interval '1 second'; --带时区
?column?
------------------------
2015-09-19 09:47:43+08
postgres=# select timestamp with time zone 'epoch' + last_record_time * interval '1 second' from t_sfa_sample_tmp limit 1; ---结合字段
?column?
------------------------
2015-09-19 09:47:43+08
postgres=# select to_char(to_timestamp(last_record_time), 'YYYY-MM-DD HH24:MI:SS') from t_sfa_sample_tmp limit 1; ---
to_char
---------------------
2015-09-19 09:47:43
2、字符串转换成时间戳:
postgres=# select extract(epoch from timestamp '2015-09-19 09:47:43'); --直接输入timestamp
date_part
------------
1442656063
postgres=# select extract(epoch from interval '1 years 2 months 5 days 3 hours'); ---直接输入interval
date_part
-----------
37184400
postgres=# select update_time,extract(epoch from update_time) from off_shell_relation limit 1; ---结合字段
update_time | date_part
---------------------+------------
2015-11-26 19:07:45 | 1448536065
相关文章
- 04-2410月22日纯血鸿蒙正式版发布意味着什么?-应用管控中心:鸿蒙系统提供了应用管控中心,能够智能识别应用的风险行为,并给出将其放入应用管控中心的提示,以便在更安全可控的环境下调用。对于被加入管控的应用,系统会通过空白信息、模糊定位等方式隐藏或禁用真实敏感的用户数据,并限制应用弹框,确保应用在安全受控的前提下正常运行。 隐私保护功能:鸿蒙系统提供了图片隐私保护功能,可以在分享照片时去除图片的位置信息和拍摄数据。此外,还有AI隐私保护功能,可以自动识别并一键打码身份证、银行卡号、车票信息、头像昵称等敏感信息,防止隐私泄露。 系统级文件加密分享:鸿蒙系统支持系统级的文件加密分享机制,用户可以在手机或平板上对文件进行加密,只有授权的用户才能打开,这种系统级的分享机制不依赖应用,不限分享渠道,并支持多种文件类型。 安全认证:鸿蒙系统的安全能力获得了行业最高等级的安全认证,鸿蒙内核获得了国际CC EAL6+证书,这是业界通用操作系统内核领域首个6+等级认证。整个系统还获得了中国CCRC EAL5+认证,是业界唯一获得此认证的操作系统。 隐私灯功能:鸿蒙系统推出了全新的隐私灯功能,能在状态栏明确提示用户当前有应用正在使用麦克风、摄像头或地理位置,并能做到全局的实时显示,有效防止被应用覆盖,确保用户能够实时了解应用正在使用的敏感权限。 应用权限管理:鸿蒙系统全面梳理了所有系统授权,禁止开放了9类不合理权限,包括读取已安装应用列表、访问短信、访问存储文件等,确保应用只能访问特定权限,保护用户数据的安全和私密性。 分布式架构:鸿蒙系统的分布式架构支持多种设备间的无缝协作,允许手机轻松连接到其他设备,实现资源共享和跨设备的任务处理,同时确保了数据在不同设备间的安全传输。 微内核设计:鸿蒙系统采用微内核设计,有效防止了外部攻击,并且通过形式化方法,重塑可信安全,提供更强的安全特性和低时延等特点。 数据生命周期保护:鸿蒙系统参照数据的风险分级,提供了基于全生命周期的数据保护能力,包括数据的生成、存储、使用、传输和销毁等阶段,确保数据在各个阶段的安全。 以上这些特性共同构成了鸿蒙系统在安全和隐私保护方面的全面策略,为用户提供一个安全可靠的操作系统环境。 鸿蒙系统惊人的迭代速度 从官网鸿蒙文档的发布可以看出,纯血鸿蒙NEXT在6月份面向开发者发布 Beta1版本以来,短短4个月时间,经过6个Beta 版的迭代,到昨天发布会正式发布,V 哥从文档日期看到,HarmonyOS NEXT Release 版,更新于2024-10-18 17:16。 正式版的发布,为首款搭载纯血鸿蒙 NEXT 手机 Mate70的发布提前奠定了基础,让我们一起期待12月份里程碑式的发布会。 鸿蒙系统是智能时代的基础 当下,我们正面临第四次工业革命的进程,从第一次以蒸汽机为首的机器取代人力生产的机械制造时代,到第二次以电力大规模应用为代表的电气化和自动化时代,再到第三次以计算机和电子数据普及为代表的电子信息时代,我们都在学习和模仿,这一次的智能时代来了,鸿蒙系统将发挥着重要的基础能力。智能设备和产品,就得依托智能底座系统。 虽然说从诺基亚手机的塞班系统开始就称之为智能手机系统,随着iPhone的横空出世,和Android系统生态的发展,智能操作系统才真正被称为智能。而鸿蒙 NEXT,又重新定义了什么是智能操作系统,听 V 哥慢慢道来。 iOS 和 Android 都是为单一设备设计的操作系统,它们的内核和系统架构主要针对手机、平板等移动设备进行优化。所以我们会看到例如 iOS的应用有手机版,pad版多套应用,这无疑给企业开发增加而外的工作量。 再一个,虽然 iOS 和 Android 支持多任务和后台处理,但它们并不是为跨设备协作设计的分布式系统。在多设备协同工作方面,它们主要依赖于云服务和第三方应用来实现。 而鸿蒙 NEXT 系统(HarmonyOS NEXT)是一个分布式操作系统,它支持多种设备之间的无缝协作,实现了真正的分布式架构。鸿蒙系统通过微内核设计,提供了更好的性能和安全性,同时支持跨设备的统一操作体验。分布式系统是指由多个独立的计算机组成的系统,这些计算机之间通过网络相互连接,协同工作以完成特定的任务。 所以,在鸿蒙应用开发中,可以真正实现一次开发多端部署的特点。因为鸿蒙系统本身是分布式系统架构。这个特性不简单,随着物联网的发展,除了手机、平板、电视、手表等等这些智能设备,鸿蒙为更多的物联网、泛物联网设备的产生提供了天然的支持,鸿蒙系统可以让这些设备之间实现丝滑的数据流转,为所有智能设备提供了统一的系统级标准,这为智能时代的发展带来无限的可能,手机、平板等不是全部,而是物联网设备中的其中一种而已。 鸿蒙时代必将开启全新的世界。
- 04-24用最短长度的绳子把整个花园围起来-输入: points = [[1,2],[2,2],[4,2]] 输出: [[4,2],[2,2],[1,2]] class Solution { public: vector<vector<int>> outerTrees(vector<vector<int>>& trees) { // 如果树的数量小于等于 1,直接返回 if (trees.size <= 1) return trees; // 自定义比较函数 auto cmp = (vector<int>& p1, const vector<int>& p2) { return p1[0] < p2[0] || (p1[0] == p2[0] && p1[1] < p2[1]); }; sort(trees.begin, trees.end, cmp); // 构建下凸包 vector<vector<int>> lower; for (auto& tree : trees) { while (lower.size >= 2 && cross(lower[lower.size - 2], lower.back, tree) < 0) { lower.pop_back; } lower.push_back(tree); } // 构建上凸包 vector<vector<int>> upper; for (int i = trees.size - 1; i >= 0; i--) { auto& tree = trees[i]; while (upper.size >= 2 && cross(upper[upper.size - 2], upper.back, tree) < 0) { upper.pop_back; } upper.push_back(tree); } vector<vector<int>> result(lower); result.insert(result.end, upper.begin, upper.end); set<vector<int>> res(result.begin, result.end);// 去掉重复的点 return vector<vector<int>>(res.begin,res.end);//返回vector<vector<int>>类型 } // 计算叉积 int cross(vector<int>& O, vector<int>& A, vector<int>& B) { return (A[0] - O[0]) * (B[1] - O[1]) - (A[1] - O[1]) * (B[0] - O[0]); } }; auto cmp = (vector<int>& p1, const vector<int>& p2) { return p1[0] < p2[0] || (p1[0] == p2[0] && p1[1] < p2[1]); }; 这个比较函数用于根据树木的位置对它们进行排序。首先按 x 坐标排序,如果 x 坐标相同,则按 y 坐标排序。 叉积 A×B=Ax⋅By−Ay⋅Bx 可以帮助判断三点之间的相对方向。给定三点 O(原点)、A 和 B,叉积的结果可以用来判断 A 和 B 相对于 O 的位置关系: 正数:表示 B 在 A 的左侧,形成的角度是逆时针(O -> A -> B 是一个左转)。 负数:表示 B 在 A 的右侧,形成的角度是顺时针(O -> A -> B 是一个右转)。 零:表示 A 和 B 在同一条直线上。 构建凸包: while (lower.size >= 2 && cross(lower[lower.size - 2], lower.back, tree) < 0) 构建下凸包时,必须要保证有至少两个点,才能进行三点之间的相对方向判断。while 循环可以确保我们在引入每一个新点时,能够动态地调整 lower 中的点,以确保所有点都能形成一个外包围的凸形结构。 举个例子:第一个点 [1, 1]: 加入 lower,当前 lower = [[1, 1]] 第二个点 [2, 0]: 加入 lower,当前 lower = [[1, 1], [2, 0]] 第三个点 [3, -1]: 现在 lower.size == 2,计算叉积: cross([1, 1], [2, 0], [3, -1]) : (2 - 1) * (-1 - 1) - (0 - 1) * (3 - 2) = 1 * (-2) - (-1) * 1 = -2 + 1 = -1 叉积为负数,说明这三个点构成了 顺时针方向,这通常意味着形成了一个凹形。因此,进入 while 循环,移除 [2, 0],然后再将 [3, -1] 加入 lower。 lower 最终包含的是所有位于下边界上的点,这些点构成了围绕给定树木坐标的下半部分的凸包。具体来说,lower 会包含从最左侧的点到最右侧的点,形成一个向上的弯曲结构。 upper 构建上凸包。代码的逻辑与构建下凸包的过程相似,但它从树木坐标的最后一个点开始逆序遍历,直到第一个点。 最后将将 lower 和 upper 两个 vector 合并为一个新的 vector result.insert(result.end, upper.begin, upper.end); result.end 表示插入的位置是 result 的末尾。 upper.begin 和 upper.end 表示要插入的元素范围,即从 upper 的起始位置到结束位置。 set 去重:去除upper和lower重复的部分 set<vector<int>> res (result.begin, result.end); 在构造过程中,set 会自动去除 result 中的重复元素,只保留唯一的元素
- 04-24PHP 日期和时间 Date函数 获取当前时间
- 04-24无人机干扰技术及干扰设备突破性发展-1.无线电干扰:由于无人机在遥控、定位、数据传输等方面都依赖于无线电技术,因此通过发射干扰信号可以破坏无人机的通信链路,使其失去控制或无法传输数据。 2.GPS干扰:GPS是无人机定位的主要方式之一,通过发送误导性的GPS信号,可以使无人机无法准确获取位置信息,导致其定位偏移或丧失导航能力。 3.信号屏蔽:通过发射特定频率的屏蔽信号,可以阻止无人机接收到控制信号或传输数据,从而使其失去控制或无法完成任务。 4.光学干扰:利用强光束或激光器等设备对无人机的光学传感器和摄像头进行干扰,可以降低其视觉识别和目标跟踪能力,甚至使其无法正常工作。 无人机干扰设备是一种用于干扰无人机通信和导航的设备。它们通常使用无线电信号、电磁波或其他物理手段来干扰无人机的正常运行。这些设备可以用于各种目的,例如保护军事设施、监视区域、保护公共安全等。 然而,无人机干扰设备也存在一些问题和风险。首先,它们可能会对周围的无线设备造成干扰,包括手机、电视、无线电等。其次,无人机干扰设备可能会对无人机的控制系统造成损坏,导致无人机坠毁或失控。最后,无人机干扰设备可能会对他人隐私和安全造成威胁。因此,在使用无人机干扰设备时,必须遵守相关法律法规和道德准则,确保不会对他人造成任何伤害或损失。同时,也需要注意使用无人机干扰设备的合适性和必要性,避免过度使用或滥用。 另外,随着无人机技术的不断发展和广泛应用,无人机干扰设备也需要不断更新和改进,以适应新的挑战和需求。例如,一些先进的无人机干扰设备可以识别并仅干扰特定类型的无人机,减少对周围无线设备的干扰。同时,一些无人机干扰设备也可以与无人机进行通信,引导无人机降落或返回,避免对人员和财产造成伤害。 无人机干扰技术及干扰设备的发展近年来取得了显著的突破。这些突破主要体现在两个方面:声波干扰技术和微波武器领域的新突破。
- 04-24C++ Pirmer : 第十五章 : 面向对象程序设计之基类和派生的定义、类型转换与继承与虚函数
- 04-24基础总结深入:数据类型的分类和判断(数据、内存、变量) 对象 函数 回调函数 IIFE 函数中的this 分号
- 04-24class集中保存一个类型的构造函数和原型对象
- 04-24Chapter8:隐函数求导和相关变化率
- 04-24枚举类型互相转换(使用GetEnumName和TypeInfo两个函数)
- 04-24四、数据类型_5.(2).dict - 相关函数