前言:本篇文章的主要目的是为了把工作中常用的关于时间上的操作统一整理一下,梳理一下他们之间的转换关系,
来方便自己和广大同胞复习和快速开发使用。
目录
- Calendar官方简介
- Calendar、Date、SimpleDateFormat 初始化部分
- Calendar、Date、时间戳转化
- Calendar和时间戳 转成 Date
- Date和时间戳 转成 Calendar
- Calendar和Date 转成 时间戳
- Calendar设置日期时间和获取日期时间
- 通过Caledar提供的方法直接设置年月日时分秒
- 通过set方法单独设置年月日等各个参数
- Calendar其他部分常用参数设置
- 从Calendar获取日期时间等参数
- Calendar、Date、SimpleDateFormat部分
- SimpleDateFormat的简单使用
- 将Calendar、Date、TimeMills(时间戳)转化为指定格式日期字符串
- 将SimpleDateFormat格式化后的日期转化成Calendar、Date对象
- 判断指定时间是否在某个时间区间内
- 判断某个日期是否在指定区间(包括区间边界)内?
Calendar官方简介
The Calendar class is an abstract class that provides methods for converting between a specific instant in time and a set of calendar fields such as YEAR, MONTH, DAY_OF_MONTH, HOUR, and so on, and for manipulating the calendar fields, such as getting the date of the next week. An instant in time can be represented by a millisecond value that is an offset from the Epoch, January 1, 1970 00:00:00.000 GMT (Gregorian).
The class also provides additional fields and methods for implementing a concrete calendar system outside the package. Those fields and methods are defined as protected.
Like other locale-sensitive classes, Calendar provides a class method, getInstance, for getting a generally useful object of this type. Calendar’s getInstance method returns a Calendar object whose calendar fields have been initialized with the current date and time:
有道翻译:Calendar类是一个抽象类,它提供了一些方法,用于在特定的时间瞬间和一组日历字段(如YEAR、MONTH、DAY_OF_MONTH、HOUR等)之间进行转换,以及操作日历字段(如获取下一周的日期)。时间上的一个瞬间可以用毫秒值来表示,这个毫秒值是从格林威治时间1970年1月1日00:00:00.000(格里高利安)开始的偏移量。
该类还提供了用于在包之外实现具体日历系统的其他字段和方法。这些字段和方法被定义为受保护的。
与其他对区域设置敏感的类一样,Calendar提供了一个类方法getInstance,用于获取这种类型的一般有用对象。Calendar的getInstance方法返回一个日历对象,该对象的日历字段已经用当前日期和时间初始化
Calendar、Date、SimpleDateFormat 初始化部分
Calendar calendar = Calendar.getInstance();
Date date = new Date();
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
Calendar和Date进行初始化后,都会获得一个默认初始时间,即系统时间(时间戳)。
对应时间转换为毫秒值等于当前时间距离 January 1, 1970 00:00:00.000 GMT之间的毫秒数。
Calendar、Date、时间戳转化
Calendar和时间戳 转成 Date
/**
* Calendar 转 Date
* */
public Date transCalendarToDate(Calendar calendar){
Date date = calendar.getTime();
return date;
}
/**
* 时间戳 转 Date
* */
public Date transMillsToDate(long timeMills) {
Date date = new Date(timeMills);
return date;
}
Date和时间戳 转成 Calendar
/**
* Date 转 Calendar
* */
public Calendar transDateToCalendar(Date date) {
Calendar calendar = Calendar.getInstance();//获取Calendar实例,默认拥有当前系统时间
calendar.setTime(date);
return calendar;
}
/**
* 通过毫秒级时间戳获得对应的Calendar对象
* @param mills An instant in time can be represented by a millisecond value that is an offset from the Epoch,
* January 1, 1970 00:00:00.000 GMT (Gregorian).
* */
public Calendar transDateToCalendar(long timeMills) {
Calendar calendar = Calendar.getInstance();//获取Calendar实例,默认拥有当前系统时间
calendar.setTimeInMillis(timeMills);
return calendar;
}
Calendar和Date 转成 时间戳
/**
* Calendar 转 时间戳
* */
public long transCalendarToTimeMills(Calendar calendar) {
long timeMills = calendar.getTimeInMillis();
return timeMills;
}
/**
* Date 转 时间戳
* */
public long transCalendarToTimeMills(Date date) {
long timeMills = date.getTime();
return timeMills;
}
Calendar设置日期时间和获取日期时间
通过Caledar提供的方法直接设置年月日时分秒
/**
* 给Calendar设置指定的年月日时分秒
* @param month
* */
public Calendar getSpecifiedCalendar(int year, int month, int date, int hourOfDay, int minute, int second){
Calendar calendar = Calendar.getInstance();
//三种重载方法可以直接设置
calendar.set(year, month, date);
calendar.set(year, month, date, hourOfDay, minute);
calendar.set(year, month, date, hourOfDay, minute, second);
return calendar;
}
通过set方法单独设置年月日等各个参数
/**
* 给Calendar设置指定的年月日时分秒,可以分别单独设置
* */
public Calendar getSpecifiedCalendar1(int year, int month, int date, int hourOfDay, int minute, int second){
Calendar calendar = Calendar.getInstance();
//可以单独设置某一个
calendar.set(Calendar.YEAR, year);
calendar.set(Calendar.MONTH,month);
calendar.set(Calendar.DAY_OF_MONTH,date);
calendar.set(Calendar.HOUR_OF_DAY, hourOfDay);//24小时制的时间
calendar.set(Calendar.MINUTE, minute);
calendar.set(Calendar.SECOND, second);
return calendar;
}
Calendar其他部分常用参数设置
Calendar calendar = Calendar.getInstance();
calendar.set(Calendar.AM_PM,Calendar.AM);
calendar.set(Calendar.HOUR,9);//12-hour clock (0 - 11). Noon and midnight are represented by 0, not by 12.
calendar.set(Calendar.DAY_OF_WEEK,1);//星期几 1星期日 2星期一
calendar.set(Calendar.DAY_OF_MONTH, 20);//月份中的第几天 The first day of the month has value 1.
calendar.set(Calendar.DAY_OF_YEAR, 200);//设置一年中的第几天
calendar.set(Calendar.WEEK_OF_MONTH, 2);
calendar.set(Calendar.WEEK_OF_YEAR, 2);
从Calendar获取日期时间等参数
上方所有调用Calendar对应的set方法里面对应的字段(比如Calendar.YEAR)均可以通过Calendar对象调用get方法从Calendar对象中获取,还有几个字段没有列出,如有需要可以去看官方文档或者源码。
例如:
int year = calendar.get(Calendar.YEAR);
Calendar、Date、SimpleDateFormat部分
SimpleDateFormat的简单使用
先看一个简单使用的例子
String FORMAT_DATE = "yyyy-MM-dd HH:mm:ss";
SimpleDateFormat simpleDateFormat = new SimpleDateFormat(FORMAT_DATE);
Date date = calendar.getTime();
String formatStr = simpleDateFormat.format(date);
输出的结果格式为 1996-05-17 12:26:15
SimpleDateFormat可以将指定的Date对象转化成格式化的日期,例如1996年5月17日或者1996-05-17等。
使用起来也很简单,只需要一个装载对应日期时间的Date对象和一个约定好写法的格式字符串。
Date对象的创建以及把指定时间转换成Date对象的方法上面都已经写到了。下面就说一下格式化对应的字符串规则。
/**
SimpleDateFormat函数语法:
G 年代标志符
y 年
M 月
d 日
h 时 在上午或下午 (1~12)
H 时 在一天中 (0~23)
m 分
s 秒
S 毫秒
E 星期
D 一年中的第几天
F 一月中第几个星期几
w 一年中第几个星期
W 一月中第几个星期
a 上午 / 下午 标记符
k 时 在一天中 (1~24)
K 时 在上午或下午 (0~11)
z 时区
*/
例子
public static final String FORMAT_DATE = "yyyy-MM-dd HH:mm:ss";
详细的使用方法可以搜索一下相关文章进行了解。
将Calendar、Date、TimeMills(时间戳)转化为指定格式日期字符串
//格式化日期对应的格式
public static final String FORMAT_DATE = "yyyy-MM-dd HH:mm:ss";
/**
* Calendar转化成格式化日期字符串
* */
public String getFormatDateFromCalendar(Calendar calendar) {
SimpleDateFormat simpleDateFormat = new SimpleDateFormat(FORMAT_DATE);
Date date = calendar.getTime();
String formatStr = simpleDateFormat.format(date);
return formatStr;
}
/**
* Date转化成格式化日期字符串
* */
public String getFormatDateFromDate(Date date){
SimpleDateFormat simpleDateFormat = new SimpleDateFormat(FORMAT_DATE);
String formatStr = simpleDateFormat.format(date);
return formatStr;
}
/**
* 时间戳转化成格式化日期字符串
* @param mills the milliseconds since January 1, 1970, 00:00:00 GMT.
* */
public String getFormatDateFromDate(long mills){
SimpleDateFormat simpleDateFormat = new SimpleDateFormat(FORMAT_DATE);
Date date = new Date(mills);
String formatStr = simpleDateFormat.format(date);
return formatStr;
}
将SimpleDateFormat格式化后的日期转化成Calendar、Date对象
Calendar对象和Date之间可以互相转化
Date date = calendar.getTime();
public static final String FORMAT_DATE = "yyyy-MM-dd HH:mm:ss";
/**
* 从格式化的日期字符串获取Calendar对象
* */
public static Calendar getCalendarFromFormatStr(String formatDateStr){
SimpleDateFormat sdf = new SimpleDateFormat(FORMAT_DATE);
Calendar calendar = Calendar.getInstance();
try {
Date date = sdf.parse(formatDateStr);
calendar.setTime(date);
} catch (ParseException e) {
e.printStackTrace();
}
return calendar;
}
工具方法
判断指定时间是否在某个时间区间内
Calendar、Date和时间戳之间可以相互转化,下面直接使用的Calendar对象进行比较,如有需要可以先自行转换成Calendar
/**
* 判断指 targetCalendar 是否在指定时间内,开始时间和结束时间均用Calendar表示
*
* @param targetCalendar 需要判断的日期
* @param startCalendar 开始日期
* @param endCalendar 结束日期
* @return true 在时间区间内
* false 不再时间区间内
*/
public static boolean isBetween(Calendar targetCalendar, Calendar startCalendar, Calendar endCalendar) {
boolean isBeforeEnd = targetCalendar.before(endCalendar);
if (isBeforeEnd) {//true 目标日期在结束日期之前
boolean isAfterStart = targetCalendar.after(startCalendar);
if (isAfterStart) {//true 目标日期在开始日期之后
return true;
}
}
return false;
}
注意:该方法具有局限性,详细请看下方解释
从源码可以看到这个比较方法是通过compareTo()方法做的
下面是Calendar的部分源码
public boolean before(Object when) {
return when instanceof Calendar
&& compareTo((Calendar)when) < 0;
}
public boolean after(Object when) {
return when instanceof Calendar
&& compareTo((Calendar)when) > 0;
}
@Override
public int compareTo(Calendar anotherCalendar) {
return compareTo(getMillisOf(anotherCalendar));
}
private int compareTo(long t) {
long thisTime = getMillisOf(this);
return (thisTime > t) ? 1 : (thisTime == t) ? 0 : -1;
}
private static long getMillisOf(Calendar calendar) {
if (calendar.isTimeSet) {
return calendar.time;
}
Calendar cal = (Calendar) calendar.clone();
cal.setLenient(true);
return cal.getTimeInMillis();
}
从中可以看出Calendar进行比较是通过时间戳,也就是我们必须拥有严格意义上的时间戳(准确的时间,包括年月日时分秒毫秒),才可以通过这样的方法进行判断,而且是开区间(不包括开始和结束时间)
如果我们想判断某个日期(不包括时分秒)是否在指定区间(包括区间边界)内应该怎么做呢?
判断某个日期是否在指定区间(包括区间边界)内?
如果不需要包括区间只需要在判断时做一下对应需求的改动就可以了
思路:把三个时间都先格式化,根据要比较的级别把日期格式化成对应格式,比如:只比较年月日,那么就把日期格式化成 yyyyMMdd 格式,如 19960517,如果还需要小时,则可以把日期格式化成 yyyyMMddHH 格式,如 1996051711,这样我们就把日期变成了可以转化成long的字符串,把这个字符串转化成long就可以根据自己的需求随意进行判断比较了
下面这个例子只比较了年月日,而且包括区间的边界
/**
* 根据要比较的级别,年月日时分秒,来写这个格式化规则
*/
public static final String DATE_FORMAT = "yyyyMMdd";
/**
* 判断日期是否在开始和结束日期之间
*
* @param selectDate 需要判断的日期
* @param start 区间开始日期
* @param end 区间结束日期
*/
public boolean isDateBetween(Calendar selectDate, Calendar start, Calendar end) {
long selectInt = getFormatTimeStr(selectDate);
long startInt = getFormatTimeStr(start);
long endInt = getFormatTimeStr(end);
if (selectInt == -1 || startInt == -1 || endInt == -1) {
return false;
}
if (selectInt >= startInt && selectInt <= endInt) {
return true;
}else{
return false;
}
}
/**
* 将Calendar格式化成指定时间格式,然后转成long
* 返回int值的时间,格式为yyyyMMdd,因为只比较年月日
* */
private static long getFormatTimeStr(Calendar calendar) {
long timeInt;
if (calendar == null) {
return -1;
}
SimpleDateFormat sdr = new SimpleDateFormat(DATE_FORMAT);
String dateStr = sdr.format(calendar.getTime());//eg:201801126
try {
timeInt = Integer.parseInt(dateStr);
} catch (NumberFormatException e) {
e.printStackTrace();
return -1;
}
return timeInt;
}
获取前后几天对应的Calendar对象
如果需要获取指定日期的前后几天的日期,可以自己传入指定的Calendar对象。同样也可以根据需要使用Calendar.MONTH、Calendar.YEAR获取前后几年对应的日期。
/**
* 获取前几天或者后几天
* @param offsetDay 偏移量 >0 代表向后的天数
* <0 代表向前的天数
* */
public Calendar getCalendarDateOffset(int offsetDay){
Calendar calendar = Calendar.getInstance();
calendar.add(Calendar.DATE,offsetDay);
return calendar;
}
到这里关于时间相关的常用操作就介绍的差不多了,如果后期还有新的内容还会继续补充。
end