本文详细介绍了 Java 开发中处理日期时间的核心类与方法。内容涵盖 java.util.Date 的基本操作、DateFormat 与 SimpleDateFormat 的多语言格式化处理,以及 Calendar 类在日期字段计算和时区处理中的应用。通过实际代码示例,解决了日期格式化、字符串解析、日期加减及星期/月份边界计算等常见需求,并指出了月份从0开始等易错点。
核心类概述与作用
在 Java 中进行日期和时间处理,主要涉及以下五个关键类。理解它们的层级关系是正确使用的先决条件:
java.util.Date:表示特定的瞬间,精确到毫秒。自 JDK 1.1 起,官方建议使用 Calendar 进行字段转换,使用 DateFormat 进行格式化。Date 中直接获取年、月、日的方法大多已被废弃。
java.text.DateFormat:日期/时间格式化子类的抽象基类。它提供与语言无关的格式化和分析功能,支持将日期转换为文本(格式化)或文本转换为日期(分析)。
java.text.SimpleDateFormat:DateFormat 的具体子类,允许用户定义自定义的日期-时间格式模式。它是日常开发中最常用的格式化类。
java.util.Calendar:抽象类,用于在特定瞬间与日历字段(如 YEAR、MONTH、DAY_OF_MONTH 等)之间进行转换,并提供日历字段的算术操作。
java.util.GregorianCalendar:Calendar 的具体子类,提供世界上大多数国家使用的格里高利历标准系统。
java.util.Date 的基础使用
java.util.Date 主要用于表示时间点,其核心操作包括获取当前时间及毫秒级时间戳。以下是获取系统当前时间的完整示例:
public class TestDate {
public static void main(String[] args) {
TestDate testdate = new TestDate();
testdate.getSystemCurrentTime();
testdate.getCurrentDate();
}
/**
* 获取系统当前时间
* System.currentTimeMillis()返回系统当前时间,结果为1970年1月1日0时0分0秒开始,到程序执行取得系统时间为止所经过的毫秒数
* 1秒=1000毫秒
*/
public void getSystemCurrentTime(){
System.out.println("---获取系统当前时间---");
System.out.println(System.currentTimeMillis());
}
public void getCurrentDate(){
System.out.println("---获取系统时间---");
//创建并初始化一个日期(初始值为当前日期)
Date date = new Date();
System.out.println("现在的日期是 = " + date.toString());
System.out.println("自1970年1月1日0时0分0秒开始至今所经历的毫秒数 = " + date.getTime());
}
}
第1步:通过 DateFormat 进行标准格式化
DateFormat 提供了基于默认区域风格的静态工厂方法,适合快速生成符合当地习惯的日期字符串。推荐做法是复用格式化实例以避免重复加载区域信息。
// 单次格式化
String formatted = DateFormat.getDateInstance().format(myDate);
// 批量处理时复用实例以提高效率
DateFormat df = DateFormat.getDateInstance();
for (Date d : myDateArray) {
output.println(df.format(d));
}
可以通过指定风格(FULL, LONG, MEDIUM, SHORT)和 Locale 来定制格式:
// 法国法语LONG风格日期格式
DateFormat dfFR = DateFormat.getDateInstance(DateFormat.LONG, Locale.FRANCE);
// 分析字符串为日期对象
Date parsedDate = dfFR.parse("24 janvier 2016");
第2步:使用 SimpleDateFormat 实现自定义格式
当需要精确控制输出格式时,应使用 SimpleDateFormat。模式字母含义如下:yyyy(年)、MM(月)、dd(日)、hh/mm/ss(时分秒)、EEEE(星期)。
public class TestDateFormat {
public static void main(String[] args) throws ParseException {
TestDateFormat tdf = new TestDateFormat();
tdf.dateFormat();
}
/**
* 对SimpleDateFormat类进行测试
* @throws ParseException
*/
public void dateFormat() throws ParseException{
//创建日期
Date date = new Date();
//创建不同的日期格式
DateFormat df1 = DateFormat.getInstance();
DateFormat df2 = new SimpleDateFormat("yyyy-MM-01 hh:mm:ss EE");
DateFormat df3 = DateFormat.getDateInstance(DateFormat.FULL, Locale.CHINA); //产生一个指定国家指定长度的日期格式,长度不同,显示的日期完整性也不同
DateFormat df4 = new SimpleDateFormat("yyyy年MM月dd日 hh时mm分ss秒 EE", Locale.CHINA);
DateFormat df5 = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss EEEEEE", Locale.US);
DateFormat df6 = new SimpleDateFormat("yyyy-MM-dd");
//将日期按照不同格式进行输出
System.out.println("-------将日期按照不同格式进行输出------");
System.out.println("按照Java默认的日期格式,默认的区域 : " + df1.format(date));
System.out.println("按照指定格式 yyyy-MM-dd hh:mm:ss EE ,系统默认区域 :" + df2.format(date));
System.out.println("按照日期的FULL模式,区域设置为中文 : " + df3.format(date));
System.out.println("按照指定格式 yyyy年MM月dd日 hh时mm分ss秒 EE ,区域为中文 : " + df4.format(date));
System.out.println("按照指定格式 yyyy-MM-dd hh:mm:ss EE ,区域为美国 : " + df5.format(date));
System.out.println("按照指定格式 yyyy-MM-dd ,系统默认区域 : " + df6.format(date));
//将符合该格式的字符串转换为日期,若格式不相配,则会出错
Date date1 = df1.parse("16-01-24 下午2:32");
Date date2 = df2.parse("2016-01-24 02:51:07 星期日");
Date date3 = df3.parse("2016年01月24日 星期五");
Date date4 = df4.parse("2016年01月24日 02时51分18秒 星期日");
Date date5 = df5.parse("2016-01-24 02:51:18 Sunday");
Date date6 = df6.parse("2016-01-24");
System.out.println("-------输出将字符串转换为日期的结果------");
System.out.println(date1);
System.out.println(date2);
System.out.println(date3);
System.out.println(date4);
System.out.println(date5);
System.out.println(date6);
}
}
java.util.Calendar 高级操作与避坑指南
Calendar 是进行日期计算(加减、获取特定位)的主力工具。使用时需特别注意其内部常量定义的“陷阱”。
第1步:正确初始化与设置时间
可通过多种方式创建 Calendar 实例,注意构造函数中月份的取值范围是 0-11。
public class TestCalendar {
public static void main(String[] args) throws ParseException {
TestCalendar testCalendar = new TestCalendar();
testCalendar.testCalendar();
testCalendar.testCalendar2();
}
public void testCalendar(){
//创建Calendar的方式
Calendar now1 = Calendar.getInstance();
Calendar now2 = new GregorianCalendar();
Calendar now3 = new GregorianCalendar(2016, 01, 24);
Calendar now4 = new GregorianCalendar(2016, 01, 24, 15, 55); //陷阱:Calendar的月份是0~11
Calendar now5 = new GregorianCalendar(2016, 01, 24, 15, 55, 44);
Calendar now6 = new GregorianCalendar(Locale.US);
Calendar now7 = new GregorianCalendar(TimeZone.getTimeZone("GMT-8:00"));
//通过日期和毫秒数设置Calendar
now2.setTime(new Date());
System.out.println(now2);
now2.setTimeInMillis(new Date().getTime());
System.out.println(now2);
//定义日期的中文输出格式,并输出日期
SimpleDateFormat df = new SimpleDateFormat("yyyy年MM月dd日 hh时mm分ss秒 E", Locale.CHINA);
System.out.println("获取日期中文格式化化输出:" + df.format(now5.getTime()));
System.out.println();
System.out.println("--------通过Calendar获取日期中年月日等相关信息--------");
System.out.println("获取年:" + now5.get(Calendar.YEAR));
System.out.println("获取月(月份是从0开始的):" + now5.get(Calendar.MONTH));
System.out.println("获取日:" + now5.get(Calendar.DAY_OF_MONTH));
System.out.println("获取时:" + now5.get(Calendar.HOUR));
System.out.println("获取分:" + now5.get(Calendar.MINUTE));
System.out.println("获取秒:" + now5.get(Calendar.SECOND));
System.out.println("获取上午、下午:" + now5.get(Calendar.AM_PM));
System.out.println("获取星期数值(星期是从周日开始的):" + now5.get(Calendar.DAY_OF_WEEK));
System.out.println();
System.out.println("---------通用星期中文化转换---------");
String dayOfWeek[] = {"", "日", "一", "二", "三", "四", "五", "六"};
System.out.println("now5对象的星期是:" + dayOfWeek[now5.get(Calendar.DAY_OF_WEEK)]);
System.out.println();
System.out.println("---------通用月份中文化转换---------");
String months[] = {"一月", "二月", "三月", "四月", "五月", "六月", "七月", "八月", "九月", "十月", "十一月", "十二月"};
System.out.println("now5对象的月份是: " + months[now5.get(Calendar.MONTH)]);
第2步:执行日期计算与边界判断
Calendar 在处理月末最后一天、星期推算及日期差值方面具有天然优势。请务必牢记:月份从0开始(1月为0),星期从周日开始(周日为1)。
public void testCalendar2() throws ParseException{
//获取当前月份的最大天数
Calendar cal = Calendar.getInstance();
int maxday=cal.getActualMaximum(Calendar.DAY_OF_MONTH);
int minday=cal.getActualMinimum(Calendar.DAY_OF_MONTH);
System.out.println(maxday);
//取当月的最后一天
DateFormat formatter3=new SimpleDateFormat("yyyy-MM-"+maxday);
System.out.println(formatter3.format(cal.getTime()));
//取当月的最后一天
DateFormat formatter4=new SimpleDateFormat("yyyy-MM-"+minday);
System.out.println(formatter4.format(cal.getTime()));
//求两个日期之间相隔的天数
java.text.SimpleDateFormat format = new java.text.SimpleDateFormat("yyyy-MM-dd");
java.util.Date beginDate= format.parse("2007-12-24");
java.util.Date endDate= format.parse("2007-12-25");
long day=(endDate.getTime()-beginDate.getTime())/(24*60*60*1000);
System.out.println("相隔的天数="+day);
//一年前的日期
java.text.Format formatter5=new java.text.SimpleDateFormat("yyyy-MM-dd");
java.util.Date todayDate=new java.util.Date();
long beforeTime=(todayDate.getTime()/1000)-60*60*24*365;
todayDate.setTime(beforeTime*1000);
String beforeDate=formatter5.format(todayDate);
System.out.println(beforeDate);
Calendar calendar = Calendar.getInstance();
calendar.add(Calendar.YEAR, -1);
System.out.println(formatter5.format(calendar.getTime()));
//当前星期的星期一和星期日
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMdd");
GregorianCalendar gregorianCalendar = new GregorianCalendar();
int dayInWeek = gregorianCalendar.get(Calendar.DAY_OF_WEEK);
int offset = 0;
if (dayInWeek == 1) {
// 星期天
offset = 6;
} else {
// 星期一至星期六
offset = dayInWeek - 2;
}
gregorianCalendar.add(GregorianCalendar.DAY_OF_MONTH, -offset);
String sday = dateFormat.format(gregorianCalendar.getTime());
gregorianCalendar.add(GregorianCalendar.DAY_OF_MONTH, 6);
String eday = dateFormat.format(gregorianCalendar.getTime());
System.out.println("这个星期的星期一:" + sday);
System.out.println("这个星期的星期天:" + eday);
}
}
总结
Java 日期时间处理的核心场景可归纳为五点:创建时间对象、格式化显示、字符串互转、提取年月日等字段、以及日期比较与加减运算。在使用 Calendar 进行计算时,时刻注意其底层常量的特殊性,能有效避免大量逻辑错误。
以上就是Java日期时间使用方法的详细内容,更多关于Java日期处理技巧的资料请关注本站其它相关文章!