输入日期格式和日期字符串,实现返回yyyy-MM-dd格式的日期。
YYYY,YY ,DD,WW 自由组合。
YYYY,YY ,MM 自由组合。
最后返回yyyy-MM-dd格式的日期
前提条件是 日期格式和日期字符串配备才可以。
比如:
日期格式:"DD/MM/YYYY" ; 日期字符串 : "21112024" ; 返回 2024-21-11
日期格式:"YYWW" ; 日期字符串 : "2250"
日期格式:"yyMMdd" ; 日期字符串 : "221224"
这样的。
实现代码
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeParseException;
import java.time.temporal.TemporalAdjusters;
import java.util.Date;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;
public class DateFormatConvert {
public static LocalDate formatDatetime(String dtStr, String format, int weekRule) throws Exception {
LocalDate date = LocalDate.now();
try {
// Map to store the extracted date components
Map<String, String> dateComponents = new HashMap<>();
String dateStr = dtStr;
String formatStr = format.replace("/", "").toUpperCase();
dtStr = dtStr.replace("/", "");
int year = 0;int month = 0;int day = 0;
// Handle special case for 'D' at the beginning
if (dtStr.startsWith("D")) {
//format = format.substring(1);
dtStr = dtStr.substring(1);
}
if(format.equalsIgnoreCase("YYYY-MM-DD")){
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
try {
LocalDate localDate = LocalDate.parse(dtStr, formatter);
System.out.println("The date string is valid: " + localDate);
return localDate;
} catch (DateTimeParseException e) {
System.out.println("The date string is invalid: " + e.getMessage());
throw new Exception("Format(" + format + ") and DateCode( " + dtStr + " ) do not match ");
}
}
if(formatStr.length() != dtStr.length()){
throw new Exception("Format and DateCode do not match ");
}
// Extract date components based on the format
if (formatStr.contains("YYYY")) {
int yyyy = formatStr.indexOf("YYYY");
dateComponents.put("year", dtStr.substring(yyyy, yyyy+4));
year = Integer.parseInt(dtStr.substring(yyyy, yyyy+4));
} else if (formatStr.contains("YY")) {
int yy = formatStr.indexOf("YY");
String yearStr = "20" + dtStr.substring(yy, yy+2);
year = Integer.parseInt(yearStr); // Convert YY to YYYY
dateComponents.put("year", yearStr);
}
if (formatStr.contains("MM")) {
int mm = formatStr.indexOf("MM");
month = Integer.parseInt(dtStr.substring(mm, mm+2));
dateComponents.put("month", dtStr.substring(mm, mm+2));
}
if (formatStr.contains("DD")) {
int dd = formatStr.indexOf("DD");
day = Integer.parseInt(dtStr.substring(dd, dd+2));
dateComponents.put("day", dtStr.substring(dd, dd+2));
} else if (formatStr.contains("D")) {
// Remaining 'D' case, should be handled last
int d = formatStr.indexOf("D");
day = Integer.parseInt("0" + dtStr.charAt(d));
dateComponents.put("day", String.valueOf(day)); // Only one digit day
}
// Handle week number (WW) if present 算法规则: 1月1日是星期一则为第一周,不是后一周为第一周。
if (formatStr.contains("WW") && weekRule == 0) {
int ww = formatStr.indexOf("WW");
String week = dtStr.substring(ww, ww+2);
dateComponents.put("week", week);
int weekNumber = Integer.parseInt(week);
// 验证周数是否在有效范围内
if (weekNumber < 1 || weekNumber > 53) {
throw new Exception("week in 1-53 !!!");
}
if(year != 0){
date = date.withYear(year);
}
LocalDate firstDayOfYear = date.withDayOfYear(1);
//从第一周的星期一开始算起。
LocalDate dateOfWeek = firstDayOfYear.with(TemporalAdjusters.nextOrSame(java.time.DayOfWeek.MONDAY))
.plusWeeks(weekNumber - 1);
// Adjust year if the calculated date falls in the next year due to week number being late in the year
if (dateOfWeek.getYear() != date.getYear()) {
date = dateOfWeek.withYear(date.getYear());
if (date.isAfter(dateOfWeek)) {
date = dateOfWeek;
System.out.println(" 三 1 该周的开始日期是: " + date.format(DateTimeFormatter.ofPattern("yyyy-MM-dd")));
} else {
LocalDate correctDate = LocalDate.of(date.getYear(), 1, 1)
.with(TemporalAdjusters.nextOrSame(java.time.DayOfWeek.MONDAY))
.plusWeeks(weekNumber - 1);
date = correctDate;
System.out.println(" 三 2 该周的开始日期是: " + date.format(DateTimeFormatter.ofPattern("yyyy-MM-dd")));
}
} else {
date = dateOfWeek;
}
System.out.println(" 三 3 该周的开始日期是: " + date.format(DateTimeFormatter.ofPattern("yyyy-MM-dd")));
return LocalDate.parse(date.format(DateTimeFormatter.ofPattern("yyyy-MM-dd")));
}
//算法规则: 如果第一个星期四不在第一周,我们需要回退到前一周的星期四
if(formatStr.contains("WW") && weekRule == 1){
int ww = formatStr.indexOf("WW");
String week = dtStr.substring(ww, ww+2);
dateComponents.put("week", week);
int weekNumber = Integer.parseInt(week);
// 验证周数是否在有效范围内
if (weekNumber < 1 || weekNumber > 53) {
throw new Exception("week in 1-53 !!!");
}
if(year != 0){
date = date.withYear(year);
}
// 获取ISO周字段(考虑周一为一周的第一天)
//WeekFields weekFields = WeekFields.of(Locale.getDefault()); // 1表示周一为一周的第一天
WeekFields weekFields = WeekFields.of(DayOfWeek.MONDAY,1); // 1表示周一为一周的第一天
// 由于我们不知道第一周的确切日期,我们需要找到该年的第一个星期四(ISO 8601标准)
// 然后我们可以计算出第一周的起始日期
LocalDate firstThursdayOfYear = LocalDate.of(year, 1, 1)
.with(ChronoField.ALIGNED_WEEK_OF_MONTH, 1) // 这通常会给我们1月的第一周,但不一定是ISO周
.with(TemporalAdjusters.nextOrSame(java.time.DayOfWeek.THURSDAY)); // 找到第一个星期四
// 如果第一个星期四不在第一周,我们需要回退到前一周的星期四
LocalDate firstWeekStart = firstThursdayOfYear;
if (firstThursdayOfYear.get(weekFields.weekOfWeekBasedYear()) != 1) {
firstWeekStart = firstThursdayOfYear.minusWeeks(1).with(TemporalAdjusters.previousOrSame(java.time.DayOfWeek.THURSDAY));
}
// 现在我们知道第一周的起始日期,我们可以加上所需的周数来找到目标日期
//int weekNumber = Integer.parseInt(ww);
LocalDate targetDate = firstWeekStart.plusWeeks(weekNumber - 1); // 减1是因为我们已经有了第一周的起始日期
// 格式化输出日期
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
System.out.println(" 五 该周的开始日期是: " + targetDate.format(formatter));
return LocalDate.parse(targetDate.format(formatter));
}
// Format the final date
String formattedDate = String.format("%s-%s-%s",
dateComponents.getOrDefault("year", "2024"),
dateComponents.getOrDefault("month", "01"),
dateComponents.getOrDefault("day", "01"));
// Validate the formatted date (optional, for robustness)
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
LocalDate dt = LocalDate.parse(formattedDate, formatter);
System.out.println(" TEST 该周的开始日期是: " + dt);
return dt;
} catch (ParseException e) {
throw new Exception(e.getMessage()); // Or handle the error appropriately
}catch (Exception ex) {
throw new Exception(ex.getMessage());
}
}
}