JAVA各种时间类型的取得

本文详细介绍了Java中日期处理的相关方法,包括获取当前时间、格式化日期、时间差计算等常用操作,并通过实例展示了如何灵活运用这些方法解决实际问题。
package com.hello.test;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.Locale;
import java.util.MissingResourceException;
import java.util.ResourceBundle;

import org.apache.log4j.Logger;

public class DateUtil {

	private static Logger log = Logger.getLogger(DateUtil.class);

	private static String defaultDatePattern = null;

	private static String timePattern = "HH:mm";

	public static Date getSystemTime() {
		Calendar now = Calendar.getInstance();
		return now.getTime();

	}

	public static synchronized String getDatePattern() {
		Locale locale = Locale.CHINA; // LocaleContextHolder.getLocale();

		try {
			defaultDatePattern = ResourceBundle.getBundle("yyyy-MM-dd", locale).getString("date.format");
		} catch (MissingResourceException mse) {
			defaultDatePattern = "yyyy-MM-dd";
		}

		return defaultDatePattern;
	}

	public static final String getDate(Date aDate) {
		SimpleDateFormat df = null;
		String returnValue = "";

		if (aDate != null) {
			df = new SimpleDateFormat(getDatePattern());
			returnValue = df.format(aDate);
		}

		return (returnValue);
	}

	public static final Date convertStringToDate(String aMask, String strDate) {
		SimpleDateFormat df = null;
		Date date = null;
		df = new SimpleDateFormat(aMask);

		if (log.isDebugEnabled()) {
			log.debug("converting '" + strDate + "' to date with mask '" + aMask + "'");
		}

		try {
			date = df.parse(strDate);
		} catch (ParseException pe) {
			log.error("ParseException: " + pe);
		}

		return (date);
	}

	public static String getTimeNow(Date theTime) {
		return getDateTime(timePattern, theTime);
	}

	public static Calendar getToday() throws ParseException {
		Date today = new Date();
		SimpleDateFormat df = new SimpleDateFormat(getDatePattern());

		// This seems like quite a hack (date -> string -> date),
		// but it works ;-)
		String todayAsString = df.format(today);
		Calendar cal = new GregorianCalendar();
		cal.setTime(convertStringToDate(todayAsString));

		return cal;
	}

	public static Date getMonday(Date date) {
		Calendar c = Calendar.getInstance();
		c.setTime(date);
		if (c.get(Calendar.DAY_OF_WEEK) == 1) {
			date = DateUtil.addDays(date, -7);
			c.setTime(date);
		}

		c.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY);
		String mondayString = DateUtil.format(c.getTime(), "yyyy-MM-dd");
		mondayString = mondayString + " 00:00:00";
		return convertStringToDate("yyyy-MM-dd HH:mm:ss", mondayString);
	}

	public static Date getFriday(Date date) {
		Calendar c = Calendar.getInstance();
		c.setTime(date);
		c.set(Calendar.DAY_OF_WEEK, Calendar.FRIDAY);
		String fridayString = format(c.getTime(), "yyyy-MM-dd");
		fridayString = fridayString + " 23:59:59";
		return convertStringToDate("yyyy-MM-dd HH:mm:ss", fridayString);

	}

	public static final String getDateTime(String aMask, Date aDate) {
		SimpleDateFormat df = null;
		String returnValue = "";

		if (aDate == null) {
			log.error("aDate is null!");
		} else {
			df = new SimpleDateFormat(aMask);
			returnValue = df.format(aDate);
		}

		return (returnValue);
	}

	public static final String convertDateToString(Date aDate) {
		return getDateTime(getDatePattern(), aDate);
	}

	public static Date convertStringToDate(String strDate) {
		Date aDate = null;

		try {
			if (log.isDebugEnabled()) {
				log.debug("converting date with pattern: " + getDatePattern());
			}

			aDate = convertStringToDate(getDatePattern(), strDate);
		} catch (Exception pe) {
			log.error("Could not convert '" + strDate + "' to a date, throwing exception");

		}

		return aDate;
	}

	public static int dayDiff(Date first, Date second) {

		long msPerDay = 1000 * 60 * 60 * 24;
		long diff = (first.getTime() / msPerDay) - (second.getTime() / msPerDay);

		Long convertLong = new Long(diff);
		return convertLong.intValue();
	}

	public static long dayDiffMilSecond(Date first, Date second) {

		long diff = first.getTime() - second.getTime();
		Long convertLong = new Long(diff);
		return convertLong;
	}

	public static String format(Date date, String pattern) {
		if (date == null)
			return "";
		SimpleDateFormat formatter = new SimpleDateFormat(pattern);
		return formatter.format(date);
	}

	static public final Date addDays(Date target, int days) {
		long msPerDay = 1000 * 60 * 60 * 24; // 一天的毫秒数
		long msTarget = target.getTime(); // 返回从一个特定的日期(1970。。)到现在经过的毫秒数。
		long msSum = msTarget + (msPerDay * days);
		Date result = new Date();
		result.setTime(msSum); // 根据毫秒设置日期
		return result;
	}

	public static Date beforeDays(Date target, int days) {
		long msPerDay = 1000 * 60 * 60 * 24; // 一天的毫秒数
		long msTarget = target.getTime(); // 返回从一个特定的日期(1970。。)到现在经过的毫秒数。
		long msSum = msTarget - (msPerDay * days);
		Date result = new Date();
		result.setTime(msSum); // 根据毫秒设置日期
		return result;
	}

	public static Date formatString(String time, String format) {
		try {
			SimpleDateFormat formater = new SimpleDateFormat(format);
			return formater.parse(time);
		} catch (Exception e) {
			return null;
		}
	}

	public static Date getFirstDateOfMonth(Date date) {
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(date);
		calendar.set(Calendar.DAY_OF_MONTH, 1);
		calendar.set(Calendar.HOUR_OF_DAY, 0);
		calendar.set(Calendar.MINUTE, 0);
		calendar.set(Calendar.SECOND, 0);
		return calendar.getTime();
	}

	public static Date getLastlyDateOfMonth(Date date) {
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(date);
		int month = calendar.get(Calendar.MONTH);
		calendar.set(Calendar.MONTH, month + 1);
		calendar.set(Calendar.DAY_OF_MONTH, 1);
		calendar.set(Calendar.HOUR_OF_DAY, 23);
		calendar.set(Calendar.MINUTE, 59);
		calendar.set(Calendar.SECOND, 59);
		calendar.add(Calendar.DAY_OF_MONTH, -1);
		return calendar.getTime();
	}

	public static Date getFirstDateOfNextMonth(Date date) {
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(date);
		int month = calendar.get(Calendar.MONTH);
		calendar.set(Calendar.MONTH, month + 1);
		calendar.set(Calendar.DAY_OF_MONTH, 1);
		calendar.set(Calendar.HOUR_OF_DAY, 0);
		calendar.set(Calendar.MINUTE, 0);
		calendar.set(Calendar.SECOND, 0);
		return calendar.getTime();

	}

	public static String getCurrentDayPath() {
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy");
		Date now = new Date();
		String filePath = sdf.format(now) + "/";
		sdf = new SimpleDateFormat("MM");
		filePath += sdf.format(now) + "/";
		sdf = new SimpleDateFormat("dd");
		filePath += sdf.format(now) + "/";

		return filePath;
	}
}
 

 

<think> 我们参考上述引用,特别是引用[1][2][3][4],它们都提到了使用Java计算两个日期相减的方法。 在引用[2]中,有一个示例代码,它使用两个Date对象,然后计算它们相差的毫秒数,再转换为天、小时、分钟和秒。 但是,用户只关心天数,因此我们可以简化步骤,只计算天数。 需要注意的是,在Java中,如果使用较新的版本(Java 8及以上),推荐使用java.time包中的类(如LocalDate)来操作日期,因为java.util.Date和Calendar类存在设计缺陷。 然而,如果用户仍然在使用旧版的Date类,我们也需要提供相应的解决方案。 因此,我们可以提供两种方法: 方法1:使用传统的java.util.Date(适用于Java 7及以下) 方法2:使用java.time.LocalDate(适用于Java 8及以上) 根据引用[3]和[4],我们也可以看到推荐使用java.time包。 步骤: 1. 使用java.util.Date(传统方法): 将两个Date对象转换为时间戳(毫秒),然后相减得到毫秒差,再将毫秒差转换为天数(注意:1天=24*60*60*1000毫秒)。 注意:由于日期相减的天数可能是小数,但通常我们只需要整数天(可能根据需求是绝对值,或者包含正负),这里我们取绝对值还是保留符号?一般来说,我们取绝对值表示间隔天数,但有时可能需要知道方向(比如前多少天,后多少天)。根据用户需求,这里我们假设用户需要两个日期相差的天数(绝对值),但我们也给出有符号的计算。 2. 使用java.time.LocalDate(现代方法): 将Date对象转换为LocalDate(如果用户从Date开始),然后使用ChronoUnit.DAYS.between()方法计算两个LocalDate之间的天数差。 但是,用户给出的引用[2]中使用了DateUtils,但这里我们使用标准库。 另外,注意:使用Date计算天数差时,由于涉及到时间部分,直接按毫秒计算天数可能会因为时间部分(时、分、秒)而出现不是整天的情况。所以,如果只关心日期部分(年、月、日),则应该清除时间部分,或者使用LocalDate来忽略时间部分。 因此,我们更推荐使用LocalDate,因为它只包含日期部分。 如果用户坚持使用Date,我们可以先将其转换为LocalDate(如果使用Java8+),或者清除时间部分(设置为00:00:00)再计算。 考虑到用户的问题中指定了“Date类型”,我们提供两种方案: 方案一(Java 8及以上,推荐): 步骤: a. 将Date转换为Instant,然后转换为LocalDate(使用时区,一般用系统默认时区) b. 使用ChronoUnit.DAYS.between(startDate, endDate)计算天数差 方案二(适用于旧版Java): 使用Calendar类来设置时间到同一天的开始时间(清除时间部分),然后计算两个Date的毫秒差,再除以一天的毫秒数。 但是,由于时区、夏令时等问题,用毫秒数计算天数可能不准确。所以,更可靠的方法是使用Calendar设置到同一天的0点,然后计算两个0点之间的天数差。 由于问题复杂,我们给出两种方案,并说明其优缺点。 根据引用[4],我们也可以看出,使用java.time包是更优的选择。 因此,我们首先推荐使用Java 8的java.time包。 代码示例: 方法1:使用Java 8的java.time包 ```java import java.time.Instant; import java.time.LocalDate; import java.time.ZoneId; import java.time.temporal.ChronoUnit; import java.util.Date; public class DateDifferenceExample { public static long getDaysBetween(Date startDate, Date endDate) { // 将Date转换为LocalDate LocalDate start = startDate.toInstant().atZone(ZoneId.systemDefault()).toLocalDate(); LocalDate end = endDate.toInstant().atZone(ZoneId.systemDefault()).toLocalDate(); // 计算两个LocalDate之间的天数差 return ChronoUnit.DAYS.between(start, end); } } ``` 注意:返回的天数差可能是负数(如果endDate在startDate之前)。如果需要绝对值,可以取绝对值。 方法2:使用旧版Java(使用Calendar清除时间部分) ```java import java.util.Calendar; import java.util.Date; public class DateDifferenceExample { public static long getDaysBetween(Date startDate, Date endDate) { // 将两个日期的时间部分都设置为0:00:00 Calendar cal1 = Calendar.getInstance(); cal1.setTime(startDate); cal1.set(Calendar.HOUR_OF_DAY, 0); cal1.set(Calendar.MINUTE, 0); cal1.set(Calendar.SECOND, 0); cal1.set(Calendar.MILLISECOND, 0); Calendar cal2 = Calendar.getInstance(); cal2.setTime(endDate); cal2.set(Calendar.HOUR_OF_DAY, 0); cal2.set(Calendar.MINUTE, 0); cal2.set(Calendar.SECOND, 0); cal2.set(Calendar.MILLISECOND, 0); // 计算两个时间的毫秒差 long diffMillis = cal2.getTimeInMillis() - cal1.getTimeInMillis(); // 转换为天数 return diffMillis / (24 * 60 * 60 * 1000); } } ``` 注意:这种方法也是返回有符号的差值,即如果endDate在startDate之前,返回负数。同样,除以一天的毫秒数(86400000)得到整数天(小数部分被截断)。另外,这种方法忽略了闰秒和夏令时调整,但对于大多数应用足够。 但是,方法2在夏令时切换时可能会有一天误差,因为有些天不是完整的24小时。因此,推荐使用方法1。 总结:如果使用Java 8及以上,强烈推荐使用java.time包;如果使用旧版,可以使用Calendar方法,但要注意其局限性。 另外,引用[2]中使用了DateUtils,这是Apache Commons Lang库中的一个工具类,但用户没有要求使用第三方库,所以我们使用标准库。 因此,我们提供上述两种方法。 最后,根据引用[4]中提到的需求,用户可能只需要天数,所以我们只返回天数。 </think>在Java中计算两个`java.util.Date`类型日期的天数差,推荐以下两种方法: --- ### 方法1:使用 Java 8+ 的 `java.time` 包(推荐) ```java import java.time.Instant; import java.time.LocalDate; import java.time.ZoneId; import java.time.temporal.ChronoUnit; import java.util.Date; public class DateUtils { public static long getDaysDifference(Date date1, Date date2) { // 将Date转换为LocalDate(忽略时间部分) LocalDate localDate1 = date1.toInstant().atZone(ZoneId.systemDefault()).toLocalDate(); LocalDate localDate2 = date2.toInstant().atZone(ZoneId.systemDefault()).toLocalDate(); // 计算天数差(绝对值) return Math.abs(ChronoUnit.DAYS.between(localDate1, localDate2)); } } ``` **说明**: 1. 通过 `toInstant()` 和 `atZone()` 将 `Date` 转换为时区敏感的 `ZonedDateTime` 2. 使用 `toLocalDate()` 剥离时间部分,仅保留日期 3. `ChronoUnit.DAYS.between()` 直接计算纯日期差值 4. `Math.abs()` 保证结果为正数(若需方向性可移除) --- ### 方法2:使用旧版 `Calendar`(Java 7 及以下) ```java import java.util.Calendar; import java.util.Date; public class DateUtils { public static long getDaysDifference(Date date1, Date date2) { Calendar cal1 = Calendar.getInstance(); cal1.setTime(date1); // 重置为当天0点 cal1.set(Calendar.HOUR_OF_DAY, 0); cal1.set(Calendar.MINUTE, 0); cal1.set(Calendar.SECOND, 0); cal1.set(Calendar.MILLISECOND, 0); Calendar cal2 = Calendar.getInstance(); cal2.setTime(date2); cal2.set(Calendar.HOUR_OF_DAY, 0); cal2.set(Calendar.MINUTE, 0); cal2.set(Calendar.SECOND, 0); cal2.set(Calendar.MILLISECOND, 0); // 计算毫秒差并转换为天数 long diffMillis = Math.abs(cal2.getTimeInMillis() - cal1.getTimeInMillis()); return diffMillis / (24 * 60 * 60 * 1000); } } ``` **说明**: 1. 通过 `Calendar` 将时间统一归零到当天0点 2. 计算毫秒差后除以一天的毫秒数(24×60×60×1000=86400000) 3. 同样用 `Math.abs()` 保证正值结果 --- ### 使用示例 ```java public static void main(String[] args) { Date date1 = new Date(); // 当前时间 Date date2 = new Date(date1.getTime() - 3 * 24 * 60 * 60 * 1000); // 3天前 long daysDiff = DateUtils.getDaysDifference(date1, date2); System.out.println("相差天数: " + daysDiff); // 输出: 相差天数: 3 } ``` --- ### 关键注意事项 1. **时区处理**: - 方法1显式使用系统默认时区(`ZoneId.systemDefault()`) - 方法2隐式依赖 `Calendar` 的时区设置 - 跨时区场景需明确指定时区(如 `ZoneId.of("Asia/Shanghai")`)[^1][^3] 2. **精度问题**: - 两种方法均**忽略时间部分**(如 `2023-01-01 23:59` 和 `2023-01-02 00:01` 算作相差1天) - 若需精确到小时/分钟,需修改计算逻辑[^2] 3. **新旧API选择**: - Java 8+ 首选 `java.time` 包(线程安全且设计更合理)[^3][^4] - 遗留系统可用 `Calendar`,但需注意线程安全问题 --- ### 相关问题 1. 如何计算两个日期之间的小时差或分钟差? 2. 处理跨时区的日期计算时需要注意什么? 3. 为什么 `java.time` 包比传统的 `Date` 和 `Calendar` 更推荐使用? 4. 如何实现带方向的日期差值计算(如返回负数表示过去)? [^1]: Java计算两个日期相减 [^2]: 关于两个Date类型时间相减 [^3]: Java中计算两个日期相减 [^4]: java 两个日期如何相
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值