日期的格式有很多形式,在使用过程中经常需要转换,下面是各种类型转换的使用例子以及日期计算方法的例子。
一、不同格式日期相互转换方法
1 public class TestDateConvertUtil { 2 3 public static void main(String[] args) throws ParseException { 4 // 获取当前时间 5 Date date = new Date(); // 获取当前时间 6 long timestamp = System.currentTimeMillis(); // 获取当前时间戳 7 8 // 日期格式转换 9 date2String(); // 日期转字符串 10 string2Date(); // 字符串转日期 11 date2Timestamp(); // 日期转时间戳 12 timestamp2Date(); // 时间戳转日期 13 cst2Date(); // CST格式转日期 14 nonstandard2Date(); // 非标准格式转日期 15 convertDateStr(); // 日期字符串格式转换 16 date2Calendar(); // 日期转日历 17 calendar2Date(); // 日历转日期 18 } 19 20 public static void date2String() { 21 SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); 22 Date date = new Date(); 23 String dateStr = sdf.format(date); 24 System.out.println(dateStr); 25 } 26 27 public static void string2Date() throws ParseException { 28 SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); 29 String dateStr = "2018-05-16 19:30:20"; 30 Date date = sdf.parse(dateStr); 31 System.out.println(date); 32 } 33 34 public static void date2Timestamp() { 35 Date date = new Date(); 36 String timestamp = String.valueOf(date.getTime()); 37 System.out.println(timestamp); 38 } 39 40 public static void timestamp2Date() { 41 String timestamp = "1526470220000"; 42 Date date = new Date(new Long(timestamp)); 43 System.out.println(date); 44 } 45 46 public static void cst2Date() throws ParseException { 47 SimpleDateFormat sdf = new SimpleDateFormat("EEE MMM dd HH:mm:ss zzz yyyy", java.util.Locale.US); // 注意使用Locale.US参数 48 String cst = "Tue May 16 19:30:20 CST 2018"; 49 Date date = sdf.parse(cst); 50 System.out.println(date); 51 } 52 53 public static void nonstandard2Date() throws ParseException { 54 SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd"); 55 sdf.setLenient(false); // 设置严格验证日期 56 String dateStr = "20180516"; 57 Date date = sdf.parse(dateStr); 58 System.out.println(date); 59 } 60 61 public static void convertDateStr() throws ParseException { 62 SimpleDateFormat sdfSource = new SimpleDateFormat("yyyyMMdd"); 63 SimpleDateFormat sdfTarget = new SimpleDateFormat("yyyy-MM-dd"); 64 String dateSource = "20180516"; 65 String dateTarget = sdfTarget.format(sdfSource.parse(dateSource)); 66 System.out.println(dateTarget); 67 } 68 69 public static void date2Calendar() { 70 Date date = new Date(); 71 Calendar c = Calendar.getInstance(); 72 c.setTime(date); 73 System.out.println(c); 74 } 75 76 public static void calendar2Date() { 77 Calendar c = Calendar.getInstance(); 78 Date date = c.getTime(); 79 System.out.println(date); 80 } 81 }
例子中,setLenient方法默认值为true,意思为宽泛的日期格式校验,比如20180532这样的值转date类型,会自动变成20180601。如果需要严格的日期校验需要设置为false。
二、日期计算方法
日期的计算通常是通过Calendar类,但使用起来没有这么方便。org.apache.commons.lang3.time.DateUtils类提供了很多简便的日期计算方法,可供使用,其实其底层也是通过Calendar类来实现的。
下面日期计算例子中DateUtils的方法及参数大部分都有年、月、日、时、分、秒、毫秒之分,可以根据自身需要调用。
1 public class TestDateCalculateUtil { 2 3 public static void main(String[] args) throws ParseException { 4 // 日期计算.例子:2018-05-16 19:30:20 5 DateUtils.setYears(new Date(), 2019); // 根据参数设置日期年份.输出:2019-05-16 19:30:20 6 DateUtils.addMonths(new Date(), -1); // 根据参数增加日期月份.输出:2019-04-16 19:30:20 7 DateUtils.truncate(new Date(), Calendar.DATE); // 根据参数截取日期.输出:2019-04-16 00:00:00 8 DateUtils.ceiling(new Date(), Calendar.DATE); // 根据参数向上进位日期.输出:2018-05-17 00:00:00 9 DateUtils.getFragmentInDays(new Date(), Calendar.MONTH); // 根据参数截取范围内日期后返回天数.输出:16 10 DateUtils.truncatedEquals(new Date(), new Date(), Calendar.DATE); //根据参数范围比较日期是否相同,该例子只比较年月日.输出:true 11 DateUtils.truncatedCompareTo(new Date(), new Date(), Calendar.MONTH); //根据参数范围比较日期大小,该例子只比较年月.输出:0 12 13 // 举例 14 getFirstSecondOfMonth(); // 获取当月第一秒 15 getLastSecondOfMonth(); // 获取当月最后一秒 16 getDayOfYear(); // 获取日期是该年的第几天 17 getFirstSundayOfMonth(); // 获取当月的第一个周日 18 } 19 20 public static void getFirstSecondOfMonth() { 21 Date date = new Date(); 22 date = DateUtils.truncate(date, Calendar.MONTH); // 截取日期到月份 23 System.out.println(date); // 输出:2018-05-01 00:00:00 24 } 25 26 public static void getLastSecondOfMonth() { 27 Date date = new Date(); 28 date = DateUtils.ceiling(date, Calendar.MONTH); // 向上进位月份 29 date = DateUtils.addSeconds(date, -1); // 减1秒 30 System.out.println(date); // 输出:2018-05-31 23:59:59 31 } 32 33 public static void getDayOfYear() { 34 Date date = new Date(); 35 long day = DateUtils.getFragmentInDays(date, Calendar.YEAR); // 截取年之后的日期部分,并按天数返回 36 System.out.println(day); // 输出:136 37 } 38 39 public static void getFirstSundayOfMonth() { 40 Date date = new Date(); 41 date = DateUtils.setDays(date, 1); // 从该月第一天开始 42 while (true) { 43 Calendar c = Calendar.getInstance(); 44 c.setTime(date); 45 if (c.get(Calendar.DAY_OF_WEEK) == Calendar.SUNDAY) { // 比较该天是否为周日 46 System.out.println(date); // 输出:2018-05-06 19:30:20 47 break; 48 } else { 49 date = DateUtils.addDays(date, 1); 50 } 51 } 52 } 53 }
各个方法之间可以相互组合使用,基本上能解决大部分的日期计算问题。
2018-9-4 更新:计算日期间隔的方法
日期间隔的计算可以使用org.apache.commons.lang3.time.DurationFormatUtils类提供的formatPeriod方法,也可以根据自身需求稍加封装即可计算年、月、日等间隔。
1 public static void main(String[] args) { 2 // 两个日期之间实际的间隔,并按规定格式返回,如:2018.8.31与2018.9.4 相差5天 3 String period = DurationFormatUtils.formatPeriod(DateUtils.addDays(new Date(), -5).getTime(), new Date().getTime(), "y-M-d"); 4 System.out.println(period); // 相差5天,输出:0-0-5 5 6 // 计算两个月之间的间隔,跨月即算间隔1个月,如:2018.8.31与2018.9.4 相差1个月 7 int periodOfMonth = getPeriodOfMonth(DateUtils.addDays(new Date(), -5), new Date()); 8 System.out.println(periodOfMonth); // 相差1个月,输出:1 9 } 10 11 public static int getPeriodOfMonth(Date dateBegin, Date dateEnd) { 12 Date begin = DateUtils.truncate(dateBegin, Calendar.MONTH); 13 Date end = DateUtils.truncate(dateEnd, Calendar.MONTH); 14 String period = DurationFormatUtils.formatPeriod(begin.getTime(), end.getTime(), "M"); 15 return Integer.parseInt(period); 16 }
formatPeriod方法中,可选择的格式化参数: