愿你如阳光,明媚不忧伤。
目録
1. Java 中的日期时间
java.util.Date 是 java.sqlDate,Time,Timestamp 的父类,提供了两个构造函数来实例化 Date 对象。但Date的设计具有"千年虫"以及"时区"的问题,建议使用Calendar类来操作时间。
- 第一个构造函数使用当前日期和时间来初始化对象。
Date( );- 第二个构造函数接收一个参数,该参数是从1970年1月1日起的毫秒数。
Date(long millisec)
* 在Java中输出java new Date(0)
输出的是:Thu Jan 01 08:00:00 CST 1970
,这是因为时区的概念,中国是东八区,所以对应的是早上八点
- Date 对象函数
返回值 | 函数 | 描述 |
---|---|---|
boolean | after(Date date) | Date对象在指定日期之后返回true,否则返回false |
boolean | before(Date date) | Date对象在指定日期之前返回true,否则返回false |
int | compareTo(Date date) | 与指定日期进行比较,两者相等返回0,之前返回负数,之后返回正数 |
返回自1970年1月1日 00:00:00 GMT 以来的毫秒数 | ||
void | setTime(long time) | 用自1970年1月1日00:00:00 GMT以后的毫秒数设置时间和日期 |
String | toString( ) | 转换为:dow mon dd hh:mm:ss zzz yyyy 格式输出 |
- java.util.Calendar 日历函数(部分)
Calendar 类是一个抽象类,在实际使用时实现特定的子类的对象,创建对象的过程对程序员来说是透明的,只需要使用getInstance方法创建即可,其日历字段已由当前日期和时间初始化。
返回值 | 函数 | 描述 |
---|---|---|
Calendar | getInstance( [ TimeZone zone , Locale aLocale ] ) | 返回基于当前时区和区域设置的日历 |
void | add(int field, int amount) | 基于日历的规则实现日期加减 |
boolean | after(Object when) | 判断是否在另一个日期对象表示的时间之后 |
boolean | before(Object when) | 判断是否在另一个日期对象表示的时间之前 |
void | clear( [ int field ] ) | 将日历字段的值和时间值设置为初始状态 |
Object | clone() | 创建并返回该对象的副本 |
int | compareTo(Calendar anotherCalendar) | 与指定日期进行比较,两者相等返回0,之前返回负数,之后返回正数 |
int | get(int field) | 返回指定日历字段的值 |
int | getMaximum(int field) | 返回指定日历字段的理论最大值 |
int | getMinimum(int field) | 返回指定日历字段的理论最小值 |
int | getActualMaximum(int field) | 返回指定日历字段的实际最大值 |
int | getActualMinimum(int field) | 返回指定日历字段的实际最小值 |
Date | getTime() | 返回当前日期 |
void | set(int field) | 设置日历字段的值 |
Date date = new Date();
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
Calendar calendar = Calendar.getInstance();
System.out.println(sdf.format(date));// 2020-12-31 20:08:05
int a = 5;
System.out.println(calendar.get(a));// 31
calendar.clear();
System.out.println(calendar.get(a));// 1
- java.util.Calendar 中的静态常量(日历字段)
静态常量 | 数字 | 描述 | 范围 |
---|---|---|---|
ERA | 0 | 纪元 | 0 - 1 |
YEAR | 1 | 年 | 1 - 292278994 |
MONTH | 2 | 月份 | 0 - 11 |
WEEK_OF_YEAR | 3 | 当年第几周 | 1-53 |
WEEK_OF_MONTH | 4 | 当月第几周 | 0 - 6 |
DATE | 5 | 日期 | 1 - 31 |
DAY_OF_MONTH | 5 | 当月第几天(同 DATE) | 1 - 31 |
DAY_OF_YEAR | 6 | 当年第几天 | 1 - 366 |
DAY_OF_WEEK1 | 7 | 当周第几天 | 1 - 7 |
DAY_OF_WEEK_IN_MONTH | 8 | 当月第几周 | 1 - 6 |
AM_PM | 9 | 上午 / 下午 | 0 - 1 |
HOUR | 10 | 小时 | 0 - 11 |
HOUR_OF_DAY | 11 | 一天中的第几小时 | 0 - 23 |
MINUTE | 12 | 分 | 0 - 59 |
SECOND | 13 | 秒 | 0 - 59 |
MILLISECOND | 14 | 毫秒 | 0 - 999 |
ZONE_OFFSET | 15 | 毫秒为单位指示距 GMT 的大致偏移量 | -46800000 - 50400000 |
DST_OFFSET | 16 | 毫秒为单位指示夏令时的偏移量 | 0 - 7200000 |
FIELD_COUNT | 17 | 字段值总数 | 0 - 16 |
- java.text.DateFormat 格式化日期抽象类
DateFormat 是日期/时间格式化子类的抽象类,它以与语言无关的方式格式化并分析日期或时间。
- java.text.SimpleDateFormat 格式化日期
SimpleDateFormat 是一个以与语言环境相关的方式来格式化和分析日期的具体类,常用格式:“yyyy-MM-dd hh:mm:ss”
Date date = new Date();
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
System.out.println(sdf.format(date));
// 2020-12-24 01:24:59
字母 | 描述 |
---|---|
a | A.M./P.M. 标记 |
DDD | 一年中的日子 |
dd | 一月中的日子 |
E | 星期几 |
F | 一个月中第几周的周几 |
G | 纪元标记(AD) |
HH | 二位数表示小时 24进制(0-23) |
hh | 二位数表示小时 12进制(1-12) |
K | A.M./P.M. (0~11)格式小时 |
k | 一天中的小时(1~24) |
MM | 月份 |
mm | 分钟 |
ss | 秒数 |
sss | 毫秒数 |
W | 一月中的第几周 |
w | 一年中的第几周 |
yyyy | 四位年份 |
z | 时区 |
- printf 格式化日期
自带格式:使用两个字母格式,它以 %t 开头并且以下面表格中的一个字母结尾
自定义格式:用一个格式化字符串指出要被格式化的参数的索引,索引必须紧跟在%后面,而且必须以$结束
转换符 | 说明 | 示例 |
---|---|---|
c | 包括全部日期和时间信息 | 星期六 十月 27 14:21:20 CST 2007 |
F | "年-月-日"格式 | 2020-12-24 |
D | "月/日/年"格式 | 12/24/20 |
r | "HH:MM:SS PM"格式(12时制) | 02:25:51 下午 |
T | "HH:MM:SS"格式(24时制) | 13:24:59 |
R | "HH:MM"格式(24时制) | 13:24 |
A | 星期几的全称 | 木曜日 |
a | 星期几的简称 | 木 |
B | 月份的全称 | 12月 |
b | 月份的简称 | 12月 |
C | 年的前两位 | 20 |
y | 年的后两位 | 20 |
j | 一年中的第几天 | 359 |
m | 两位数字的月份(补0) | 12 |
d | 两位数字的天数(补0) | 24 |
e | 数字的天数(一位不补0) | 24 |
s | 输出字符串 | Due date: |
S | 将字符串以大写形式输出 | DUE DATE: |
n | 表示换行 | - |
Date date = new Date();
System.out.printf("全部日期和时间信息:%tc%n", date);
// 全部日期和时间信息:木 12月 24 14:01:39 CST 2020
System.out.printf("%1$S %2$tB %2$td, %2$tY" , "Due date:", date);
// DUE DATE: 12月 24, 2020
2. MySQL 中的日期时间
- time 数据类型
小时部分大于24的原因是 TIME 类型不仅可以用于表示一天的时间(小于24),还可以表示某个事件过去的时间或两个事件之间的时间间隔(最大间隔35天) - year 数据类型
能够在1个字节内保存0年以及1901~2155年,并能使用两位或四位数字显示它们。所有的两位数字年份均被视为介于1970~2069年之间,这意味着,如果你在YEAR列中保存了01,MySQL服务器会将其当作2001年
数据类型 | 格式 | 范围起 | 范围止 |
---|---|---|---|
date | YYYY-MM-DD | 1000-01-01 | 9999-12-3 |
datetime | YYYY-MM-DD HH:MM:SS | 1000-01-01 00:00:00 | 9999-12-31 23:59:59 |
time | HH:MM:SS | -838:59:59 | 838:59:59 |
timestamp | YYYY-MM-DD HH:MM:SS | 1970-01-01 00:00:00UTC | 2038-01-19 03:14:07UTC |
year | YYYY | 1901 | 2155 |
- Date 日期函数
函数 | 说明 | 示例 |
---|---|---|
NOW() | 返回语句开始执行的日期和时间 | 2021-01-05 18:57:23 |
SYSDATE() | 返回当前动态的实时日期和时间 | 2021-01-05 18:57:23 |
CURDATE() | 返回当前的日期 | 2021-01-05 |
CURTIME() | 返回当前的时间 | 18:57:23 |
DATE(date) | 提取日期或日期/时间表达式的日期部分 | 2021-01-05 |
EXTRACT(unit FROM date) | 返回日期/时间的单独部分 | unit_value |
DATE_ADD(date,INTERVAL expr type) | 向日期添加指定的时间间隔 | 2021-01-06 18:57:23 |
DATE_SUB(date,INTERVAL expr type) | 从日期减去指定的时间间隔 | 2021-01-04 18:57:23 |
DATEDIFF(date1,date2) | 返回两个日期之间的天数 | 30 |
DATE_FORMAT(date,format) | 用不同的格式显示日期/时间 | Jan 01 2021 18:57 PM |
3. Oracle 中的日期时间
数据类型 | 格式 | 范围起 | 范围止 |
---|---|---|---|
date | YYYY-MM-DD | 1000-01-01 | 9999-12-3 |
INTERVAL DAY TO SECOND2 | +/-DDD HH:MM:SS.ssss | - | - |
INTERVAL YEAR TO MONTH3 | +/-YY-MM | - | - |
TIMESTAMP | YYYY-MM-DD HH:MM:SS | 1970-01-01 00:00:00UTC | 2038-01-19 03:14:07UTC |
TIMESTAMP WITH LOCAL TIME ZONE4 | YYYY-MM-DD HH:MM:SS | 1970-01-01 00:00:00UTC | 2038-01-19 03:14:07UTC |
TIMESTAMP WITH TIME ZONE | YYYY-MM-DD HH:MM:SS | 1970-01-01 00:00:00UTC | 2038-01-19 03:14:07UTC |
*****************************************************************
时间间隔字面量 说明
----------------------------------------------------------------
INTERVAL '3' DAY 时间间隔为3天
INTERVAL '2' HOUR 时间间隔为2小时
INTERVAL '25' MINUTE 时间间隔为25分钟
INTERVAL '45' SECOND 时间间隔为45秒
INTERVAL '3 2' DAY TO HOUR 时间间隔为3天零2小时
INTERVAL '3 2:25' DAY TO MINUTE 时间间隔为3天零2小时25分
INTERVAL '3 2:25:45' DAY TO SECOND 时间间隔为3天零2小时25分45秒
INTERVAL '123 2:25:45.12' DAY(3) TO SECOND(2) 时间间隔为123天零2小时25分45.12秒; 天的精度是3位数字,秒的小数部分的精度是2位数字
INTERVAL '3 2:00:45' DAY TO SECOND 时间间隔为3天2小时0分45秒
INTERVAL '-3 2:25:45' DAY TO SECOND 时间间隔为负数,值为3天零2小时25分45秒
INTERVAL '1234 2:25:45' DAY(3) TO SECOND 时间间隔无效,因为天的位数超过了指定的精度3
INTERVAL '123 2:25:45.123' DAY TO SECOND(2) 时间间隔无效,因为秒的小数部分的位数超过了指定的精度2
.................................................................
INTERVAL '123' YEAR(3) 时间间隔为123年【默认精度为2】
INTERVAL '300' MONTH(3) 时间间隔为300月
INTERVAL '123-2' YEAR(3) TO MONTH 时间间隔为123年2个月【
*****************************************************************
- 日期格式化参数
项目 | 参数 | 含义 |
---|---|---|
year | y | 年的最后一位 |
yy | 年的最后二位 | |
yyy | 年的最后三位 | |
yyyy | 四位数表示年 | |
month | mm | 二位数字表示月 |
mon | 简写形式 eg: 12月/dec | |
month | 全称形式 eg: 12月/december | |
day | dd | 当月第几天 |
ddd | 当年第几天 | |
dy | 当周第几天,简写形式 eg: 水/wed | |
day | 当周第几天,全称形式 eg: 水曜日/wednesday | |
hour | hh | 二位数表示小时 12进制 |
hh24 | 二位数表示小时 24小时 | |
minute | mi | 二位数表示分钟 |
second | ss | 二位数表示秒 60进制 |
season | q | 一位数 表示季度 (1-4) |
week | w | 当月第几周 |
ww | 当年第几周 |
select to_char(sysdate,'y-yy-yyy-yyyy-mon-dd-ddd-dy-day-hh24-mi-ss-q-w-ww') from dual;
- 日期函数
函数 | 实例 | 含义 |
---|---|---|
ADD_MONTHS(d,int) | add_months(sysdate,12) | 将给定的日期增加月份 |
LAST_DAY(d) | last_day(sysdate) | 返回指定月份的最后一天 |
MONTHS_BETWEEN(d1,d2) | months_between(sysdate,to_date(‘2020/12/31’,‘yyyy/mm/dd’)) | 返回两个日期之间的月份 |
NEW_TIME(d,tz1,tz2) | new_time(sysdate,‘PDT’,‘GMT’) | tz1的日期和时间是d时,返回时区tz2中的日期和时间 |
NEXT_DAY(d,string) | next_day(‘17-9月-2012’,‘星期六’) | 计算在日期d后满足由string给出的条件的第一天 |
ROUND(d[,format]) | round(sysdate,‘yyyy-MM-DD’) | 将日期d按照由format指定的格式进行处理.如果没有给format则使用缺省设置’DD’ |
TRUNC(d,format) | trunc(sysdate,‘mi’) | 计算截尾到由format指定单位的日期d,缺省参数同ROUNG |
4. 格林威治时间
GMT(Greenwich Mean Time)格林威治平时又称格林威治时间。它规定太阳每天经过位于英国伦敦郊区的皇家格林威治天文台的时间为中午12点。格林威治皇家天文台为了海上霸权的扩张计划,在十七世纪就开始进行天体观测。为了天文观测,选择了穿过英国伦敦格林威治天文台子午仪中心的一条经线作为零度参考线,这条线,简称格林威治子午线。1884年10月在美国华盛顿召开了一个国际子午线会议,该会议将格林威治子午线设定为本初子午线,并将格林威治平时作为世界时间标准。由此也确定了全球24小时自然时区的划分,所有时区都以和 GMT 之间的偏移量做为参考。1972年之前,格林威治时间一直是世界时间的标准。1972年之后,GMT 不再是一个时间标准了。
5. 世界标准时间
UTC(Coodinated Universal Time)协调世界时又称世界统一时间、世界标准时间、国际协调时间。由于英文(CUT)和法文(TUC)的缩写不同,作为妥协,简称UTC。UTC 是现在全球通用的时间标准,全球各地都同意将各自的时间进行同步协调。UTC 时间是经过平均太阳时(以格林威治时间GMT为准)、地轴运动修正后的新时标以及以秒为单位的国际原子时所综合精算而成。在军事中,协调世界时会使用“Z”来表示。又由于Z在无线电联络中使用“Zulu”作代称,协调世界时也会被称为"Zulu time"。
- UTC 由两部分构成:
- 原子时间(TAI, International Atomic Time):
结合了全球400个所有的原子钟而得到的时间,它决定了我们每个人的钟表中,时间流动的速度。 - 世界时间(UT, Universal Time):
也称天文时间,或太阳时,他的依据是地球的自转,我们用它来确定多少原子时,对应于一个地球日的时间长度。
6. 时区
时区(Time Zone)随着火车铁路与其他交通和通讯工具的发展,以及全球化贸易的推动,各地使用各自的当地太阳时间带来了时间不统一的问题,在19世纪催生了统一时间标准的需求,时区由此诞生。从格林威治本初子午线起,经度每向东或者向西间隔15°,就划分一个时区,在这个区域内,大家使用同样的标准时间。全球共分为24个标准时区,相邻时区的时间相差一个小时。但实际上,为了照顾到行政上的方便,常将1个国家或1个省份划在一起。所以时区并不严格按南北直线来划分,而是按自然条件来划分。另外:由于目前,国际上并没有一个批准各国更改时区的机构。一些国家会由于特定原因改变自己的时区。
7. 夏令时
DST(Daylight Saving Time)夏令时又称夏季时间,或者夏时制。它是为节约能源而人为规定地方时间的制度。一般在天亮早的夏季人为将时间提前一小时,可以使人早起早睡,减少照明量,以充分利用光照资源,从而节约照明用电。全球约40%的国家在夏季使用夏令时,其他国家则全年只使用标准时间。标准时间在有的国家也因此被相应地称为冬季时间。在施行夏令时的国家,一年里面有一天只有23小时(夏令时开始那一天),有一天有25小时(夏令时结束那一天),其他时间每天都是24小时。
8. 本地时间
Native Time 在日常生活中所使用的时间我们通常称之为本地时间。这个时间等于我们所在(或者所使用)时区内的当地时间,它由与世界标准时间(UTC)之间的偏移量来定义。这个偏移量可以表示为 UTC-或 UTC+,后面接上偏移的小时和分钟数。
【每日一面】
如何避免在公历闰年时出现日期转换错误或程序逻辑错误
使用 lengthOfYear() 函数来判断当年有多少天
// 获取今年的天数
int daysOfThisYear = LocalDate.now().lengthOfYear();
// 获取指定某年的天数
int daysOfAppointYear = LocalDate.of(2020, 2, 25).lengthOfYear();
周日为第一天,以此类推 ↩︎
需要向数据库提供一个 INTERVAL DAY TO SECOND 字面值,语法格式:
[+|-][ d] [ h[: m[: s]]]’ [DAY[( days_precision)]])[TO HOUR | MINUTE | SECOND[( seconds_precision)]] ↩︎需要向数据库提供一个 INTERVAL YEAR TO MONTH 字面值,语法格式:
[+|-] integer [- integer]’ {YEAR | MONTH} [(precision)][TO {YEAR | MONTH}] ↩︎在跨越多时区的系统里,timestamp with timezone 或者 timestamp with local timezone 比较重要:
timestamp with time zone 表达的是针对标准时区(格林尼治时间)的差。
timestamp with local time zone 表达的是根据你当前所处时区,变化你和格林尼治时间的差。 ↩︎