在之前的项目中,经常会遇到Calendar,Date的一些操作时间的类,并且总会遇到时间日期之间的格式转化问题,虽然做完了但是总是忘记,记不清楚,每次还都要查找资料。今天总结一下,加深印象。
Calendar
Calendar是java.util 包下面的一个抽象类,它为特定瞬间与一组诸如YEAR、MONTH、DAY_OF_MONTH、HOUR等日历字段之间的转换提供了一些方法,并未操作日历字段(例如获得下星期的日期)提供了一些方法。瞬间值可用毫秒值来表示,它是距格林威治标准时间 1970 年1月 1日的 00:00:00:000的偏移量。
Java API 中说到,Calendar提供了一个类方法getInstance,以此获得此类型的一个通用对象,Calendar的getInstance返回一个Calendar对象,其日历字段值已由当前日期和时间初始化。我们知道,抽象类是不能够被实例化的,那为什么会返回一个Calendar对象呢?Calendar还有一个直接子类GregorianCalendar,这个类是Calendar的实现类,那么其实getInstance方法返回的是Calendar的子类GregorianCalendar的对象。
Calendar对日历字段的操作有三种方法:
set() ,add() , roll()
set(f,value),这个方法的含义是把日历字段f设置成value,api中说到,它设置了一个内部的成员变量,以指示f发生了改变,但是直到调用get()
、getTime()
、getTimeInMillis()
、add()
或 roll()
时才会重新计算日历的时间值(以毫秒为单位)。
add(f,delate),将delate添加到f字段中,这相当于是set(f,get(f)+delate),当然,这样改动的话,可能日历的其他字段也会发生相应的改变,与 set()
不同,add()
强迫日历系统立即重新计算日历的毫秒数和所有字段。
roll(f,value)与add(f,delate)的区别 :在完成调用后,更大的字段无变化
在项目中,经常看见的是通过Calendar对象得到当前的年月日。
下面通过一个小小的例子看看是如何得到年月日的
import java.util.Calendar; public class CalendarTest { public static void main(String[] args) { Calendar cal= Calendar.getInstance(); int day= cal.get(Calendar.DATE); int month=cal.get(Calendar.MONTH)+1; int year=cal.get(Calendar.YEAR); String[] weekDays = {"星期日", "星期一", "星期二", "星期三", "星期四", "星期五", "星期六"}; int w = cal.get(Calendar.DAY_OF_WEEK) - 1; if (w < 0) w = 0; System.out.println( year+"年"+month+"月"+day+"号,"+weekDays[w]); } }
此代码输出的是2017年6月15号,星期四
为什么month要加1才能得到当前月份呢?
是因为在格里高利历和罗马儒略历中一年中的第一个月是 JANUARY,它为 0;最后一个月取决于一年中的月份数。 简单来说,因为这个值的初始值是0,因此我们要用它来表示正确的月份时就需要加1。为什么week要减1呢?这是因为一个星期中的第一天是SunDay,从星期日到星期六,对应的数字分别是1,2,3,4,5,6,7,所以需要减1。 Calendar还有其他的一些方法,比如getTimeMillis(),返回Calendar的时间值,以毫秒计算getTime(),返回一个此Calendar的时间值的Date对象,和new Date()的值是一样的。 Date Date也是java.util包下的一个类,类Date
表示特定的瞬间,精确到毫秒。从 JDK 1.1 开始,应该使用Calendar
类实现日期和时间字段之间转换,使用DateFormat
类来格式化和解析日期字符串。Date
中的相应方法已废弃。 SimpleDateFormat SimpleDateFormat 是一个以与语言环境有关的方式来格式化和解析日期的具体类。SimpleDateFormat是DateFormat抽象类的实现类,DateFormat继承Format,Format定义了编程接口,用于将语言环境敏感的对象格式化为String
(使用format
方法)和将String
重新解析为对象(使用parseObject
方法)。
在格式化日期的时候,经常用到的构造方法是带一个String参数的
Public SimpleDateFormat(String pattern)这个构造函数的意思是用给定的模式和默认的语言环境构的日期格式符号来格式化。 SimpleDateFormat中有format方法和pase方法,format方法是将Date对象转化为String字符串,pase是将字符串转化为Date对象。下面通过代码来展示日期和字符串之间的转化。假如我要将一个日期类型的时间格式转化成"yyyy-mm-dd"类型的字符串,需要用到format方法,Date date=new Date();SimpleDateFormat sdf = new SimpleDateFormat("yyyy-mm-dd");sdf.format(date);如果需要将"yyyy-mm-dd"String类型的日期转化成日期对象类型,就需要用到parse,
String str= "2017-6-17"sdf.parse(str),这样就可以得到一个日期类型。 附上项目当中的时间转换的util,里面包含了对时间的各种转化。
import java.sql.Timestamp; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.Calendar; import java.util.Date; import java.util.Locale; import java.util.TimeZone; import org.apache.commons.lang3.StringUtils; public final class DateUtil { // 默认显示日期的格式 public static final String DATAFORMAT_STR = "yyyy-MM-dd"; // 默认显示日期的格式 public static final String YYYY_MM_DATAFORMAT_STR = "yyyy-MM"; // 默认显示日期时间的格式 public static final String DATATIMEF_STR = "yyyy-MM-dd HH:mm:ss"; // 默认显示日期时间的格式 public static final String DATATIMEF_STR2 = "yyyyMMdd HH:mm:ss"; // 默认显示日期时间的格式 精确到毫秒 public static final String DATATIMEF_STR_MIS = "yyyyMMddHHmmssSSS"; // 默认显示日期时间的格式 精确到分钟 public static final String DATATIMEF_STR_MI = "yyyy-MM-dd HH:mm"; public static final String DATATIMEF_STR_MDHm = "MM.dd HH:mm"; public static final String HH_STR = "HH"; // 精确到秒 public static final String DATATIMEF_STR_SEC = "yyyyMMddHHmmss"; // 默认显示简体中文日期的格式 public static final String ZHCN_DATAFORMAT_STR = "yyyy年MM月dd日"; // 默认显示简体中文日期时间的格式 public static final String ZHCN_DATATIMEF_STR = "yyyy年MM月dd日HH时mm分ss秒"; // 默认显示简体中文日期时间的格式 public static final String ZHCN_DATATIMEF_STR_4yMMddHHmm = "yyyy年MM月dd日HH时mm分"; // 默认显示月份和日期的格式 public static final String MONTHANDDATE_STR = "MM.dd"; public static final String DATATIMEF_STR_MIN = "yyyyMMddHHmm"; public static final String HOUR_END = " 23:59:59"; public static final String HOUR_START = " 00:00:00"; private DateUtil() { } public static Date now() { return Calendar.getInstance(Locale.CHINESE).getTime(); } public static Date daysAfter(Date baseDate, int increaseDate) { Calendar calendar = Calendar.getInstance(Locale.CHINESE); calendar.setTime(baseDate); calendar.add(Calendar.DATE, increaseDate); return calendar.getTime(); } public static Date hoursAfter(Date baseDate, int increaseHours) { Calendar calendar = Calendar.getInstance(Locale.CHINESE); calendar.setTime(baseDate); calendar.add(Calendar.HOUR_OF_DAY, increaseHours); return calendar.getTime(); } public static Date minuteAfter(Date baseDate, int increaseMonths) { Calendar calendar = Calendar.getInstance(Locale.CHINESE); calendar.setTime(baseDate); calendar.add(Calendar.MINUTE, increaseMonths); return calendar.getTime(); } public static Date monthAfter(Date baseDate, int increaseMonths) { Calendar calendar = Calendar.getInstance(Locale.CHINESE); calendar.setTime(baseDate); calendar.add(Calendar.MONTH, increaseMonths); return calendar.getTime(); } public static Date getInternalDateByDay(Date d, int days) { Calendar now = Calendar.getInstance(TimeZone.getDefault()); now.setTime(d); now.add(Calendar.DATE, days); return now.getTime(); } public static Date getInternalDateByMinute(Date d, int minutes) { Calendar now = Calendar.getInstance(TimeZone.getDefault()); now.setTime(d); now.add(Calendar.MINUTE, minutes); return now.getTime(); } /** * 将Date转换成字符串“yyyy-mm-dd hh:mm:ss”的字符串 * * @param date * @return */ public static String dateToDateString(Date date) { return dateToDateString(date, DATATIMEF_STR); } /** * 将Date转换成字符串“yyyy-mm-dd hh:mm:ss”的字符串 * * @param date * @return */ public static String dateToDateString2(Date date) { return dateToDateString(date, DATATIMEF_STR2); } /** * 将Date转换成formatStr格式的字符串 * * @param date * @param formatStr * @return */ public static String dateToDateString(Date date, String formatStr) { if (date == null) { return null; } java.text.DateFormat df = getDateFormat(formatStr); return date != null ? df.format(date) : ""; } /** * 按照默认formatStr的格式,转化dateTimeStr为Date类型 dateTimeStr必须是formatStr的形式 * * @param dateTimeStr * @param formatStr * @return */ public static Date getDate(String dateTimeStr, String formatStr) { try { if (dateTimeStr == null || dateTimeStr.equals("")) { return null; } java.text.DateFormat sdf = new SimpleDateFormat(formatStr); java.util.Date d = sdf.parse(dateTimeStr); return d; } catch (ParseException e) { throw new RuntimeException(e); } } public static String getCurDate() { return dateToDateString(Calendar.getInstance().getTime(), DATAFORMAT_STR); } public static String getCurHour() { return dateToDateString(Calendar.getInstance().getTime(), HH_STR); } public static int getThisMonth() { Calendar c = Calendar.getInstance(Locale.CHINESE); int month = c.get(Calendar.MONTH) + 1; return month; } public static int getThisWeek() { Calendar c = Calendar.getInstance(Locale.CHINESE); c.setFirstDayOfWeek(Calendar.MONDAY); int week = c.get(Calendar.WEEK_OF_YEAR); return week; } public static SimpleDateFormat getDateFormat(final String formatStr) { return new SimpleDateFormat(formatStr); } @SuppressWarnings("deprecation") public static String getFirstDateOfMonth(Date now) { SimpleDateFormat df1 = new SimpleDateFormat(DATATIMEF_STR); Date da = new Date(now.getYear(), now.getMonth(), 01); return df1.format(da); } @SuppressWarnings("deprecation") public static String getLastDateOfMonth(Date now) { SimpleDateFormat df1 = new SimpleDateFormat(DATATIMEF_STR); Date da = new Date(now.getYear(), now.getMonth(), 31); return df1.format(da); } /** * 获取两个毫秒间隔的分钟 * * @param t1 * @param t2 * @return */ public static int getMinutesBetweenMillis(long t1, long t2) { return (int) ((t1 - t2) / (60 * 1000)); } /** * 判断目标时间是否处于某一时间段内 * * @param target * @param begin * @param end * @return */ public static boolean compareTargetTime(Date target, String begin, String end) { // 格式化时间 暂时不考虑传入参数的判断,其他地方如果要调用,最好扩展判断一下入参问题 String targetTime = dateToDateString(target, DATATIMEF_STR).substring( 11);// HH:mm:ss if (targetTime.compareTo(begin) >= 0 && end.compareTo(targetTime) >= 0) { return true; } return false; } /** * * @param time1 * @param timw2 * @return time1 小于 time 2 返回 true */ public static boolean compareTime(Date time1, Date time2) { long start = time1.getTime(); long end = time2.getTime(); if (start < end) { return true; } return false; } /** * 取得两个时间段的时间间隔 return t2 与t1的间隔天数 throws ParseException * 如果输入的日期格式不是0000-00-00 格式抛出异常 */ public static int getBetweenDays(String t1, String t2) throws ParseException { SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd"); int betweenDays = 0; Date d1 = format.parse(t1); Date d2 = format.parse(t2); Calendar c1 = Calendar.getInstance(); Calendar c2 = Calendar.getInstance(); c1.setTime(d1); c2.setTime(d2); // 保证第二个时间一定大于第一个时间 if (c1.after(c2)) { c1 = c2; c2.setTime(d1); } int betweenYears = c2.get(Calendar.YEAR) - c1.get(Calendar.YEAR); betweenDays = c2.get(Calendar.DAY_OF_YEAR) - c1.get(Calendar.DAY_OF_YEAR); for (int i = 0; i < betweenYears; i++) { c1.set(Calendar.YEAR, (c1.get(Calendar.YEAR) + 1)); betweenDays += c1.getMaximum(Calendar.DAY_OF_YEAR); } return betweenDays; } /** * 格式化时间 yyyy-MM-dd * * @return */ public static String getFormatDate(Date date) { return new SimpleDateFormat().format(date); } /** * 按照默认formatStr的格式,转化dateTimeStr为Date类型 dateTimeStr必须是formatStr的形式 * * @param dateTimeStr * @param formatStr * @return */ public static Date getFormatDate(Date dateTimer, String formatStr) { try { if (dateTimer == null) { return null; } java.text.DateFormat sdf = new SimpleDateFormat(formatStr); String timeStr = sdf.format(dateTimer); Date formateDate = sdf.parse(timeStr); return formateDate; } catch (ParseException e) { throw new RuntimeException(e); } } /** * 获取两个时间之间相差的天数 * * @param time1 * @param time2 * @return */ public static long getQuot(String time1, String time2) { long quot = 0; SimpleDateFormat ft = new SimpleDateFormat("yyyy-MM-dd"); try { Date date1 = ft.parse(time1); Date date2 = ft.parse(time2); quot = date1.getTime() - date2.getTime(); quot = quot / 1000 / 60 / 60 / 24; } catch (ParseException e) { e.printStackTrace(); } return quot; } public static long getQuot(Date time1, Date time2) { if(time1==null || time2==null) return -1; long quot = 0; quot = time1.getTime() - time2.getTime(); quot = quot / 1000 / 60 / 60 / 24; return quot; } /** * 获取和当前时间相差的分钟数 * * @param begin * @return */ public static long getDiffenceValue(Date begin) { long value = 0; Calendar cal = Calendar.getInstance(); Date now = cal.getTime(); value = (now.getTime() - begin.getTime()) / 1000 / 60; return value; } /** * 获取和当前时间相差的秒数 * * @param begin * @return */ public static long getSecondsValue(Date begin) { long value = 0; Calendar cal = Calendar.getInstance(); Date now = cal.getTime(); value = (now.getTime() - begin.getTime()) / 1000; return value; } public static long getMillsBetweenTwoDate(Date date1, Date date2) { return date1.getTime() - date2.getTime(); } /** * 求多少天前/后的日期 * * @param field * 单位:年,月,日 * @param day * 多少天 * @return */ public static final Date addDate(int field, int day) { Calendar nowCalendar = Calendar.getInstance(Locale.CHINESE); nowCalendar.setTime(DateUtil.now()); nowCalendar.add(field, day); return nowCalendar.getTime(); } /** * 获取本月第一天 * @return */ public static final String getCurrFirstDay(){ SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd"); Calendar c = Calendar.getInstance(); c.add(Calendar.MONTH, 0); c.set(Calendar.DAY_OF_MONTH, 1);// 设置为1号,当前日期既为本月第一天 String first = format.format(c.getTime()); return first; } /** * 获取本月第一天 * @return */ public static final String getCurrLastDay(){ SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd"); //获取当前月最后一天 Calendar ca = Calendar.getInstance(); ca.set(Calendar.DAY_OF_MONTH, ca.getActualMaximum(Calendar.DAY_OF_MONTH)); String last = format.format(ca.getTime()); return last; } /** * date类型转timestamp类型 * @return */ public static final Timestamp dateToTimestamp(Date date){ Timestamp time = new Timestamp(date.getTime()); return time; } /** * timestamp类型转date类型 * @return */ public static final Date TimestampTodate(Timestamp date){ Date d = new Date(date.getTime()); return d; } /** * String类型转date类型 * @return */ public static final Date StringTodate(String date){ if(StringUtils.isNotBlank(date)){ SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); try { return sdf.parse(date); } catch (ParseException e) { return null; } }else{ return null; } } }