日期Date格式判断

在一般的WEB编程中,经常会碰到字符串形式的日期,需要将这个日期转化为Date对象来使用或是存储。这是一个比较常用的功能,我们有必要将它抽取出来做成一个小工具,以备后需!

我在这里说的只是日期Date,不包括时间Time YYYY-MM-DD



private static final String DATESTRING_CONTAINS_1 = "-";
private static final String DATESTRING_CONTAINS_2 = "/";
private static final String DATESTRING_CONTAINS_3 = ":";

/** *//**
* 判断该字符串是否为正确格式的时间
* YYYY-MM-DD YYYY:MM:DD YYYY/MM/dd
* 注意加入对于月份和天数的判断还有闰年 比如2月28日
* @param dateString
* @return
*/
public static boolean isRightDateFormat(String dateString) ...{

String delimer = "";
if (StringUtils.containsString(dateString, StringUtils.DATESTRING_CONTAINS_1)) ...{
delimer = StringUtils.DATESTRING_CONTAINS_1;
return dateFormatHelper(dateString, delimer);
}

if (StringUtils.containsString(dateString, StringUtils.DATESTRING_CONTAINS_2)) ...{
delimer = StringUtils.DATESTRING_CONTAINS_2;
return dateFormatHelper(dateString, delimer);
}

if (StringUtils.containsString(dateString, StringUtils.DATESTRING_CONTAINS_3)) ...{
delimer = StringUtils.DATESTRING_CONTAINS_3;
return dateFormatHelper(dateString, delimer);
}

return false;
}

//date判断辅助类
private static boolean dateFormatHelper(String dateString, String delimer) ...{
String [] tempSplits = new String[3];
try ...{
if (StringUtils.containsString(dateString, delimer)) ...{
tempSplits = dateString.split(delimer);
if ((Integer.parseInt(tempSplits[0])>=0 && Integer.parseInt(tempSplits[0]) <=3000)
&& (Integer.parseInt(tempSplits[1]) >=1 && Integer.parseInt(tempSplits[1]) <=12)
&& (Integer.parseInt(tempSplits[2]) >=1 && Integer.parseInt(tempSplits[2]) <=31)) ...{
//获得当前月份 如果是 4 6 9 11月份则应该是30天
int tmpMonth = Integer.parseInt(tempSplits[1]);
int tmpDate = Integer.parseInt(tempSplits[2]);
int tmpYear = Integer.parseInt(tempSplits[0]);

if(tmpMonth == 4
|| tmpMonth == 6
|| tmpMonth == 9
|| tmpMonth == 11) ...{
if (tmpDate > 30) ...{
return false;
}
} else if (tmpMonth == 2) ...{
//对于2月份天数的判断
if (tmpYear%4 == 0) ...{
if (tmpDate > 29) ...{
return false;
}
} else ...{
if (tmpDate > 28) ...{
return false;
}
}
}
return true;
} else ...{
return false;
}
}
} catch (NumberFormatException e) ...{
// TODO Auto-generated catch block
return false;
}
return false;
}

/** *//**
* 通过dateString得到Date对象
* DateString的格式必须为 YYYY-MM-DD YYYY:MM:DD YYYY/MM/dd
*
* @param dateString
* @return
*/
public static Date getDateByString(String dateString) ...{
//
// if (!isRightDateFormat(dateString)) {
// return null;
// }

Date retDate = null;
SimpleDateFormat sdf = new SimpleDateFormat();

if (StringUtils.containsString(dateString, StringUtils.DATESTRING_CONTAINS_1)) ...{
sdf.applyPattern("yyyy-MM-dd");
}

if (StringUtils.containsString(dateString, StringUtils.DATESTRING_CONTAINS_2)) ...{
sdf.applyPattern("yyyy/MM/dd");
}

if (StringUtils.containsString(dateString, StringUtils.DATESTRING_CONTAINS_3)) ...{
sdf.applyPattern("yyyy:MM:dd");
}

try ...{
retDate = sdf.parse(dateString);
} catch (ParseException e) ...{
retDate = null;
}
return retDate;
}
在这里还对闰年,闰月,30天的月份进行了判断

使用:可以先调用isRightDateFormat方法判断字符串是否正确格式,再调用getDateByString获得Date对象

或者直接调用getDateByString方法,但要将其中注释掉的那两行添上
### 日期范围重叠判断的实现 在处理多个日期范围时,判断是否存在重叠是常见的需求,尤其是在日程安排、会议预定等场景下。为了实现这一功能,可以将日期范围表示为包含起始时间和结束时间的区间,并通过比较这些区间的交集来判断是否存在重叠。 在 Java 中,可以使用 `java.util.Date` 或 `java.time.LocalDate` 来表示日期,并通过比较两个日期范围的起始和结束值来判断它们是否重叠。以下是一个基于 `LocalDate` 的实现方法: ```java import java.time.LocalDate; import java.util.ArrayList; import java.util.List; public class DateRangeOverlapChecker { public static boolean isOverlapping(LocalDate start1, LocalDate end1, LocalDate start2, LocalDate end2) { return start1.isBefore(end2) && start2.isBefore(end1); } public static boolean hasOverlap(List<LocalDate[]> ranges) { for (int i = 0; i < ranges.size(); i++) { for (int j = i + 1; j < ranges.size(); j++) { LocalDate[] range1 = ranges.get(i); LocalDate[] range2 = ranges.get(j); if (isOverlapping(range1[0], range1[1], range2[0], range2[1])) { return true; } } } return false; } public static void main(String[] args) { List<LocalDate[]> ranges = new ArrayList<>(); ranges.add(new LocalDate[]{LocalDate.of(2023, 10, 1), LocalDate.of(2023, 10, 5)}); ranges.add(new LocalDate[]{LocalDate.of(2023, 10, 8), LocalDate.of(2023, 10, 10)}); ranges.add(new LocalDate[]{LocalDate.of(2023, 10, 5), LocalDate.of(2023, 10, 8)}); boolean overlapExists = hasOverlap(ranges); System.out.println("是否存在重叠: " + overlapExists); } } ``` 上述代码中,`isOverlapping` 方法用于判断两个日期范围是否重叠,其逻辑基于以下条件: - 如果第一个范围的开始日期早于第二个范围的结束日期,并且第二个范围的开始日期早于第一个范围的结束日期,则两个范围存在重叠[^3]。 `hasOverlap` 方法则遍历所有日期范围对,调用 `isOverlapping` 方法来判断是否存在任意两个范围的重叠。如果存在,则返回 `true`,否则返回 `false`。 ### 使用 `LocalDate` 的优势 使用 `java.time.LocalDate` 而不是 `java.util.Date` 有以下优势: - `LocalDate` 是不可变的,线程安全的。 - `LocalDate` 提供了更直观的日期操作方法,如 `isBefore` 和 `isAfter`。 - `LocalDate` 支持 ISO 8601 标准日期格式,避免了格式化和解析的复杂性[^2]。 ### 处理 `Date` 格式日期范围 如果使用 `java.util.Date`,可以使用 `compareTo` 方法来比较日期的先后顺序。以下是一个基于 `Date` 的实现示例: ```java import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Date; import java.util.List; public class DateRangeOverlapCheckerWithDate { public static boolean isOverlapping(Date start1, Date end1, Date start2, Date end2) { return start1.before(end2) && start2.before(end1); } public static boolean hasOverlap(List<Date[]> ranges) { for (int i = 0; i < ranges.size(); i++) { for (int j = i + 1; j < ranges.size(); j++) { Date[] range1 = ranges.get(i); Date[] range2 = ranges.get(j); if (isOverlapping(range1[0], range1[1], range2[0], range2[1])) { return true; } } } return false; } public static void main(String[] args) throws Exception { SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); List<Date[]> ranges = new ArrayList<>(); ranges.add(new Date[]{sdf.parse("2023-10-01"), sdf.parse("2023-10-05")}); ranges.add(new Date[]{sdf.parse("2023-10-08"), sdf.parse("2023-10-10")}); ranges.add(new Date[]{sdf.parse("2023-10-05"), sdf.parse("2023-10-08")}); boolean overlapExists = hasOverlap(ranges); System.out.println("是否存在重叠: " + overlapExists); } } ``` 该实现与 `LocalDate` 版本类似,但使用了 `Date` 类和 `SimpleDateFormat` 进行日期解析和格式化。`isOverlapping` 方法通过 `before` 方法判断日期的先后顺序[^2]。 ### 优化思路 - **排序优化**:如果日期范围已经按起始日期排序,可以使用线性扫描的方法来判断是否存在重叠,时间复杂度为 $ O(n) $。 - **区间树**:对于大规模的日期范围管理,可以使用区间树(Interval Tree)来高效处理插入、删除和查询操作,时间复杂度为 $ O(\log n) $。 - **线段树**:线段树(Segment Tree)也可以用于处理区间问题,尤其适合需要频繁更新和查询的场景[^4]。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值