在Java编程中,判断当前日期或特定日期是星期几是一项常见的需求,广泛应用于日程安排、日志记录、业务逻辑处理等场景,Java提供了多种方式来实现这一功能,从早期的java.util.Date和java.util.Calendar类,到Java 8引入的java.time包,每种方式都有其特点和适用场景,本文将详细介绍这些方法,并分析其优缺点,帮助开发者选择最适合的解决方案。

使用java.util.Calendar类(旧版API)
在Java 8之前,java.util.Calendar是处理日期和时间的主要工具类,通过Calendar实例可以获取日期的各个字段,包括星期几,需要注意的是,Calendar中DAY_OF_WEEK字段的取值范围是1(星期日)到7(星期六),这与部分开发者的习惯可能存在差异。
实现步骤如下:
- 获取
Calendar实例,可以使用Calendar.getInstance()方法获取当前日期的实例,或通过Calendar.getInstance(TimeZone)指定时区。 - 调用
get(Calendar.DAY_OF_WEEK)方法获取星期几对应的数值。 - 根据返回值判断具体的星期名称,通常需要通过条件判断或数组映射来实现。
示例代码:
import java.util.Calendar;
public class CalendarExample {
public static void main(String[] args) {
Calendar calendar = Calendar.getInstance();
int dayOfWeek = calendar.get(Calendar.DAY_OF_WEEK);
String[] weekDays = {"", "星期日", "星期一", "星期二", "星期三", "星期四", "星期五", "星期六"};
System.out.println("今天是:" + weekDays[dayOfWeek]);
}
}
注意事项:
Calendar类是线程不安全的,在多线程环境下需要额外处理同步问题。- 月份从0开始计数(0表示一月),而星期几从1开始计数,容易混淆。
- API设计较为繁琐,例如获取月份需要
Calendar.MONTH+1,容易出错。
使用java.text.SimpleDateFormat类(格式化方式)
SimpleDateFormat是用于日期格式化和解析的类,可以通过定义特定的模式字符串来获取星期几的名称,这种方式的优势在于代码简洁,直接通过格式化输出即可得到星期名称。
实现步骤如下:

- 创建
SimpleDateFormat实例,并指定包含星期的格式模式,如”EEEE”表示完整星期名称,”E”表示简写(如”周一”)。 - 调用
format(Date)方法,将Date对象或Calendar对象格式化为字符串。
示例代码:
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
public class SimpleDateFormatExample {
public static void main(String[] args) {
Calendar calendar = Calendar.getInstance();
Date date = calendar.getTime();
SimpleDateFormat sdf = new SimpleDateFormat("EEEE");
String weekDay = sdf.format(date);
System.out.println("今天是:" + weekDay);
// 简写形式
SimpleDateFormat sdfShort = new SimpleDateFormat("E");
System.out.println("今天是:" + sdfShort.format(date));
}
}
注意事项:
SimpleDateFormat同样是线程不安全的,多线程环境下应每次创建新实例或使用同步代码块。- 格式模式字符串区分大小写,”EEEE”和”e”的行为可能因不同Java版本而异。
- 需要结合
Date或Calendar使用,无法直接处理java.time包中的日期类。
使用java.time包(Java 8+推荐)
Java 8引入了全新的java.time包,提供了更现代、更线程安全的日期时间API,其中LocalDate类表示不带时区的日期,而DayOfWeek枚举则专门用于表示星期几。
核心方法:
LocalDate.now():获取当前日期。LocalDate.of(year, month, day):创建指定日期。getDayOfWeek():返回DayOfWeek枚举值,包含丰富的方法(如getValue()返回1-7,getDisplayName()本地化名称)。
示例代码:
import java.time.DayOfWeek;
import java.time.LocalDate;
import java.time.format.TextStyle;
import java.util.Locale;
public class Java8TimeExample {
public static void main(String[] args) {
// 获取当前日期的星期几
LocalDate today = LocalDate.now();
DayOfWeek dayOfWeek = today.getDayOfWeek();
// 获取星期几的数值(1=星期一,7=星期日,注意与Calendar不同)
int dayValue = dayOfWeek.getValue();
System.out.println("今天是星期" + dayValue);
// 获取本地化的星期名称
String weekName = dayOfWeek.getDisplayName(TextStyle.FULL, Locale.CHINA);
System.out.println("今天是:" + weekName);
// 处理指定日期
LocalDate specificDate = LocalDate.of(2023, 10, 1);
DayOfWeek specificDay = specificDate.getDayOfWeek();
System.out.println("2023年10月1日是:" + specificDay.getDisplayName(TextStyle.SHORT, Locale.CHINA));
}
}
优势分析:

- 线程安全:所有
java.time类都是不可变且线程安全的。 - API设计直观:
DayOfWeek枚举提供了清晰的常量和方法,避免了数值混淆。 - 支持本地化:通过
getDisplayName()方法可以轻松获取不同语言的星期名称。 - 功能丰富:支持日期计算、时区处理等高级功能。
性能与适用场景对比
| 方法 | 线程安全 | 易用性 | 功能丰富度 | 适用场景 |
|---|---|---|---|---|
| Calendar | 否 | 较低 | 中等 | 遗留系统维护,Java 7及以下 |
| SimpleDateFormat | 否 | 中等 | 较低 | 简单日期格式化,单线程环境 |
| java.time (LocalDate) | 是 | 高 | 高 | 新项目开发,Java 8及以上版本 |
推荐选择:
- 对于新项目或使用Java 8及以上版本的开发,优先选择
java.time包,其设计更符合现代编程需求,且能有效避免线程安全问题。 - 维护旧项目时,若无法升级Java版本,需注意
Calendar和SimpleDateFormat的线程安全问题,可通过局部变量或同步机制规避风险。
常见问题与解决方案
-
星期几的数值差异
Calendar中星期日为1,而LocalDate的DayOfWeek中星期一为1,需根据具体API调整逻辑。 -
国际化处理
若需支持多语言,java.time的getDisplayName()方法提供了更灵活的本地化支持,而旧版API需手动维护语言资源。 -
日期计算
若需计算某日期的前后星期几(如“下个周一”),java.time的plusWeeks()和with(TemporalAdjuster)方法更为便捷。
Java中判断星期几的方法经历了从传统API到现代API的演进,开发者应根据项目需求、Java版本和团队熟悉度选择合适的技术方案,在条件允许的情况下,推荐使用java.time包,其优秀的线程安全性和丰富的功能能够显著提升开发效率和代码质量,通过理解各类API的特点和注意事项,可以更好地避免潜在陷阱,写出健壮且可维护的日期处理代码。


















