1. Java时间戳
在最早出现的 UNIX 操作系统考虑到计算机产生的年代和应用的时限,把1970年1月1日0点定义为时间纪元,这种定义时间的方式在计算机语言中广泛存在,Java就是其中之一。之所以使用Long数据类型来表示时间是因为Long类型可以表示足够大的数,进而可以表示未来更多的时间。
2. Java中日期时间的使用
主要涉及一下几个类:
java.util.Date
java.text.DateFormat
java.text.SimpleDateFormat
java.util.Calendar
java.util.GregorianCalendar
下面是对上述几个类逐个介绍:
2.1 java.util.Date
先看Java jdk文档的描述:
The class Date represents a specific instant in time, with millisecond precision.
意思是说Data类表示一个特定的时间瞬间,精确到毫秒。并且从 JDK 1.1 起,废弃了把日期转换为年、月、日、小时、分钟和秒值的方法,应该使用 Calendar 类实现日期和时间各字段之间的转换,使用 DateFormat 类来格式化和分析日期字符串。其实Date里的好多方法现在都已经被废弃。
例子:
public class DateDemo {
public static void main(String[] args) {
Date date = new Date();
String current = date.toString();
System.out.println("当前时间是:"+current);
long millisecond = date.getTime();
System.out.println("自格林威治时间(1970年1月1日0时0分0秒)起到现在的所经过的毫秒数:"+millisecond);
//setTime(long time)方法设置自日期1970年1月1日00:00:00 GMT后,来显示时间的毫秒。
date.setTime(1234567890);
System.out.println("设置后的时间为:"+date.toString());
//比较一个时间是否在另一个时间之前
Date date1 = new Date();
date1.setTime(12345);
Date date2 = new Date();
date2.setTime(1234);
System.out.println("date1 在 date2 之前:"+date1.before(date2));
System.out.println("date1 在 date2 之后:"+date1.after(date2));
}
}
2.2 java.text.DateFormat
先看一下继承体系:
DateFormat是个抽象类,我们使用的其实是的直接子类SimpleDateFormat。
DateFormat 是日期/时间格式化子类的抽象类,它以与语言无关的方式格式化并解析日期或时间。日期/时间格式化子类(如 SimpleDateFormat)允许进行格式化(也就是日期 -> 文本)、解析(文本-> 日期)和标准化。将日期表示为 Date 对象,或者表示为从 GMT(格林尼治标准时间)1970 年 1 月 1 日 00:00:00 这一刻开始的毫秒数。
(1) DateFormat 提供了很多类方法,以获得基于默认或给定语言环境和多种格式化风格的默认日期/时间 Formatter。格式化风格包括 FULL、LONG、MEDIUM 和 SHORT。方法描述中提供了使用这些风格的更多细节和示例。
(2) DateFormat 可帮助进行格式化并解析任何语言环境的日期。对于月、星期,甚至日历格式(阴历和阳历),其代码可完全与语言环境的约定无关。
要格式化一个当前语言环境下的日期,可使用某个静态工厂方法:如
myString = DateFormat.getDateInstance().format(myDate);
(3) 如果格式化多个日期,那么获取该格式并多次使用它是更为高效的做法,这样系统就不必多次获取有关环境语言和国家/地区约定的信息了。
DateFormat df = DateFormat.getDateInstance();
for (int i = 0; i < myDate.length; ++i) {
output.println(df.format(myDate[i]) + "; ");
}
(4)要格式化不同语言环境的日期,可在 getDateInstance() 的调用中指定它,如:
DateFormat df = DateFormat.getDateInstance(DateFormat.LONG, Locale.FRANCE);
还可使用 DateFormat 进行解析。
myDate = df.parse(myString);
(5) 使用 getDateInstance 来获取该国家/地区的标准日期格式。另外还提供了一些其他静态工厂方法。使用 getTimeInstance 可获取该国家/地区的时间格式。使用 getDateTimeInstance 可获取日期和时间格式。可以将不同选项传入这些工厂方法,以控制结果的长度(从 SHORT 到 MEDIUM 到 LONG 再到 FULL)。确切的结果取决于语言环境,但是通常:
SHORT 完全为数字,如 12.13.52 或 3:30pm
MEDIUM 较长,如 Jan 12, 1952
LONG 更长,如 January 12, 1952 或 3:30:32pm
FULL 是完全指定,如 Tuesday、April 12、1952 AD 或 3:30:42pm PST。
如果愿意,还可以在格式上设置时区。如果想对格式化或解析施加更多的控制(或者给予用户更多的控制),可以尝试将从工厂方法所获取的 DateFormat 强制转换为 SimpleDateFormat。这适用于大多数国家/地区;只是要记住将其放入一个 try 代码块中,以防遇到特殊的格式。
还可以使用借助 ParsePosition 和 FieldPosition 的解析和格式化方法形式来逐步地解析字符串的各部分。
对齐任意特定的字段,或者找出字符串在屏幕上的选择位置。
同步
日期格式不是同步的。建议为每个线程创建独立的格式实例。如果多个线程同时访问一个格式,则它必须保持外部同步。
例子:
public static void dateFormatTest(){
Date date = new Date();
DateFormat fullFormat = DateFormat.getDateTimeInstance(DateFormat.FULL, DateFormat.FULL);
DateFormat longFormat = DateFormat.getDateTimeInstance(DateFormat.LONG, DateFormat.LONG);
DateFormat mediumFormat = DateFormat.getDateTimeInstance(DateFormat.MEDIUM, DateFormat.MEDIUM);
DateFormat shortFormat = DateFormat.getDateTimeInstance(DateFormat.SHORT, DateFormat.SHORT);
System.out.println("DateFormat.FULL = "+fullFormat.format(date));
System.out.println("DateFormat.LONG = "+longFormat.format(date));
System.out.println("DateFormat.MEDIUM = "+mediumFormat.format(date));
System.out.println("DateFormat.SHORT = "+shortFormat.format(date));
DateFormat dateFormat = DateFormat.getDateInstance();
String myString = dateFormat.format(new Date());
System.out.println("myString = "+myString);
DateFormat dateFormat1 = DateFormat.getDateInstance(DateFormat.DATE_FIELD);
System.out.println("DateFormat.DATE_FIELD = "+dateFormat1.format(date));
}
2.3 java.text.SimpleDateFormat的使用
SimpleDateFormat 是一个以与语言环境有关的方式来格式化和解析日期的具体类。它允许进行格式化(日期 -> 文本)、解析(文本 -> 日期)和规范化。
SimpleDateFormat 使得可以选择任何用户定义的日期-时间格式的模式。但是,仍然建议通过 DateFormat 中的 getTimeInstance、getDateInstance 或 getDateTimeInstance 来创建日期-时间格式器。每一个这样的类方法都能够返回一个以默认格式模式初始化的日期/时间格式器。可以根据需要使用 applyPattern 方法来修改格式模式。
日期和时间模式
日期和时间格式由日期和时间模式 字符串指定。在日期和时间模式字符串中,未加引号的字母 ‘A’ 到 ‘Z’ 和 ‘a’ 到 ‘z’ 被解释为模式字母,用来表示日期或时间字符串元素。文本可以使用单引号 (‘) 引起来,以免进行解释。””” 表示单引号。所有其他字符均不解释;只是在格式化时将它们简单复制到输出字符串,或者在解析时与输入字符串进行匹配。
定义了以下模式字母(所有其他字符 ‘A’ 到 ‘Z’ 和 ‘a’ 到 ‘z’ 都被保留):
来上个例子吧
public static void simpleDateFormatTest(){
SimpleDateFormat simpleDateFormat1 =new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
SimpleDateFormat simpleDateFormat2 =new SimpleDateFormat("yyyy年MM月dd日 HH时mm分ss秒");
SimpleDateFormat simpleDateFormat3 =new SimpleDateFormat("这个一天中的第 H 个小时");
SimpleDateFormat simpleDateFormat4 =new SimpleDateFormat("这是一年中的第 D 天");
SimpleDateFormat simpleDateFormat5 =new SimpleDateFormat("这是 z 时区");
SimpleDateFormat simpleDateFormat6 =new SimpleDateFormat("这是一年中的第 M 个星期");
Date date =new Date();
System.out.println(date.toString());
System.out.println(simpleDateFormat1.format(date));
System.out.println(simpleDateFormat2.format(date));
System.out.println(simpleDateFormat3.format(date));
System.out.println(simpleDateFormat4.format(date));
System.out.println(simpleDateFormat5.format(date));
System.out.println(simpleDateFormat6.format(date));
}
2.4 java.util.Calendar
继承图:
Calendar 类是一个抽象类,它为特定瞬间与一组日历字段(诸如YEAR、MONTH、DAY_OF_MONTH、HOUR等)之间的转换提供了一些方法,并为操作日历字段(例如获得下星期的日期)提供了一些方法。瞬间可用毫秒值来表示,它是距历元(即格林威治标准时间 1970年1月1日的00:00:00.000,格里高利历)的偏移量。
自从JDK1.1版本开始,系统推荐使用Calendar类进日期和时间的处理。
java.util.calendar 类是一个抽象类,它提供了与在某一特定时刻和一组日历字段如YEAR,MONTH,DAY_OF_MONTH,HOUR等,并为操作日历字段。
public static void calendarTest(){
Calendar c1 = Calendar.getInstance();
c1.set(2016, 11 - 1, 11);
System.out.println("上述设置的时间为:" + c1.getTime());
Calendar c2 = Calendar.getInstance();
int year = c2.get(Calendar.YEAR);
int month = c2.get(Calendar.MONTH) + 1;
int date = c2.get(Calendar.DATE);
int day = c2.get(Calendar.DAY_OF_WEEK);
int hour = c2.get(Calendar.HOUR_OF_DAY);
int minute = c2.get(Calendar.MINUTE);
int second = c2.get(Calendar.SECOND);
System.out.println("当前年份:" + year);
System.out.println("当前月份:" + month);
System.out.println("当前日期:" + date);
System.out.println("当前星期:" + day);
System.out.println("当前小时:" + hour);
System.out.println("当前分钟:" + minute);
System.out.println("当前秒:" + second);
}
2.5 java.util.GregorianCalendar
GregorianCalendar继承自Calendar,扩展了一个更加通用的Calendar类,用来表示标准的日历,这个类描述了日历的一般属性,提供了世界上大多数国家和地区使用的标准日历。
来个例子吧:
public static void gregorianCalendarTest(){
GregorianCalendar gregorianCalendar1 = new GregorianCalendar();
int today = gregorianCalendar1.get(Calendar.DAY_OF_MONTH);
int month = gregorianCalendar1.get(Calendar.MONTH);
int weekday = gregorianCalendar1.get(Calendar.DAY_OF_WEEK);
int firstDayOfWeek = gregorianCalendar1.getFirstDayOfWeek();
System.out.println("------------------------------------------");
System.out.println("当前时间为:"+gregorianCalendar1.getTime());
System.out.println("today = " + today);
System.out.println("month = " + month+1);// month是从0开始,
System.out.println("weekday = " + weekday);
System.out.println("每周第一天从"+firstDayOfWeek+"开始");
//设置日期
GregorianCalendar gregorianCalendar2 = new GregorianCalendar();
//calendar.set()设置日期
// month是从0开始,
gregorianCalendar2.set(2015, 11, 12, 10, 21, 20);
System.out.println("------------------------------------------");
System.out.println("设置的时间为:" + gregorianCalendar2.getTime());
//日期类转化成时间类
Calendar gregorianCalendar3 = new GregorianCalendar();
System.out.println("------------------------------------------");
System.out.println("当前时间为:"+gregorianCalendar3.getTime());
//年份减去2年
gregorianCalendar3.add(Calendar.YEAR, -2);
//月份减去2年
gregorianCalendar3.add(Calendar.MONTH, -2);
//日期减去两天
gregorianCalendar3.add(Calendar.DATE, -2);
System.out.println("修改过的时间为:"+gregorianCalendar3.getTime());
}
笔者水平有限,如有错误,欢迎指正,谢谢!