String类型的日期与BigDecimal类型相互转化

实际开发中的案例,需要将日期格式为String类型的"2018-11-13",然后转为BigDecimal(8,2)类型的20181113存入数据库。查询时再将数据转为String类型格式展示。

1、先定义工具类:

(如果没有传入生失效时间,这自动设置一个默认值;如果有则,不需要。)

/**
 * @Description 工具类
 * Create at: 2018年11月21日 下午4:41:54
 */
public class CommonUtils {

	private final static String HYPHEN = "-";

	
	/**
	 * 默认失效时间9999-12-31
	 */
	public static BigDecimal getDefaultInvalidTime() {
		// 获取String类型的时间
		String defaultInvalidTime = "9999-12-31";
		return strToBigDecimal(defaultInvalidTime);
	}

	/**
	 * 默认生效时间 为当前时间
	 */
	public static BigDecimal getNowDate() {
		// 我要获取当前的日期
		Date date = new Date();
		// 设置要获取到什么样的时间
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
		// 获取String类型的时间
		String createdate = sdf.format(date);
		return strToBigDecimal(createdate);
	}

	/**
	 * 生效日期,失效日期 String->BigDecimal
	 * 
	 * @param effectiveDate
	 * @return BigDecimal
	 */
	public static BigDecimal strToBigDecimal(String effectiveDate) {
		StringBuilder sb = new StringBuilder();
		String[] splitWithHyphen = effectiveDate.split(HYPHEN);
		for (String item : splitWithHyphen) {
			sb.append(item);
		}
		String newEffectiveDate = sb.toString();
		BigDecimal bd = new BigDecimal(newEffectiveDate);
		return bd;
	}

	/**
	 * 生效日期,失效日期 BigDecimal->String
	 * 
	 * @param effectiveDate
	 * @return String
	 */
	public static String bigDecimalToStr(BigDecimal effectiveDate) {
		String strEffectiveDate = effectiveDate.toString();
		StringBuilder sb = new StringBuilder();
		sb.append(strEffectiveDate);
		sb.insert(4, HYPHEN);
		sb.insert(7, HYPHEN);
		return sb.toString();
	}
}

2、调用(伪代码)

/**
*String->BigDecimal 
* 入库
*/
public void demo(Param param){
    //传入的参数param

// 设置默认生失效时间
		BigDecimal effectiveStartDate = null;
		BigDecimal effectiveEndDate = null;
		try {
			effectiveStartDate = StringUtils.isBlank(param.getEffectiveStartDate()) ? CommonUtils.getNowDate()
					: CommonUtils.strToBigDecimal(param.getEffectiveStartDate());
			effectiveEndDate = StringUtils.isBlank(param.getEffectiveEndDate()) ? CommonUtils.getDefaultInvalidTime()
					: CommonUtils.strToBigDecimal(param.getEffectiveEndDate());
		} catch (Exception e) {
			throw new ApplicationServiceException("生失效时间转换异常");
		}
}

/**
*BigDecimal ->String
* 查询展示
*/
public void demo01(Vo vo){
    // 日期转换BigDecimal->String
				vo.setEffectiveStartDateName(CommonUtils.bigDecimalToStr(vo.getEffectiveStartDate()));
				vo.setEffectiveEndDateName(CommonUtils.bigDecimalToStr(vo.getEffectiveEndDate()));
}

3、效果

效果图

 

一般都要判断失效时间-生效时间>=0 .视具体的业务来定。

<think>好的,我现在要帮用户解决关于SimpleDateFormat日期格式换的问题。首先,我需要回想用户之前的问题。之前他问过BigDecimal除以零的情况,现在日期格式化,可能是他在处理数据换时遇到了不同的问题,比如从数据库或API获取日期数据后需要格式化显示。 接下来,我需要确定用户的需求是什么。他提到“SimpleDateFormat日期格式换”,可能想知道如何使用这个类来日期格式,或者在使用过程中遇到了异常,比如线程安全问题。根据经验,SimpleDateFormat虽然不是线程安全的,但用户可能只是需要基本的用法示例。 然后,我需要考虑用户的身份。可能是Java初学者,或者有一定经验但不太熟悉日期处理的开发者。他可能在实际项目中需要将日期从一种格式为另一种,比如从"yyyy-MM-dd HH:mm:ss"成"dd/MM/yyyy"形式,或者解析字符串为Date对象。 用户可能没有明确说出的深层需求可能包括:如何处理解析时的异常,比如ParseException,或者为什么推荐使用Java 8的DateTimeFormatter替代SimpleDateFormat。此外,他可能关心时区问题,或者格式化后的字符串出现不正确的情况,比如小时数不对,这可能时区设置有关。 我需要组织回答的结构,先介绍SimpleDateFormat的基本用法,包括创建实例、格式化和解析日期。然后指出线程安全问题,并给出解决方案,比如使用局部变量或同步,最后推荐Java 8的替代方案,因为这是更现代且线程安全的方法。 还要注意示例代码的正确性,比如在格式字符串中使用正确的字母,比如“MM”代表月份,“mm”代表分钟,避免常见的错误。同时,提醒用户在解析时字符串必须格式严格匹配,否则会抛出异常。 可能用户在使用旧版Java,无法升级到Java 8,所以需要提供两种解决方案。此外,用户可能遇到的典型问题,比如多线程环境下SimpleDateFormat的并发问题,导致结果错误或异常,需要强调线程安全的重要性。 总结来说,回答需要涵盖基本用法、注意事项、线程安全问题和替代方案,确保用户能全面了解并正确应用,同时避免常见的陷阱。</think>以下是关于Java中`SimpleDateFormat`日期格式换的详细介绍和注意事项: --- ### **一、核心作用** `SimpleDateFormat` 是Java中用于**日期字符串相互换**的类,主要功能: - **格式化**:将 `Date` 对象为指定格式的字符串(如 `"2023-08-25 14:30:00"`) - **解析**:将符合格式的字符串解析为 `Date` 对象 --- ### **二、基础用法示例** #### 1. 日期 → 字符串(格式化) ```java // 1. 定义日期格式 SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); // 2. 创建Date对象 Date now = new Date(); // 3. 格式化输出 String formattedDate = sdf.format(now); // 结果示例:"2023-08-25 14:30:00" ``` #### 2. 字符串 → 日期(解析) ```java String dateStr = "2023-08-25"; SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); Date date = sdf.parse(dateStr); // 注意:字符串必须严格匹配格式,否则抛ParseException ``` --- ### **三、格式符号说明** | 符号 | 含义 | 示例 | |------|---------------------|------------| | `y` | 年(Year) | `yyyy` → 2023 | | `M` | 月(Month) | `MM` → 08(补零) | | `d` | 日(Day in month) | `dd` → 25 | | `H` | 小时(24小时制) | `HH` → 14 | | `h` | 小时(12小时制) | `hh` → 02 | | `m` | 分钟(Minute) | `mm` → 30 | | `s` | 秒(Second) | `ss` → 45 | | `S` | 毫秒(Millisecond) | `SSS` → 789 | | `E` | 星期几 | `E` → 周二 | --- ### **四、线程安全问题解决方案** #### 1. 问题根源 `SimpleDateFormat` **不是线程安全**的,多线程共享同一实例会导致: - 数据混乱(如格式错误) - `NumberFormatException` 等异常 #### 2. 解决方案 - **局部创建**(每次使用新实例): ```java public String formatDate(Date date) { SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); return sdf.format(date); } ``` - **加锁同步**: ```java private static final SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); public synchronized String formatDate(Date date) { return sdf.format(date); } ``` - **使用ThreadLocal**: ```java private static final ThreadLocal<SimpleDateFormat> threadLocalSdf = ThreadLocal.withInitial(() -> new SimpleDateFormat("yyyy-MM-dd")); public String formatDate(Date date) { return threadLocalSdf.get().format(date); } ``` --- ### **五、Java 8+ 推荐替代方案** Java 8引入的 `java.time.format.DateTimeFormatter` **线程安全且更简洁**: ```java // 格式化 LocalDateTime now = LocalDateTime.now(); DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"); String formattedDate = now.format(formatter); // 解析 String dateStr = "2023-08-25"; LocalDate date = LocalDate.parse(dateStr, DateTimeFormatter.ISO_DATE); ``` --- ### **六、常见问题** 1. **解析失败** 字符串格式不匹配时抛 `ParseException`,建议捕获处理: ```java try { Date date = sdf.parse("2023/08-25"); // 格式错误 } catch (ParseException e) { e.printStackTrace(); } ``` 2. **时区问题** 默认使用系统时区,需显式设置时区: ```java SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); sdf.setTimeZone(TimeZone.getTimeZone("GMT+8")); ``` --- ### **总结** - **优先使用Java 8的 `DateTimeFormatter`**(线程安全、API更友好) - 若必须用 `SimpleDateFormat`,需确保线程安全(如通过`ThreadLocal`) - 格式字符串严格区分大小写(如 `MM` 表示月份,`mm` 表示分钟)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值