Java日期转换SimpleDateFormat的使用及注意事项

文章介绍了两个Java工具类,一个是DateUtils,提供了日期的增减、判断、格式转换等功能,另一个是DateFormatUtils,专用于日期格式的解析和展示。重点强调了日期格式的注意事项和示例。
摘要由CSDN通过智能技术生成

一、附上两个日期转换的工具类

1、日期时间获取及转换

import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;

import org.apache.commons.lang.StringUtils;

import com.star.sms.model.sale.core.BalanceSheetItem;

/**
 * 时间工具.
 */
public final class DateUtils {

    /**
     * 年模式
     */
    public static final int YEAR_MODE = Calendar.YEAR;

    /**
     * 月模式
     */
    public static final int MONTH_MODE = Calendar.MONTH;

    /**
     * 日模式
     */
    public static final int DATE_MODE = Calendar.DATE;

    private static Calendar calendar = Calendar.getInstance();

    private static final int LAST_HOUR_OF_DAY = 23;

    private static final int LAST_MINUTE = 59;

    private static final int LAST_SECOND = 59;

    private static final int LAST_MILLISECOND = 999;

    private static final int YEAR_BASE = 1900;

    private static final int YEAR_RATE = 10000;

    private static final int MONTH_RATE = 100;

    private DateUtils() {
    }

    /**
     * 得到下一年的日期
     * 
     * @param date 当前日期
     * @return 下一年
     */
    public static Date nextYear(Date date) {
        return moveDatePointForwardsByMode(date, YEAR_MODE, 1);
    }

    /**
     * 得到前一年的日期
     * 
     * @param date 当前日期
     * @return 前一年
     */
    public static Date preYear(Date date) {
        return moveDatePointBackwardsByMode(date, YEAR_MODE, 1);
    }

    /**
     * 得到下一月的日期
     * 
     * @param date 当前日期
     * @return 下一月
     */
    public static Date nextMonth(Date date) {
        return moveDatePointForwardsByMode(date, MONTH_MODE, 1);
    }

    /**
     * 得到前一月的日期
     * 
     * @param date 当前日期
     * @return 前一月
     */
    public static Date preMonth(Date date) {
        return moveDatePointBackwardsByMode(date, MONTH_MODE, 1);
    }

    /**
     * 得到下一天的日期
     * 
     * @param date 当前日期
     * @return 下一天
     */
    public static Date nextDate(Date date) {
        return moveDatePointForwardsByMode(date, DATE_MODE, 1);
    }

    /**
     * 得到前一天的日期
     * 
     * @param date 当前日期
     * @return 前一天
     */
    public static Date preDate(Date date) {
        return moveDatePointBackwardsByMode(date, DATE_MODE, 1);
    }

    /**
     * 得到某天的最后一刻
     * 
     * @param date 某天
     * @return 最后一刻
     */
    public static Date getEndOfDate(Date date) {
        calendar.setTime(date);
        calendar.set(Calendar.HOUR_OF_DAY, LAST_HOUR_OF_DAY);
        calendar.set(Calendar.MINUTE, LAST_MINUTE);
        calendar.set(Calendar.SECOND, LAST_SECOND);
        calendar.set(Calendar.MILLISECOND, LAST_MILLISECOND);
        return calendar.getTime();
    }

    /**
     * 得到某天的第一时刻(用于显示)
     * 
     * @param date 某天
     * @return 第一时刻
     * @deprecated 不能滥用,目前控件对0:00:00显示的问题没用解决,暂时只在BalanceHelper中使用
     * @see com.star.sms.model.sale.help.BalanceHelper#prepareDate000(BalanceSheetItem)
     */
    public static Date getBeginOfDate000(Date date) {
        calendar.setTime(date);
        calendar.set(Calendar.HOUR_OF_DAY, 0);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);
        calendar.set(Calendar.MILLISECOND, 1);
        return calendar.getTime();
    }

    /**
     * 得到某天的第一时刻
     * 
     * @param date 某天
     * @return 第一时刻
     */
    public static Date getBeginOfDate(Date date) {
        calendar.setTime(date);
        calendar.set(Calendar.HOUR_OF_DAY, 0);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);
        calendar.set(Calendar.MILLISECOND, 0);
        return calendar.getTime();
    }

    /**
     * 移动日期指针
     * 
     * @param date 日期
     * @param amount 数量
     * @return 移动后的日期
     */
    public static Date moveDatePointForwards(Date date, int amount) {
        return moveDatePointForwardsByMode(date, DATE_MODE, amount);
    }

    /**
     * 移动日期指针
     * 
     * @param date 日期
     * @param amount 数量
     * @return 移动后的日期
     */
    public static Date moveDatePointBackwards(Date date, int amount) {
        return moveDatePointBackwardsByMode(date, DATE_MODE, amount);
    }

    /**
     * 移动日期指针(进)
     * 
     * @param date 日期
     * @param mode 日期模式
     * @param amount 数量
     * @return 移动后的日期
     */
    public static Date moveDatePointForwardsByMode(Date date, int mode, int amount) {
        assertMode(mode);
        calendar.setTime(date);
        calendar.set(mode, calendar.get(mode) + amount);
        return calendar.getTime();
    }

    /**
     * 移动日期指针(退)
     * 
     * @param date 日期
     * @param mode 日期模式
     * @param amount 数量
     * @return 移动后的日期
     */
    public static Date moveDatePointBackwardsByMode(Date date, int mode, int amount) {
        assertMode(mode);
        calendar.setTime(date);
        calendar.set(mode, calendar.get(mode) - amount);
        return calendar.getTime();
    }

    /**
     * 通过一个日期字符串得到一个日期
     * 
     * @param dateStr 日期字符串
     * @return 日期实例
     */
    public static Date newDateInstance(String dateStr) {
        int[] ymd = ymd(dateStr);
        calendar.set(Calendar.YEAR, ymd[0]);
        calendar.set(Calendar.MONTH, ymd[1]);
        calendar.set(Calendar.DATE, ymd[2]);
        return calendar.getTime();
    }
    
    /**
     * 判断日期date是否是当前月份
     * @param date
     * @return
     */
	public static boolean isCurrentMonth(Date date) {
		Calendar currentDate = Calendar.getInstance();
		int currentYear = currentDate.get(Calendar.YEAR);
		int currentMonth = currentDate.get(Calendar.MONTH);
		
		Calendar stopTime = Calendar.getInstance();
		stopTime.setTime(date);
		
		int stopYear = stopTime.get(Calendar.YEAR);
		int stopMonth = stopTime.get(Calendar.MONTH);
		
		return currentYear == stopYear && currentMonth ==stopMonth;
	}

    /**
     * 是否同一天(精确到日,不管'时'分'秒)
     * 
     * @param d1 日期1
     * @param d2 日期2
     * @return boolean
     */
    public static boolean simpleSameDate(Date d1, Date d2) {
        return build(ymd(d1)) == build(ymd(d2));
    }

    // ==========private methods===============//
    private static void assertMode(int mode) {
        if ((YEAR_MODE != mode) && (MONTH_MODE != mode) && (DATE_MODE != mode)) {
            throw new IllegalArgumentException("please use STATIC of DateUtils.class");
        }
    }

    private static int build(int[] ymd) {
        if ((null == ymd) || (3 != ymd.length)) {
            throw new IllegalArgumentException("should 1900,01,01");
        }
        return ymd[0] * YEAR_RATE + ymd[1] * MONTH_RATE + ymd[2];
    }

    private static int[] ymd(Date date) {
        calendar.setTime(date);
        int[] ymd = new int[] { calendar.get(Calendar.YEAR) - YEAR_BASE,
                               calendar.get(Calendar.MONTH), calendar.get(Calendar.DATE) };
        return ymd;
    }

    private static int[] ymd(String dateStr) {
        String[] ymdStr = StringUtils.split(dateStr, '-');
        if ((null == ymdStr) || (3 != ymdStr.length)) {
            throw new IllegalArgumentException("should 2008-08-08");
        }
        int[] ymd = new int[] { Integer.valueOf(ymdStr[0]), Integer.valueOf(ymdStr[1]),
                               Integer.valueOf(ymdStr[2]) };
        return ymd;
    }
  
    /**
	 * getStartOfDate.
	 * 
	 * @param date
	 *            Date
	 * @return Date
	 */
	public static Date getStartOfDate(Date date) {
		if(date == null) {
			return null;
		}
		Calendar cal = Calendar.getInstance();
		cal.setTime(date);
		cal.set(Calendar.HOUR_OF_DAY, 0);
		cal.set(Calendar.MINUTE, 0);
		cal.set(Calendar.SECOND, 0);
		cal.set(Calendar.MILLISECOND, 0);
		return cal.getTime();
	}
	
	/**
	 * 计算两个日期间相差的天数
	 * @param beginDate
	 * @param endDate
	 * @return days
	 */
	public static int getDaysBetween(Date beginDate, Date endDate) {
		if (beginDate.after(endDate)) { 
			Date swap = beginDate;
			beginDate = endDate;
			endDate = swap;
		}
		Calendar beginCalendar = Calendar.getInstance();
		beginCalendar.setTime(beginDate);
		Calendar endCalendar = Calendar.getInstance();
		endCalendar.setTime(endDate);

		int days = endCalendar.get(Calendar.DAY_OF_YEAR)
				- beginCalendar.get(Calendar.DAY_OF_YEAR);
		
		int endDateYear = endCalendar.get(Calendar.YEAR);

		while (beginCalendar.get(Calendar.YEAR) != endDateYear) {
			days += beginCalendar.getActualMaximum(Calendar.DAY_OF_YEAR);
			beginCalendar.add(Calendar.YEAR, 1);
		}

		return days;
	}

	public static Date getEndOfMonth(Date date) {
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(date);
		calendar.set(Calendar.DAY_OF_MONTH, 1);
		calendar.add(Calendar.MONTH, 1);
		calendar.add(Calendar.DATE, -1);
		return getEndOfDate(calendar.getTime());
	}
	
	public static int getMonthNum(Date startDT, Date endDT) {
		Calendar startCalendar = Calendar.getInstance();
		startCalendar.setTime(startDT);
		Calendar endCalendar = Calendar.getInstance();
		endCalendar.setTime(endDT);
		int monthNum = 0;
		while (startCalendar.before(endCalendar)) {
			monthNum++;
			startCalendar.add(Calendar.MONTH, 1);
		}
		return monthNum;
	}
	
	public static boolean isSameDay(Date startDate, Date endDate) {
		Calendar start = Calendar.getInstance();
		start.setTime(startDate);
		Calendar end = Calendar.getInstance();
		end.setTime(endDate);
		if (start.get(Calendar.YEAR) == end.get(Calendar.YEAR)
				&& start.get(Calendar.MONTH) == end.get(Calendar.MONTH)
				&& start.get(Calendar.DAY_OF_MONTH) == end
						.get(Calendar.DAY_OF_MONTH)) {
			return true;
		}
		return false;
	}

	/**
	 * 
	 * @param date
	 * @param format
	 * @return
	 */
	public static String format(Date date,String format){
		if (date == null ) {
			return "";
		}
		SimpleDateFormat forDateFormat = new SimpleDateFormat(format);
		return forDateFormat.format(date);
	} 
	
}

2、日期格式转换工具类

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;

public class DateFormatUtils {

	public static final String SHORT_DATE_STR = "yyyy-MM-dd";
	public static final String SIMPLE_DATE_STR = "yyyy-MM-dd HH:mm:ss";

	public static Date toDate(String date) {
		SimpleDateFormat sdf = new SimpleDateFormat(SIMPLE_DATE_STR);
		try {
			return sdf.parse(date);
		} catch (ParseException e) {
			throw new MsrRuntimeException("date format error:" + date);
		}
	}

	public static Date toShortDate(String date) {
		SimpleDateFormat sdf = new SimpleDateFormat(SHORT_DATE_STR);
		try {
			return sdf.parse(date);
		} catch (ParseException e) {
			throw new MsrRuntimeException("date format error:" + date);
		}
	}

	public static String toStr(Date date) {
		SimpleDateFormat sdf = new SimpleDateFormat(SIMPLE_DATE_STR);
		return sdf.format(date);
	}

	public static String toShortStr(Date date) {
		SimpleDateFormat sdf = new SimpleDateFormat(SHORT_DATE_STR);
		return sdf.format(date);
	}
}

二、日期格式转换注意事项

1、一定要注意大小写的问题,大小写不同代表的含义不一样:yyyy-MM与YYYY-MM

2、另外转换的时候要注意位数的限制,比如yyyy-M 与 yyyy-MM

具体含义见源码说明:

<table border=0 cellspacing=3 cellpadding=0 summary="Chart shows pattern letters, date/time component, presentation, and examples.">
 *     <tr bgcolor="#ccccff">
 *         <th align=left>Letter
 *         <th align=left>Date or Time Component
 *         <th align=left>Presentation
 *         <th align=left>Examples
 *     <tr>
 *         <td><code>G</code>
 *         <td>Era designator
 *         <td><a href="#text">Text</a>
 *         <td><code>AD</code>
 *     <tr bgcolor="#eeeeff">
 *         <td><code>y</code>
 *         <td>Year
 *         <td><a href="#year">Year</a>
 *         <td><code>1996</code>; <code>96</code>
 *     <tr>
 *         <td><code>M</code>
 *         <td>Month in year
 *         <td><a href="#month">Month</a>
 *         <td><code>July</code>; <code>Jul</code>; <code>07</code>
 *     <tr bgcolor="#eeeeff">
 *         <td><code>w</code>
 *         <td>Week in year
 *         <td><a href="#number">Number</a>
 *         <td><code>27</code>
 *     <tr>
 *         <td><code>W</code>
 *         <td>Week in month
 *         <td><a href="#number">Number</a>
 *         <td><code>2</code>
 *     <tr bgcolor="#eeeeff">
 *         <td><code>D</code>
 *         <td>Day in year
 *         <td><a href="#number">Number</a>
 *         <td><code>189</code>
 *     <tr>
 *         <td><code>d</code>
 *         <td>Day in month
 *         <td><a href="#number">Number</a>
 *         <td><code>10</code>
 *     <tr bgcolor="#eeeeff">
 *         <td><code>F</code>
 *         <td>Day of week in month
 *         <td><a href="#number">Number</a>
 *         <td><code>2</code>
 *     <tr>
 *         <td><code>E</code>
 *         <td>Day in week
 *         <td><a href="#text">Text</a>
 *         <td><code>Tuesday</code>; <code>Tue</code>
 *     <tr bgcolor="#eeeeff">
 *         <td><code>a</code>
 *         <td>Am/pm marker
 *         <td><a href="#text">Text</a>
 *         <td><code>PM</code>
 *     <tr>
 *         <td><code>H</code>
 *         <td>Hour in day (0-23)
 *         <td><a href="#number">Number</a>
 *         <td><code>0</code>
 *     <tr bgcolor="#eeeeff">
 *         <td><code>k</code>
 *         <td>Hour in day (1-24)
 *         <td><a href="#number">Number</a>
 *         <td><code>24</code>
 *     <tr>
 *         <td><code>K</code>
 *         <td>Hour in am/pm (0-11)
 *         <td><a href="#number">Number</a>
 *         <td><code>0</code>
 *     <tr bgcolor="#eeeeff">
 *         <td><code>h</code>
 *         <td>Hour in am/pm (1-12)
 *         <td><a href="#number">Number</a>
 *         <td><code>12</code>
 *     <tr>
 *         <td><code>m</code>
 *         <td>Minute in hour
 *         <td><a href="#number">Number</a>
 *         <td><code>30</code>
 *     <tr bgcolor="#eeeeff">
 *         <td><code>s</code>
 *         <td>Second in minute
 *         <td><a href="#number">Number</a>
 *         <td><code>55</code>
 *     <tr>
 *         <td><code>S</code>
 *         <td>Millisecond
 *         <td><a href="#number">Number</a>
 *         <td><code>978</code>
 *     <tr bgcolor="#eeeeff">
 *         <td><code>z</code>
 *         <td>Time zone
 *         <td><a href="#timezone">General time zone</a>
 *         <td><code>Pacific Standard Time</code>; <code>PST</code>; <code>GMT-08:00</code>
 *     <tr>
 *         <td><code>Z</code>
 *         <td>Time zone
 *         <td><a href="#rfc822timezone">RFC 822 time zone</a>
 *         <td><code>-0800</code>
 * </table>
 * </blockquote>

`SimpleDateFormat` 是 Java 中用于解析、格式化日期时间字符串的一种工具类,它属于 `java.text.SimpleDateFormat` 类。这个类可以将日期时间的文本表示转换为 `Date` 对象,或者反过来将 `Date` 对象转换成易于人类阅读的文本表示。 ### 使用步骤 #### 创建 `SimpleDateFormat` 创建一个新的 `SimpleDateFormat` 实例需要指定日期格式化的模式。例如: ```java String formatPattern = "yyyy-MM-dd HH:mm:ss"; SimpleDateFormat sdf = new SimpleDateFormat(formatPattern); ``` #### 解析日期 你可以使用 `parse()` 方法将格式化的日期字符串解析为日期对象: ```java String dateStr = "2023-03-15 14:30:00"; Date dateObj = sdf.parse(dateStr); System.out.println("Parsed Date: " + dateObj); ``` #### 格式化日期 `format()` 方法则可以将日期对象转换回格式化的字符串: ```java String formattedDate = sdf.format(dateObj); System.out.println("Formatted Date: " + formattedDate); ``` ### 注意事项 - **线程安全**:`SimpleDateFormat` 类不是线程安全的,如果在多线程环境中使用,每次解析或格式化之前都应该重新初始化实例。 - **性能**:频繁地解析和格式化可能会消耗较多资源,特别是在高并发场景下。 - **国际化支持**:通过使用 `DateTimeFormatter` 和 `DateTimeParseException` 等替代类,可以获得更好的国际化支持,并且避免了 `SimpleDateFormat` 的一些局限性。 ### 相关问题: 1. `SimpleDateFormat` 和 `DateTimeFormatter` 之间的区别是什么? 2. 如何处理 `SimpleDateFormat` 的线程安全性问题? 3. `SimpleDateFormat` 是否支持所有国际日期格式?
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值