介绍API之前,先了解下几个基本知识。
计算世界时间的主要标准有:
- UTC(Coordinated Universal Time)协调世界时:是以原子时秒长为基础,在时刻上尽量接近于世界时的一种时间计量系统。
- GMT(Greenwich Mean Time)世界时:也称为格林威治标准时间,格林威治位于本初子午线上。
- CST(Central Standard Time)中央标准时间:CST可视为美国、澳大利亚、古巴或中国的标准时间。
Java中的时间是从 1970 年 1 月 1 日 00:00:00 开始计算。
Java8之前的日期API java.util.Date
java.util.Date类是JDK1.0引入的,表示特定的瞬间(时间戳),精确到毫秒。比如2022年01月01日 00:00:00就是一个瞬间,而用Date表示,就是从1970 年 1 月 1 日 00:00:00 到该时间所经历的毫秒数。
Date类常用的构造器有两个:
- Date():获取本地当前时间创建对象。
- Date(long date):使用给定的时间值构建对象。
常用方法:
- getTime():返回自 1970 年 1 月 1 日 00:00:00 GMT 以来此 Date 对象表示的毫秒数。
- toString():把此 Date 对象转换为以下形式的 String: dow mon dd hh:mm:ss zzz yyyy 其中: dow 是一周中的某一天 (Sun, Mon, Tue, Wed, Thu, Fri, Sat),zzz是时间标准。
Date类使用的简单演示:
@Test
public void test() {
Date date = new Date();
System.out.println(date);
System.out.println(date.getTime()); // 获取当前对象的时间戳
Date date1 = new Date(1651472939950L);
System.out.println(date1);
}
当然Date类中还有许多其他方法,比如获取当前对象代表的秒数,小时数,分钟数等等,不过这些方法大多都过时了,由 java.util.Calendar中的方法代替。还有一些与新的日期类转换的方法,就不在这里介绍了。
java.util.Calendar(日历)类
java.util.Date类代表一个时间戳。如果想要知道某个时间点所处的位置,比如该时间是星期几,一个月中的第几天,一年中的第几天等等,就必须使用日历类了。
Calendar是JDK1.1引入的,是一个抽象基类,主要用于完成日期字段之间相互 *** 作的功能。
获取Calendar实例的方法
- 使用Calendar.getInstance()方法。(基本都用这个方法)
- 调用它的子类GregorianCalendar的构造器。
Calendar中定义了一些常量(日期字段)供我们使用,比如:
YEAR:代表年份
MONTH:代表月份
MINUTE:代表分钟
SECOND:代表秒
DAY_OF_WEEK:代表一周中天数,也就是星期几。
HOUR_OF_DAY :代表一天中的小时数,也就是几点。
DAY_OF_WEEK_IN_MONTH:代表处于一个月的第几周。
注意:
- 获取月份时:一月是0,二月是1,以此类推,12月是11
- 获取星期时:周日是1,周二是2 , 。。。。周六是7
Calendar类提供了对日期字段 *** 作的方法,获取、设置、对日期进行加减 *** 作等。
常用方法:
- public void set(int field,int value):对日历对象进行修改
- public int get(int field):获取日历对象的属性
- public void add(int field,int amount):对日历对象的属性进行修改
- public final Date getTime():获取日历中Date对象
- public final void setTime(Date date):通过Date对象修改日历
- public boolean after(Object when):当前日历对象是否在when之后,当然这个when必须是Calendar的实例
- public boolean before(Object when):当前日历对象是否在when之前
- public int compareTo(Calendar anotherCalendar):比较日历对象的先后
Calendar类使用的简单演示:
@Test
public void test() {
// 初始化,获取当前本地时间的日历对象
Calendar calender = Calendar.getInstance();
//Calendar gregorianCalendar = new GregorianCalendar();
// 获取部分时间 比如几号,星期几
int dayofweek = calender.get(Calendar.DAY_OF_WEEK);
int dayofmonth = calender.get(Calendar.DAY_OF_MONTH);
int dayofweekinmonth = calender.get(Calendar.DAY_OF_WEEK_IN_MONTH);
System.out.println(dayofweek);
System.out.println(dayofmonth);
System.out.println(dayofweekinmonth);
// set
calender.set(Calendar.DAY_OF_MONTH, 22); //设置为当月的第21天
System.out.println(calender.get(Calendar.DAY_OF_MONTH));
calender.add(Calendar.DAY_OF_MONTH, 2); //往后推2天
System.out.println(calender.get(Calendar.DAY_OF_MONTH));
calender.add(Calendar.DAY_OF_MONTH,-2); // 往前推两天
System.out.println(calender.get(Calendar.DAY_OF_MONTH));
// Date <--> Calendar
Date time = calender.getTime();
System.out.println(time);
Date date = new Date();
calender.setTime(date);
System.out.println(calender.getTime());
//比较日期的先后
Calendar calendar1 = Calendar.getInstance();
System.out.println(calendar1.before(calender));
System.out.println(calendar1.after(calender));
System.out.println(calendar1.compareTo(calender));
}
java.text.SimpleDateFormat
Java虽然提供了日期相关的 *** 作,但是想要创建任意时间的日期对象却并不方便(难道还要去算毫秒数?),而且Date类的API不易于国际化,大部分被废弃了。比如我们常见的是这种格式:2000-01-01 00:00:00,而Date类打印的是这种格式:Mon May 02 15:49:33 CST 2022。对于使用不同时间格式的地区来说很不舒服。
所以,提供日期格式转换功能的类java.text.SimpleDateFormat出现了。java.text.SimpleDateFormat类是一个不与语言环境有关的方式来格式化和解析日期的具体类。它允许进行格式化:日期->文本、解析:文本->日期
格式化相关方法:
- SimpleDateFormat() :默认的模式和语言环境创建对象
- public SimpleDateFormat(String pattern):该构造方法可以用参数pattern指定的格式创建一个对象
- public String format(Date date):格式化时间对象date
解析相关方法:
public Date parse(String source):从给定字符串的开始解析文本,以生成一个日期。
对于日期格式的转换,并不是随意构造,而有一套规范:
日期转换的基本 *** 作:
package com.chunni.date;
import org.junit.Test;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
public class SimpleDateFormatTest {
@Test
public void test() {
// 产生一个Date实例
Date date = new Date();
// 产生一个format格式化的实例
SimpleDateFormat format = new SimpleDateFormat();
// 打印输出默认的格式
System.out.println(format.format(date));
// 指定一个格式
SimpleDateFormat format1 = new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss");
System.out.println(format1.format(date));
try {
// 实例化一个指定的格式对象
Date date2 = format1.parse("2022年01月01日 08:08:08");
// 将指定的日期解析后格式化按指定的格式输出
System.out.println(date2.toString());
} catch (ParseException e) {
e.printStackTrace();
}
}
}
Java8中的日期API
老API中存在的问题:
- 可变性:像日期和时间这样的类应该是不可变的。
- 偏移性:Calendar中月份从0开始,星期从周日(1)开始计算
- 格式化:格式化只对Date有用,Calendar则不行。
- 线程安全:SimpleDateFormat是非线程安全的,每个线程都需要维护一份。
Java8新推出的日期API:
新引入的日期API线程安全且不可变,月份从1开始,星期从星期一开始,且格式转换支持多种类型。
LocalDate、LocalTime、LocalDateTime 类是其中较重要的几个类,它们的实例是不可变的对象,分别表示使用 ISO-8601日历系统的日期、时间、日期和时间。它们提供了简单的本地日期或时间,并不包含当前的时间信息,也不包含与时区相关的信息。可以提供日期相关的 *** 作,对应之前的Calendar类。
- LocalDate代表IOS格式(yyyy-MM-dd)的日期,可以存储 生日、纪念日等日期。
- LocalTime表示一个时间,而不是日期。
- LocalDateTime是用来表示日期和时间的,这是一个最常用的类之一。
(ISO-8601日历系统是国际标准化组织制定的现代公民的日期和时间的表示法,也就是公历。)
常用方法:
方法 | 描述 |
---|---|
now() / * now(ZoneId zone) | 静态方法,根据当前时间创建对象/指定时区的对象 |
of() | 静态方法,根据指定日期/时间创建对象 |
getDayOfMonth()/getDayOfYear() | 获得月份天数(1-31) /获得年份天数(1-366) |
getDayOfWeek() | 获得星期几(返回一个 DayOfWeek 枚举值) |
getMonth() | 获得月份, 返回一个 Month 枚举值 |
getMonthValue() / getYear() | 获得月份(1-12) /获得年份 |
getHour()/getMinute()/getSecond() | 获得当前对象对应的小时、分钟、秒 |
withDayOfMonth()/withDayOfYear()/withMonth()/withYear() | 将月份天数、年份天数、月份、年份修改为指定的值并返回新的对象 |
plusDays(), plusWeeks(), plusMonths(), plusYears(),plusHours() | 向当前对象添加几天、几周、几个月、几年、几小时 |
minusMonths()/minusWeeks()/minusDays()/minusYears()/minusHours() | 从当前对象减去几月、几周、几天、几年、几小时 |
当然还有日期比较相关的方法…
新API中月份从1开始,星期从周一开始,符合我们常规的计量方式。
基本使用演示:
@Test
public void testLocaleDate() {
// 获取当前时间创建对象
LocalDate localDate = LocalDate.now();
LocalTime localTime = LocalTime.now();
LocalDateTime localDateTime = LocalDateTime.now();
System.out.println(localDate);
System.out.println(localTime);
System.out.println(localDateTime);
System.out.println(localDateTime.getDayOfMonth());
System.out.println(localDateTime.getDayOfWeek().getValue());
System.out.println(localDateTime.getDayOfYear());
// 根据指定时间创建对象
LocalDateTime localDateTime1 = LocalDateTime.of(2022, 4, 10, 12, 0, 0,0);
System.out.println(localDateTime1);
// localDate不会改变,体现了不可变性
// 设置相关属性,直接使用withxx方法
LocalDate localDate1 = localDate.withDayOfMonth(3);
System.out.println(localDate1);
System.out.println(localDate);
// 日期加减 *** 作
LocalDateTime localDateTime2 = localDateTime.plusDays(3);
System.out.println(localDateTime2);
LocalDateTime localDateTime3 = localDateTime.minusDays(3);
System.out.println(localDateTime3);
System.out.println(localDateTime.isAfter(localDateTime1));
}
java.time.Instant
Instant:时间线上的一个瞬时点。 这可能被用来记录应用程序中的事件时间戳。相当于老API中的Date。
Instant表示时间线上的一点,而不需要任何上下文信息,例如,时区。概念上讲,它只是简单的表示自1970年1月1日0时0分0秒(UTC)开始的秒数。因为java.time包是基于纳秒计算的,所以Instant的精度可以达到纳秒级。
常用方法:
方法 | 描述 |
---|---|
now() | 静态方法,返回默认UTC时区的Instant类的对象 |
ofEpochMilli(long epochMilli) | 静态方法,返回在1970-01-01 00:00:00基础上加上指定毫秒数之后的Instant类的对象 |
atOffset(ZoneOffset offset) | 结合即时的偏移来创建一个 OffsetDateTime |
toEpochMilli() | 返回1970-01-01 00:00:00到当前时间的毫秒数,即为时间戳 |
equals(Object otherInstant) | 判断是否相等 |
Instant类中也存在进行加减、比较的方法…
基本使用演示:
@Test
public void test01() {
// 获取当前时间创建对象
Instant instant = Instant.now();
System.out.println(instant); // 加8小时才是北京时间
// 添加偏移量
OffsetDateTime offsetDateTime = instant.atOffset(ZoneOffset.ofHours(8));
System.out.println(offsetDateTime); //
// 获取对应毫秒数 自1970-01-01T00:00:00Z.
long l = instant.toEpochMilli();//
System.out.println(l);
// 通过Long型的时间获取时间对象
Instant instant1 = Instant.ofEpochMilli(1650977606932L);
Instant instant2 = Instant.ofEpochSecond(1650977606L);
System.out.println(instant1);
System.out.println(instant2);
// 判断时间戳是否相等
System.out.println(instant1.equals(instant2));
}
java.time.format.DateTimeFormatter
DateTimeFormatter用于格式化和解析日期时间对象。对应老API中的SimpleDateFormat。
DateTimeFormatter提供了三种初始化方式:
- DateTimeFormatter预定义的标准格式。如:ISO_LOCAL_DATE_TIME;ISO_LOCAL_DATE;ISO_LOCAL_TIME
- 本地化相关的格式。如:ofLocalizedDateTime(FormatStyle.LONG)
- 自定义的格式。如:ofPattern(“yyyy-MM-dd hh:mm:ss”),当然,自定义是用的最多的。
格式转换相关方法:
- ofPattern(String pattern) :静态方法 , 返 回 一 个 指 定 字 符 串 格 式 的DateTimeFormatter
- format(TemporalAccessor t):格式化一个日期、时间,返回字符串
- parse(CharSequence text) :将指定格式的字符序列解析为一个日期、时间
日期转换基本演示:
@Test
public void test01() {
// 初始化方式主要三种:
//预定义的标准格式。如:
//ISO_LOCAL_DATE_TIME;ISO_LOCAL_DATE;ISO_LOCAL_TIME
DateTimeFormatter formatter = DateTimeFormatter.ISO_LOCAL_DATE_TIME;
LocalDateTime now = LocalDateTime.now();
System.out.println(now);
// 格式化
String dateStr = formatter.format(now);
System.out.println(dateStr);
// 解析
TemporalAccessor date = formatter.parse("2022-04-26T21:05:35.224");
System.out.println(date);
//本地化相关的格式。如:ofLocalizedDateTime(FormatStyle.LONG)
DateTimeFormatter formatter1 = DateTimeFormatter.ofLocalizedDateTime(FormatStyle.SHORT); // 22-4-26 下午9:13
DateTimeFormatter formatter2 = DateTimeFormatter.ofLocalizedDateTime(FormatStyle.LONG); // 2022年4月26日 下午09时13分02秒
DateTimeFormatter formatter3 = DateTimeFormatter.ofLocalizedDateTime(FormatStyle.MEDIUM);// 2022-4-26 21:13:02
//DateTimeFormatter formatter4 = DateTimeFormatter.ofLocalizedDateTime(FormatStyle.FULL);// 不支持localDateTime
System.out.println(formatter1.format(now));
System.out.println(formatter2.format(now));
System.out.println(formatter3.format(now));
LocalDate date1 = LocalDate.now();
DateTimeFormatter formatter5 = DateTimeFormatter.ofLocalizedDate(FormatStyle.FULL); // 2022年4月26日 星期二
DateTimeFormatter formatter6 = DateTimeFormatter.ofLocalizedDate(FormatStyle.LONG); // 2022年4月26日
DateTimeFormatter formatter7 = DateTimeFormatter.ofLocalizedDate(FormatStyle.MEDIUM); // 2022-4-26
DateTimeFormatter formatter8 = DateTimeFormatter.ofLocalizedDate(FormatStyle.SHORT); // 22-4-26
System.out.println(formatter5.format(date1));
System.out.println(formatter6.format(date1));
System.out.println(formatter7.format(date1));
System.out.println(formatter8.format(date1));
//自定义的格式。如:ofPattern(“yyyy-MM-dd HH:mm:ss”) 用的最多,随心所欲
DateTimeFormatter formatter9 = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"); // 2022-04-26 21:22:10
DateTimeFormatter formatter10 = DateTimeFormatter.ofPattern("yyyy-MM-dd"); // 2022-04-26
DateTimeFormatter formatter11 = DateTimeFormatter.ofPattern("HH:mm:ss"); // 21:22:10
System.out.println(formatter9.format(now));
System.out.println(formatter10.format(now));
System.out.println(formatter11.format(now));
TemporalAccessor parse1 = formatter9.parse("2022-04-26 21:22:10");
System.out.println(parse1);
}
其他API的简单介绍
关于其他的API就简单说明下功能,具体细节可以查看API文档。
java.time.ZoneId :该类中包含了所有的时区信息,一个时区的ID,如 Europe/Paris
java.time.ZonedDateTime :一个在ISO-8601日历系统时区的日期时间,如 2007-12-03T10:15:30+01:00 Europe/Paris。其中每个时区都对应着ID,地区ID都为“{区域}/{城市}”的格式,例如:Asia/Shanghai等
java.time.Clock :使用时区提供对当前即时、日期和时间的访问的时钟。
java.time.Duration :持续时间,用于计算两个“时间”间隔
java.time.Period :用于计算两个“日期”间隔
java.time.temporal.TemporalAdjuster : 时间校正器。有时我们可能需要获取例如:将日期调整到“下一个工作日”等 *** 作。
java.time.temporal.TemporalAdjusters :该类通过静态方法(firstDayOfXxx()/lastDayOfXxx()/nextXxx())提供了大量的常用TemporalAdjuster 的实现。
类 | 新转旧 | 旧转新 |
---|---|---|
java.time.Instant与java.util.Date | Date.from(instant) | date.toInstant() |
java.time.Instant与java.sql.Timestamp | Timestamp.from(instant) | timestamp.toInstant() |
java.time.ZonedDateTime与java.util.GregorianCalendar | GregorianCalendar.from(zonedDateTime) | cal.toZonedDateTime() |
java.time.LocalDate与java.sql.Time | Date.valueOf(localDate) | date.toLocalDate() |
java.time.LocalTime与java.sql.Time | Date.valueOf(localTime) | time.toLocalTime() |
java.time.LocalDateTime与java.sql.Timestamp | Timestamp.valueOf(localDateTime) | timestamp.toLocalDateTime() |
java.time.ZoneId与java.util.TimeZone | Timezone.getTimeZone(id) | timeZone.toZoneId() |
java.time.format.DateTimeFormatter与java.text.DateFormat | formatter.toFormat() | 无 |
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)