在日常开发中,对日期时间的处理是很常见的,这篇我们就来讨论一下Java的时间处理。
随着Java版本的迭代,不少类存在问题,但许多人仍在使用,这里我们就这个问题展开。
一、时间日期处理
1.java.util.Date
相信很多人对这个Date类并不陌生,日常开发中经常使用。但其实它存在着一些缺点。
缺点一:年份从1900年开始,月份从0开始,日期又由1开始。这样让我们转换起来的是十分不方便。例如我们要表达生日的时候需要:
Date date = new Date(98, 8, 12);
输出:
Sat Sep 12 00:00:00 CST 1998
缺点二:Date类是可变的,能把1998年09月12日修改成3月12日意味着什么呢?这种设计会将你拖入维护的噩梦。
2.java.util.Calendar
在Date后,java推出了Calendar。Calendar是为了取代Date而出现。但是Calendar仍存在着一些缺点。
缺点一:月份依旧是从0开始计算(不过,至少Calendar 类拿掉了由1900年开始计算年份这一设计)。
缺点二:Calendar类仍是可变的,使用起来不安全。
缺点三:同时存在Date和Calendar这两个类,容易使程序员产生困惑。到底该使用哪一个类呢?此外,有的特性只在某一个类有提供,比如用 于以语言无关方式格式化和解析日期或时间的DateFormat方法就只在Date类里有。
看来我们一直使用的类已经存在着大多数人不知道或不为意的缺点。随着Java的迭代,Java8推出了新的类
3. java.time.LocalDate和java.time.LocalTime
LocalDate
类的实例是一个不可变对象,它只提供了简单的日期,并不含当天的时间信息。另外,它也不附带任何与时区相关的信息。
LocalTime
用来表示一天中的时间,比如13:45:20。
LocalDate和LocalTime的使用
//1.1 通过of重载的工厂方法创建
LocalDate ld = LocalDate.of(1998, 9, 12); //1998-09-12
LocalTime lt = LocalTime.of(13, 45, 20); // 13:45:20
//1.2 使用静态方法parse来创建
LocalDate parseDate = LocalDate.parse("1998-09-12"); //1998-09-12
LocalTime parseTime = LocalTime.parse("13:45:20"); // 13:45:20
//2. 读取LocalDate和LocalTime常用值的两种方式
//2.1 LocalDate 和 LocalTime 类提供了多种方法来 读取常用的值,比如年份、月份、星期几等
int hour = lt.getHour(); // 13
int minute = lt.getMinute(); // 45
int second = lt.getSecond(); // 20
int year = ld.getYear(); // 1998-09-12
Month month = ld.getMonth(); // Sep
int day = ld.getDayOfMonth(); // 12
DayOfWeek dow = ld.getDayOfWeek(); // Sat
int len = ld.lengthOfMonth(); // 31 (days in March)
boolean leap = ld.isLeapYear(); // false (判断是否为为闰年)
// 2.1 通过传递一个TemporalField参数给get方法拿到同样的信息。
int y = ld.get(ChronoField.YEAR); // 1998
int m = ld.get(ChronoField.MONTH_OF_YEAR); // 9
int d = ld.get(ChronoField.DAY_OF_MONTH); // 12
int dow2 = ld.get(ChronoField.DAY_OF_WEEK); // 6
int hour2 = lt.get(ChronoField.HOUR_OF_DAY); // 13
int minute2 = lt.get(ChronoField.MINUTE_OF_HOUR); // 45
int second2 = lt.get(ChronoField.SECOND_OF_MINUTE);// 20
4.java.time.LocalDateTime
虽然LocalDate和LocalTime在名字上就很容易区分,但还是存在不便利。因此还有一个类LocalDateTime,是LocalDate和LocalTime的合体。
//3. 创建LocalDateTime的两种方式
//3.1 通过重载的of工厂方法创建
LocalDateTime ldt1= LocalDateTime.of(1998, Month.SEPTEMBER, 12, 13, 45, 20);
LocalDateTime ldt2 = LocalDateTime.of(ld, lt);
//3.2 通过合并日期和时间的方式创建
LocalDateTime ldt3 = ofDate.atTime(13, 45, 20);
LocalDateTime ldt4 = ofDate.atTime(ofTime);
LocalDateTime ldt5 = ofTime.atDate(ofDate);
//4. 从LocalDateTime中提取LocalDate或者LocalTime 组件
LocalDate ld1 = ldt1.toLocalDate(); //1998-09-12
LocalTime lt1 = ldt1.toLocalTime(); //13:45:20
二、格式化日期
1.java.text.DateFormat
DateFormat 是日期/时间格式化子类的抽象类,它以与语言无关的方式格式化并分析日期或时间。日期/时间格式化子类(如 SimpleDateFormat)允许进行格式化(也就是日期 -> 文本)、分析(文本-> 日期)和标准化。将日期表示为 Date 对象,或者表示为从 GMT(格林尼治标准时间)1970 年,1 月 1 日 00:00:00 这一刻开始的毫秒数。
2. java.time.format.DateTimeFormatter
java8推出了一个新的格式化类。
private static void useDateFormatter() {
LocalDate date = LocalDate.of(2014, 3, 18);
//1. 从时间生成字符串
//1.1 使用特定不同的格式器生成字符串
String s1 = date.format(DateTimeFormatter.BASIC_ISO_DATE); //19980912
String s2 = date.format(DateTimeFormatter.ISO_LOCAL_DATE); //1998-09-12
//1.2 DateTimeFormatter类还支持静态工厂方法,它可以按 照某个特定的模式创建格式器
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd/MM/yyyy");
DateTimeFormatter chinaFormatter2 = DateTimeFormatter.ofLocalizedDate(FormatStyle.FULL);
String s3 = date.format(formatter); //12/09/1998
String s4 = date.format(chinaFormatter2); //1998年9月12日 星期六
//2. 从字符串生成时间
//2.1 通过解析代表日期或时间的字符串重新创建该日期对象。
LocalDate date1 = LocalDate.parse("19980912", DateTimeFormatter.BASIC_ISO_DATE);
LocalDate date2 = LocalDate.parse("1998-09-12", DateTimeFormatter.ISO_LOCAL_DATE);
LocalDate date3 = LocalDate.parse("12/09/1998", formatter);
LocalDate date5 = LocalDate.parse("1998年9月12日 星期六", chinaFormatter2);
//3. 自定义DateTimeFormatter
DateTimeFormatter complexFormatter = new DateTimeFormatterBuilder()
.appendText(ChronoField.DAY_OF_MONTH)
.appendLiteral(".")
.appendText(ChronoField.MONTH_OF_YEAR)
.appendLiteral(" ")
.appendText(ChronoField.YEAR)
.parseCaseInsensitive()
.toFormatter(Locale.ITALIAN);
}
总结
这里主要介绍一些新的类。Java随着版本迭代,出现了很多新的东西,值得去学习。一些原始的类的方法,百度很多,这里就不赘述。