7.5 Jdk7及以前的日期时间类
java 8 之前的日期时间类,先天设计不足,所以java8以前一般使用joda-time,java8 汲取了joda的设计方式,新增了java.time包来处理日期时间。
计算机中的时间是整数表示的一个时刻(从1970年1日 即纪元时 到现在的时间)。时刻是一个绝对时间,对时刻的解读则是相对的于时区、年历相关。
Java8之前的日期类介绍:
7.5.2.1 Date 表示时刻。内部主要是一个long值存储距离纪元时的毫秒数。绝大多数方法都是过时的。
public class Date{
private transient long fastTime;
Date(){
this(System.currentTimeMillis());
}
Date(long date){
fastTime = date;
}
//……
}
7.5.2.2 TimeZone 时区(24个,如Asia/shanghai)
//获取模式时区
TimeZone.getDefault();
7.5.2.3 Locale 国家(或地区)和语言(如zh_CN)
Locale.getDefault();
7.5.2.4 Calendar 是日期和时间操作的主要类,是抽象类,提供了多个静态方法,可以获取Calendar实例。
与Date类似,Calendar内部也有一个表示时刻的毫秒数,还定义了一个数组(长度17),表示日历中各个字段的值。
proteted long time;
proteted int fields[];
fields中存放的是下面这些字段的值,给Calendar
Calendar.YEAR,
Calendar.MONTH,
Calendar.DAY_OF_MONTH,
Calendar.DAY_OF_WEEK,
Calendar.HOUR_OF_DAY,
Calendar.MINUTE,
Calendar.SECOND,
Calendar.MILLISECOND
可以通过Calendar实例获取这些值(Calendar会根据时区,地区语言进行转换)。
//空构造函数,会获取当前的。 Calendar.getInstance("Asia/shanghai","zh_CN")
Calendar calendar = Calendar.getInstance();
int day = calendar.get(Calendar.DAY_OF_MONTH);
Calendar还支持根据字段增加减少时间(负数表示减少)。
Calendar.getInstance().add(Calendar.MONTH,-2);
总结来说,Calendar做了一项非常繁琐的工作,根据TimeZone 和 Locale 再绝对时间毫秒数和日历字段之间自动进行转换。
7.5.2.5 DateFormat(线程不安全) 提供Date和字符串表示之间的转换,主要的两个方法 format(Date d),parse(String s)
- Date的字符串表示与TimeZone、Locale都是相关的。
- 同时与两个格式化风格相关,一个是日期格式化风格,一个是时间格式化风格。
DataFormat是抽象方法,也用工厂方法创建对象。
DateFormat.getTimeInstance();
DateFormat.getDateInstance();
DateFormat.getDateTimeInstance();
其中getTimeInstance只处理时间,getDateInstance只处理日期,getDateTimeInstance处理日期和时间,三种对象的处理结果如下
Calendar calendar = Calendar.getInstance();
//结果是21:34:20
DateFormat.getTimeInstance().format(calendar.getTime());
//结果是2019-02-20
DateFormat.getDateInstance().format(calendar.getTime());
//结果是2019-02-20 21:34:20
DateFormat.getDateTimeInstance().format(calendar.getTime());
DateFormat虽然比较方便,但是日期字符串格式的更精确的控制,则应该使用SimpleDateFormat。
7.5.2.6 SimpleDateFormat(线程不安全) 是DateFormat的子类,与父类主要不同是:子类可以自定义日期格式。
String pattern = "yyyy年MM月dd日 E HH时mm分ss秒";
SimpleDateFormat simpleDateFormat = new SimpleDateFormat(pattern);
//输出结果是 2019年02月20日 Wed 21时44分42秒
OS.print(simpleDateFormat.format(calendar.getTime()));
pattern 中的英文字符a-z,A-Z表示特殊含义,其他字符原样输出.
pattern变量参数 | 对应的实际意义 | 示例 |
---|---|---|
yyyy | 4位的年份 | 2019 |
MM | 月份两位数 | 02 |
dd | 日期 | 20 |
HH/hh | 24小时制/12小时制 | 21/09 |
mm | 分钟 | 55 |
ss | 秒 | 55 |
E | 星期几 | wed |
a | 上午下午,一般配合hh使用 | PM |
SimpleDateFormat也可以方便的将字符串转成Date。
String str = "19年2月20日 09时58分33秒111";
Date date = new SimpleDateFormat("yy年M月dd日 HH时mm分ss秒SSS").parse(str);
//结果 2019年02月20日 09时58分33秒
String result = new SimpleDateFormat("yyyy年MM月dd日 HH时mm分ss秒").format(date);
7.5.3.1 Date中的过时方法
Date中的方法一般都过时了,不建议使用,有一些歧义。
new Date(2019,01,01)
实际是3919年2月。因为Date的构造函数 的年份表示的始于1900年的差值。month是从0开始的。
7.5.3.2 Calendar操作繁琐、不支持复杂计算
Calendar设计不是很成功,一些简单操作都要多次调用。对一些复杂的计算比如两个日期之间有多少个月,生日计算年龄等都不支持。
7.5.3.3 SimpleDateFormat/DateFormat线程不安全
SimpleDateFormat/DateFormat都是线程不安全的。
网友评论