
本教程旨在解决在java应用中将用户选择的周数和年份转换为对应的周起始日期和结束日期的问题。文章将深入分析传统`java.util.date` api的局限性,并详细介绍如何利用现代`java.time` api(java 8及更高版本)进行精确、可靠的日期转换,包括示例代码和在jsp/servlet环境中的应用,以实现报表过滤等功能。
在Web应用中,尤其是在报表或数据过滤场景下,用户常常需要根据“周”来筛选数据。例如,用户可能选择某个年份和一年中的某个周数(如第1周、第52周),系统需要据此计算出该周的精确起始日期和结束日期,进而用于数据库查询或页面展示。
原始代码示例中,尝试使用java.util.Date、SimpleDateFormat和Calendar类来处理日期。这些是Java早期提供的日期时间API,但它们存在诸多问题:
鉴于这些局限性,强烈建议在Java 8及更高版本中采用java.time包下的现代日期时间API。
java.time API是JSR-310的实现,提供了更简洁、更强大、更可靠的日期时间处理能力。它引入了不可变对象、明确的日期时间概念(如LocalDate、LocalTime、LocalDateTime、ZonedDateTime)以及清晰的API设计。
立即学习“Java免费学习笔记(深入)”;
对于将周数和年份转换为起始日期和结束日期的问题,我们可以利用LocalDate和WeekFields类。WeekFields允许我们定义一周的起始日(例如,周日或周一)以及一年中第一周的定义(例如,包含1月1日的第一周)。
WeekFields是一个关键类,它定义了日历系统中周的特性。常见的定义包括:
根据问题描述“1st jan = 1, 25th dec = 52”,这表明第一周包含1月1日,这与美国地区(Locale.US)的周定义更为接近。
以下Java代码演示了如何将给定的年份和周数转换为该周的起始日期和结束日期:
import java.time.DayOfWeek;
import java.time.LocalDate;
import java.time.temporal.WeekFields;
import java.util.Locale;
public class WeekDateConverter {
/**
* 根据年份和周数,计算该周的起始日期和结束日期。
*
* @param year 年份
* @param weekNumber 周数 (通常为1-52或53)
* @param locale 用于定义周起始日和第一周规则的Locale
* @return 包含起始日期和结束日期的String数组,格式为{"YYYY-MM-DD", "YYYY-MM-DD"}
*/
public static String[] getWeekStartAndEndDate(int year, int weekNumber, Locale locale) {
// 获取指定Locale的周定义
WeekFields weekFields = WeekFields.of(locale);
// 获取该年的第一天
LocalDate firstDayOfYear = LocalDate.of(year, 1, 1);
// 将日期调整到目标周的任意一天
// 这里使用 with(weekFields.weekOfYear(), weekNumber) 直接设置周数
// 注意:这种方式在某些极端情况下(如年末年初的跨年周)可能需要额外调整,
// 但对于大多数标准周定义是有效的。
LocalDate dateInTargetWeek = firstDayOfYear.with(weekFields.weekOfYear(), weekNumber);
// 找到该周的起始日期
// weekFields.getFirstDayOfWeek() 返回该Locale定义的一周的第一天(如SUNDAY或MONDAY)
LocalDate startDate = dateInTargetWeek.with(weekFields.dayOfWeek(), weekFields.getFirstDayOfWeek().getValue());
// 计算该周的结束日期 (起始日期 + 6天)
LocalDate endDate = startDate.plusDays(6);
return new String[]{startDate.toString(), endDate.toString()};
}
public static void main(String[] args) {
int year = 2023;
// 示例1: 获取2023年第1周的起始日期和结束日期 (使用Locale.US)
int week1 = 1;
String[] dates1 = getWeekStartAndEndDate(year, week1, Locale.US);
System.out.println("Year: " + year + ", Week: " + week1 + " (Locale.US)");
System.out.println(" Start Date: " + dates1[0]);
System.out.println(" End Date: " + dates1[1]);
// 预期输出 (2023年1月1日是周日,所以第1周是1月1日-1月7日)
// Start Date: 2023-01-01
// End Date: 2023-01-07
System.out.println("--------------------");
// 示例2: 获取2023年第52周的起始日期和结束日期 (使用Locale.US)
// 根据问题描述,12月25日(圣诞节)通常在第52周
int week52 = 52;
String[] dates52 = getWeekStartAndEndDate(year, week52, Locale.US);
System.out.println("Year: " + year + ", Week: " + week52 + " (Locale.US)");
System.out.println(" Start Date: " + dates52[0]);
System.out.println(" End Date: " + dates52[1]);
// 预期输出 (2023年第52周包含12月25日,起始日是周日)
// Start Date: 2023-12-24
// End Date: 2023-12-30
System.out.println("--------------------");
// 示例3: 使用ISO周定义 (一周从周一开始,第一周包含第一个星期四)
int yearISO = 2023;
int weekISO = 1;
String[] datesISO = getWeekStartAndEndDate(yearISO, weekISO, Locale.forLanguageTag("en-GB")); // 英国通常使用ISO周定义
System.out.println("Year: " + yearISO + ", Week: " + weekISO + " (ISO-like, en-GB)");
System.out.println(" Start Date: " + datesISO[0]);
System.out.println(" End Date: " + datesISO[1]);
// 预期输出 (2023年1月1日是周日,所以ISO第一周从2023-01-02开始)
// Start Date: 2023-01-02
// End Date: 2023-01-08
}
}在JSP页面中,用户通过
JSP (report.jsp) 片段优化:
<%-- 假设weekNum数组的索引k就是周数,从1开始 --%>
<div class='grid_3' id='hidden_div' style='display:none;'>
<p>
<select name='weekNumber' id='weekNumber' style='width:150px;' multiple='multiple' >
<%
// weekDates 数组用于显示,weekNum 数组的索引 k 作为实际的周数值
String weekDates[]={"01-02","01-09","01-16","01-23","01-30","02-06","02-13","02-20","02-27",
"03-06","03-13","03-20","03-27","04-03","04-10","04-17","04-24","05-01","05-08",
"05-15","05-22","05-29","06-05","06-12","06-19","06-26","07-03","07-10","07-17","07-24",
"07-31","08-07","08-14","08-21","08-28","09-04","09-11","09-18","09-25","10-02","10-09","10-16",
"10-23","10-30","11-06","11-13","11-20","11-27","12-04","12-11","12-18","12-25"};
// 假设 weekDates 数组的长度是 52,并且索引 k 对应第 k 周
// 修正循环,确保k从1开始且不越界
for (int k = 1; k <= weekDates.length; k++){
// option value 应该是实际的周数 k
// option text 可以是 weekDates[k-1] (因为数组是0索引) 或者显示周数 k
out.println("<option value =\"" + k + "\">Week " + k + " (" + weekDates[k-1] + ")</option>");
}
%>
</select>
</p>
<p>
<label>Year</label>
<select name='year' id='year' class='mediumSelect'>
<%
String currentYearStr = java.time.Year.now().toString(); // 使用java.time.Year获取当前年份
int currentYear = Integer.parseInt(currentYearStr);
for(int years=2020; years < (currentYear + 5); years++) {
if(currentYear == years){
out.println("<option value='"+years+"' selected>"+ years +"</option>");
}else{
out.println("<option value='"+years+"'>"+ years +"</option>");
}
}
%>
</select>
</p>
</div>Servlet/Action Page (report_act.jsp) 片段优化:
在服务器端的处理逻辑中,获取用户选择的年份和周数,然后调用WeekDateConverter类的方法来计算起始日期和结束日期。
// 获取请求参数
String[] selectedWeekNumbersStr = request.getParameterValues("weekNumber"); // 如果是多选
String yearStr = request.getParameter("year");
if (selectedWeekNumbersStr != null && selectedWeekNumbersStr.length > 0 && yearStr != null) {
int year = Integer.parseInt(yearStr);
// 假设我们只处理第一个选中的周数,或者遍历所有选中的周数
int weekNumber = Integer.parseInt(selectedWeekNumbersStr[0]); // 获取第一个选中的周数
// 使用我们定义的转换方法,这里使用Locale.US作为示例
String[] dates = WeekDateConverter.getWeekStartAndEndDate(year, weekNumber, Locale.US);
String startDate = dates[0];
String endDate = dates[1];
// LogFunction.loginfo("Start Date: " + startDate + ", End Date: " + endDate);
// 重定向到报告页面,传递计算出的起始和结束日期
response.sendRedirect(""+namePage+".jsp?millId="+millId+"&stationStatus="+stationStatus+"&inspectorId="+inspectorId+"&roundIdList="+roundIdList+"&reportType="+reportType+"&jobPosition="+jobPosition+"&scheduleId="+scheduleId+"&filterType="+filterType+"&weekNumber="+weekNumber+"&startDate="+startDate+"&endDate="+endDate+"&roundId="+roundId+"&stationId="+stationId+"&sequenceId="+sequenceId+"&pageNo="+pageNo+"");
} else {
// 处理错误或未选择周数的情况
// ...
}以上就是Java中周数到起始日期与结束日期的转换教程(基于java.time API)的详细内容,更多请关注php中文网其它相关文章!
java怎么学习?java怎么入门?java在哪学?java怎么学才快?不用担心,这里为大家提供了java速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号