This is the 9th day of my participation in the Gwen Challenge in November. Check out the details: The last Gwen Challenge in 2021.”
❤️ About the author: Hello everyone, I am Xiao Xu Zhu. Java field quality creator 🏆, CSDN blog expert certification 🏆, Huawei Cloud enjoy expert certification 🏆
❤️ technology live, the appreciation
❤️ like 👍 collect ⭐ look again, form a habit
Before reading this article, it is recommended to have some knowledge of the date and time of Java source code. If not, you can read this article first:
Swastika blog teaches you to understand Java source code date and time related usage
Related articles:
Hutool actual combat (take you to master the various tools) directory
4hutool :DateUtil- Format time
Source code analysis purposes
Know what it is and why
Project reference
The basis of this blog: Hutool -5.6.5 version of the source code
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-core</artifactId>
<version>5.6.5</version>
</dependency>
Copy the code
The method name: DateUtil. FormatLocalDateTime (Java. Time. LocalDateTime)
Methods described
Format date time <br> Format YYYY-MM-DD HH: MM: SS
Source code Analysis 1
/** * Format date time <br> * Format YYYY-MM-DD HH: MM :ss **@paramLocalDateTime Formatted date *@returnThe formatted character string */
public static String formatLocalDateTime(LocalDateTime localDateTime) {
return LocalDateTimeUtil.formatNormal(localDateTime);
}
Copy the code
First, the formatLocalDateTime method takes an input parameter of LocalDateTime.
Then call LocalDateTimeUtil. FormatNormal (localDateTime)
//LocalDateTimeUtil
/** * Format the date and time in yyyY-MM-DD HH: MM :ss format **@param time {@link LocalDateTime}
* @returnFormatted string *@since5.3.11 * /
public static String formatNormal(LocalDateTime time) {
return format(time, DatePattern.NORM_DATETIME_FORMATTER);
}
/** * Format the date and time in the specified format **@param time {@link LocalDateTime}
* @paramDate formatter, predefined format see: {@link DateTimeFormatter}
* @returnThe formatted character string */
public static String format(LocalDateTime time, DateTimeFormatter formatter) {
return TemporalAccessorUtil.format(time, formatter);
}
Copy the code
NORM_DATETIME_FORMATTER datepattern. NORM_DATETIME_FORMATTER date-time format:
/** * Standard date and time format, accurate to seconds: YYYY-MM-DD HH: MM :ss */
public static final String NORM_DATETIME_PATTERN = "yyyy-MM-dd HH:mm:ss";
Copy the code
And then it callsformat(LocalDateTime time, DateTimeFormatter formatter)The DateTimeFormatter class is supported by Java8, which is thread-safe.
Hutool makes a good example here of replacing SimpleDateFormat (thread-unsafe) with DateTimeFormatter.
Why SimpleDateFormat is not thread-safe
Then we continue to dig down TemporalAccessorUtil. The format (time, formatter)
/** * Format the date and time in the specified format **@param time {@link TemporalAccessor}
* @paramDate formatter, predefined format see: {@link DateTimeFormatter}
* @returnFormatted string *@since5.3.10 * /
public static String format(TemporalAccessor time, DateTimeFormatter formatter) {
if (null == time) {
return null;
}
if(null == formatter){
formatter = DateTimeFormatter.ISO_LOCAL_DATE_TIME;
}
try {
return formatter.format(time);
} catch (UnsupportedTemporalTypeException e){
if(time instanceof LocalDate && e.getMessage().contains("HourOfDay")) {// The user passes in LocalDate, but requires formatting with a time part. Convert to LocalDateTime and retry
return formatter.format(((LocalDate) time).atStartOfDay());
}else if(time instanceof LocalTime && e.getMessage().contains("YearOfEra")) {// The user passes in LocalTime, but asks for formatting with the date part, converts to LocalDateTime and tries again
return formatter.format(((LocalTime) time).atDate(LocalDate.now()));
}
throwe; }}Copy the code
If time is null, null is returned. If formatter is null, give the format default value, eg:2011-12-03T10:15:30
Format (time) is equivalent to datetimeFormatter. format(LocalDateTime). This formatting succeeds.
Worthy of mention is * * TemporalAccessorUtil. The format (TemporalAccessor time, DateTimeFormatter formatter) * * add exception handling mechanism inside
try {
return formatter.format(time);
} catch (UnsupportedTemporalTypeException e){
if(time instanceof LocalDate && e.getMessage().contains("HourOfDay")) {// The user passes in LocalDate, but requires formatting with a time part. Convert to LocalDateTime and retry
return formatter.format(((LocalDate) time).atStartOfDay());
}else if(time instanceof LocalTime && e.getMessage().contains("YearOfEra")) {// The user passes in LocalTime, but asks for formatting with the date part, converts to LocalDateTime and tries again
return formatter.format(((LocalTime) time).atDate(LocalDate.now()));
}
throw e;
}
Copy the code
Because the implementation classes of TemporalAccessor Time are commonly used as follows (provided by Java8) :
- LocalDateTime
- LocalDate
- LocalTime
When performing date-time conversion, the date-time must correspond to the formatted string to be converted, otherwise an exception will be thrown, so the above remedy is made.
Format (java.time.localdatetime, java.lang.string)
Methods described
Format the date according to a specific format
Source code Analysis 1
/** * Formats the date according to a specific format **@paramLocalDateTime Formatted date *@paramFormat Date format. The common format is: {@link DatePattern}
* @returnThe formatted character string */
public static String format(LocalDateTime localDateTime, String format) {
return LocalDateTimeUtil.format(localDateTime, format);
}
Copy the code
First: Hutool provides common date-time formats
/** * date formatting class, which provides the common date formatting object ** /
public class DatePattern {... }Copy the code
Then: call localDateTimeUtil. format(localDateTime, format)
/** * Format the date and time in the specified format **@param time {@link LocalDateTime}
* @paramFormat The date format, similar to YYYY-MM-DD HH: MM :ss,SSS *@returnThe formatted character string */
public static String format(LocalDateTime time, String format) {
if (null == time) {
return null;
}
return format(time, DateTimeFormatter.ofPattern(format));
}
Copy the code
Source format * * (time, DateTimeFormatter ofPattern (format)) * * can be disassembled into two parts:
-
DateTimeFormatter.ofPattern(format)
-
format(LocalDateTime time, DateTimeFormatter formatter)
The first part: * * DateTimeFormatter ofPattern (format) * * is to put the date/time format string into the date/time formatting objects DateTimeFormatter;
Note DateTimeFormatter ofPattern (format) usage is the pit (post code explanation — > a swastika teach you understand Java source code date and time of the related usage) :
- In normal configuration, string dates in standard format can be converted normally. If the value of month, day, hour, minute, or second is less than two digits, the conversion will fail and an exception will be thrown.
- Use YYYY and DD with caution
Format (LocalDateTime time, DateTimeFormatter formatter)
Dateutil. format(java.util.Date, java.text.dateformat)
Methods described
Format the date according to a specific format
Source code Analysis 1
/** * Formats the date according to a specific format **@paramDate Formatted date *@paramFormat Date format. The common format is: {@link DatePattern}
* @returnThe formatted character string */
public static String format(Date date, String format) {
if (null == date || StrUtil.isBlank(format)) {
return null;
}
TimeZone timeZone = null;
if (date instanceof DateTime) {
timeZone = ((DateTime) date).getTimeZone();
}
return format(date, newSimpleFormat(format, null, timeZone));
}
Copy the code
From the code, the **format(Date Date, String format)** method provides two input arguments, a formatted Date of type Date and a String to format the Date. This is to be compatible with the methods provided by the older date-time API prior to java8.
Two parameters are nulled in the method.
Then determine if the time is a Hutool DateTime object, and if so, get the TimeZone
Then call format(date, newSimpleFormat(format, NULL, timeZone)), which can be split into two parts:
-
NewSimpleFormat (format, NULL, timeZone), get SimpleDateFormat object (note: this method is not thread-safe)
-
Format (Date Date, DateFormat format) Formats a Date based on a specific format
**newSimpleFormat(format, NULL, timeZone)
/** * create {@linkSimpleDateFormat}, note that this object is not thread-safe! <br> * This object defaults to strictly formatted mode, meaning that parse will report an error if it is incorrectly formatted. * *@paramPattern expression *@param locale {@linkThe Locale}, {@codeNull} indicates the default *@param timeZone {@linkTimeZone}, {@codeNull} indicates the default *@return {@link SimpleDateFormat}
* @since5.5.5 * /
public static SimpleDateFormat newSimpleFormat(String pattern, Locale locale, TimeZone timeZone) {
if (null == locale) {
locale = Locale.getDefault(Locale.Category.FORMAT);
}
final SimpleDateFormat format = new SimpleDateFormat(pattern, locale);
if (null! = timeZone) { format.setTimeZone(timeZone); } format.setLenient(false);
return format;
}
Copy the code
If **format(Date Date, String format) specifies the time of the Date object, then format(Date, newSimpleFormat(format, NULL, timeZone))** would look like this: Format(date, newSimpleFormat(format, NULL, null)).
// Get the current locale
locale = Locale.getDefault(Locale.Category.FORMAT);
Copy the code
Then a SimpleDateFormat object is new. And set the time zone and set setLenient, which means whether or not to parse dates strictly. When setLenient is set to false, dates are strictly parsed: the date and time format is strictly adhered to, and Java does not help with calculations, throwing exceptions.
**format(Date Date, DateFormat format) **
/** * Formats the date according to a specific format **@paramDate Formatted date *@param format {@link SimpleDateFormat}
* @returnThe formatted character string */
public static String format(Date date, DateFormat format) {
if (null == format || null == date) {
return null;
}
return format.format(date);
}
Copy the code
Two input parameters are nulled. Then call simpledateformat.format (date), which was provided before java8.
Method name: DateUtil. The format (Java. Util. Date, Java. Time. The format. The DateTimeFormatter) (method has a problem, have feedback, authorities have revised)
Methods described
Format the date according to a specific format
Source code Analysis 1
/** * Formats the date according to a specific format **@paramDate Formatted date *@param format {@link DateTimeFormatter}
* @returnFormatted string *@since5.0.0 * /
public static String format(Date date, DateTimeFormatter format) {
if (null == format || null == date) {
return null;
}
return format.format(date.toInstant());
}
Copy the code
First, two input parameters are nulled.
Then, format.format(date.toinstant ()) is executed, and the code can be broken into two parts:
- Date.toinstant (): Returns an Instant object
- Datetimeformatter. format(Instant) : method of formatting date and time provided by java8
How does the code ** dateTimeFormatter.format (Instant)** handle?
public String format(TemporalAccessor temporal) {
StringBuilder buf = new StringBuilder(32);
formatTo(temporal, buf);
return buf.toString();
}
Copy the code
First, we create a StringBuilder object to concatenate strings;
Then call the **formatTo(temporal, buf)** method
public void formatTo(TemporalAccessor temporal, Appendable appendable) {
Objects.requireNonNull(temporal, "temporal");
Objects.requireNonNull(appendable, "appendable");
try {
DateTimePrintContext context = new DateTimePrintContext(temporal, this);
if (appendable instanceof StringBuilder) {
printerParser.format(context, (StringBuilder) appendable);
} else {
// buffer output to avoid writing to appendable in case of error
StringBuilder buf = new StringBuilder(32); printerParser.format(context, buf); appendable.append(buf); }}catch (IOException ex) {
throw newDateTimeException(ex.getMessage(), ex); }}Copy the code
FormatTo (temporal, buf);
The Instant object is then wrapped in a new DateTimePrintContext object
Troubleshoot demo running problems
// Format the date according to a specific format
DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy-MM-dd");
String dateStr = DateUtil.format(new Date(),dtf);
System.out.println(dateStr);
Copy the code
Datetimeformatter.format is the JDK source
From the above knowable, invoked NumberPrinterParser. Format () NumberPrinterParser is in DateTimeFormatterBuilder in the class.
You get an error at this point
Let’s see what happens to context.getValue(field) :
The above code makes sense, temporal is actually an Instant object, and Instant. GetLong only supports four field types.
NANO_OF_SECOND
MICRO_OF_SECOND
MILLI_OF_SECOND
INSTANT_SECONDS
Copy the code
If none of the above field types is present, an exception is thrown
Dateutil. format Converts the Date object to Instant when DateTimeFormatter is encountered.
Suggest other way
/** * Formats the date according to a specific format **@paramDate Formatted date *@param format
* @returnFormatted string *@since5.0.0 * /
public static String format(Date date, DateTimeFormatter format) {
if (null == format || null == date) {
return null;
}
Instant instant = date.toInstant();
ZonedDateTime zonedDateTime = instant.atZone(ZoneId.systemDefault());
LocalDateTime localDateTime = zonedDateTime.toLocalDateTime();
return format.format(localDateTime);
}
Copy the code
Format dateTimeFormatter. format(LocalDateTime)
Test the demo
// Format the date according to a specific format
String str = "The 2021-07-25 20:11:25";
DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:dd");
Date date = DateUtil.parse(str);
String dateStr = DateUtil.format(date,dtf);
System.out.println(dateStr);
Assert.assertEquals(str, dateStr);
Copy the code
Other official
Updated in version #5.7.5
/** * Formats the date according to a specific format **@paramDate Formatted date *@param format {@link SimpleDateFormat} {@link DatePattern#NORM_DATETIME_FORMATTER}
* @returnFormatted string *@since5.0.0 * /
public static String format(Date date, DateTimeFormatter format) {
if (null == format || null == date) {
return null;
}
// java.time.temporal.UnsupportedTemporalTypeException: Unsupported field: YearOfEra
// If the preceding error occurs, the Instant timestamp has no time zone information, and the default time zone is assigned
return TemporalAccessorUtil.format(date.toInstant(), format);
}
Copy the code
Replaced the new method is called TemporalAccessorUtil. The format (date. ToInstant (), the format), date. ToInstant () returns the Instant, Is turned into TemporalAccessorUtil. The format (Instant, format)
//TemporalAccessorUtil
/** * Format the date and time in the specified format **@param time {@link TemporalAccessor}
* @paramDate formatter, predefined format see: {@link DateTimeFormatter}
* @returnFormatted string *@since5.3.10 * /
public static String format(TemporalAccessor time, DateTimeFormatter formatter) {
if (null == time) {
return null;
}
if(null == formatter){
formatter = DateTimeFormatter.ISO_LOCAL_DATE_TIME;
}
try {
return formatter.format(time);
} catch (UnsupportedTemporalTypeException e){
if(time instanceof LocalDate && e.getMessage().contains("HourOfDay")) {// The user passes in LocalDate, but requires formatting with a time part. Convert to LocalDateTime and retry
return formatter.format(((LocalDate) time).atStartOfDay());
}else if(time instanceof LocalTime && e.getMessage().contains("YearOfEra")) {// The user passes in LocalTime, but asks for formatting with the date part, converts to LocalDateTime and tries again
return formatter.format(((LocalTime) time).atDate(LocalDate.now()));
} else if(time instanceof Instant){
// The timestamp has no time zone information
return formatter.format(((Instant) time).atZone(ZoneId.systemDefault()));
}
throwe; }}Copy the code
– Added a default time zone when time is Instant
else if(time instanceof Instant){
// The timestamp has no time zone information
return formatter.format(((Instant) time).atZone(ZoneId.systemDefault()));
}
Copy the code
Dateutil. formatDateTime(java.util.date)
Methods described
Format date time <br> Format YYYY-MM-DD HH: MM: SS
Source code Analysis 1
/** * Format date time <br> * Format YYYY-MM-DD HH: MM :ss **@paramDate Formatted date *@returnFormatted date */
public static String formatDateTime(Date date) {
if (null == date) {
return null;
}
return DatePattern.NORM_DATETIME_FORMAT.format(date);
}
Copy the code
First of all, it is a good habit to judge the null processing of the input parameter
Datepattern.norm_datetime_format.format (date) is then called to return the FastDateFormat object
For java8 only before the program, you can use FastDateFormat thread safety replace SimpleDateFormat thread is not safe — “source analysis
FastDateFormat is a thread-safe implementation source from Apache Commons Lang 3.5Copy the code
DatePattern.NORM_DATETIME_FORMAT-->
/** * Standard date-time format, accurate to seconds {@linkFastDateFormat} : YYYY-MM-DD HH: MM :ss */
public static final FastDateFormat NORM_DATETIME_FORMAT = FastDateFormat.getInstance(NORM_DATETIME_PATTERN);
Copy the code
Is converted toFastDateFormat.format(date)
//FastDateFormat
@Override
public String format(final Date date) {
return printer.format(date);
}
//FastDatePrinter
@Override
public String format(final Date date) {
final Calendar c = Calendar.getInstance(timeZone, locale);
c.setTime(date);
return applyRulesToString(c);
}
Copy the code
First, convert date to Calendar so that you can easily obtain the date and time
private String applyRulesToString(final Calendar c) {
return applyRules(c, new StringBuilder(mMaxLengthEstimate)).toString();
}
private <B extends Appendable> B applyRules(final Calendar calendar, final B buf) {
try {
for (final Rule rule : this.rules) { rule.appendTo(buf, calendar); }}catch (final IOException e) {
throw new DateException(e);
}
return buf;
}
Copy the code
The core code is this
for (final Rule rule : this.rules) {
rule.appendTo(buf, calendar);
}
Copy the code
Test the demo
String dateStr = "2017-03-01";
Date date = DateUtil.parse(dateStr);
String formatDateTime = DateUtil.formatDateTime(date);
Assert.assertEquals("The 2017-03-01 00:00:00", formatDateTime);
Copy the code
Breakpoint tracking code:
Follow the code
//FastDatePrinter
private static class PaddedNumberField implements NumberRule {...@Override
public void appendTo(final Appendable buffer, final Calendar calendar) throws IOException {
appendTo(buffer, calendar.get(mField));
}
/ * * * {@inheritDoc} * /
@Override
public final void appendTo(final Appendable buffer, final int value) throws IOException {
appendFullDigits(buffer, value, mSize);
}
...}
Copy the code
The year is already set: 2017
Follow the code below:
//FastDatePrinter
private static class CharacterLiteral implements Rule {...@Override
public void appendTo(final Appendable buffer, final Calendar calendar) throws IOException { buffer.append(mValue); }... }Copy the code
Just concatenate the ‘-‘ string.
Next fetch month:
//FastDatePrinter
private static class TwoDigitMonthField implements NumberRule {.../ * * * {@inheritDoc} * /
@Override
public void appendTo(final Appendable buffer, final Calendar calendar) throws IOException {
appendTo(buffer, calendar.get(Calendar.MONTH) + 1);
}
/ * * * {@inheritDoc} * /
@Override
public final void appendTo(final Appendable buffer, final int value) throws IOException { appendDigits(buffer, value); }... }Copy the code
Get month: 3
Next: concatenate the ‘-‘ string directly.
Keep following
//FastDatePrinter
private static class TwoDigitNumberField implements NumberRule {...@Override
public void appendTo(final Appendable buffer, final Calendar calendar) throws IOException {
appendTo(buffer, calendar.get(mField));
}
/ * * * {@inheritDoc} * /
@Override
public final void appendTo(final Appendable buffer, final int value) throws IOException {
if (value < 100) {
appendDigits(buffer, value);
} else {
appendFullDigits(buffer, value, 2); }}... }Copy the code
Date obtained: 2017-03-01
Then we add a space string
Time and second calls, all call the same FastDatePrinter#TwoDigitNumberField.
//FastDatePrinter
private static class TwoDigitNumberField implements NumberRule {...@Override
public void appendTo(final Appendable buffer, final Calendar calendar) throws IOException {
appendTo(buffer, calendar.get(mField));
}
/ * * * {@inheritDoc} * /
@Override
public final void appendTo(final Appendable buffer, final int value) throws IOException {
if (value < 100) {
appendDigits(buffer, value);
} else {
appendFullDigits(buffer, value, 2); }}... }Copy the code
So you get “2017-03-01 00:00:00”
Dateutil. formatDate(java.util.date)
Methods described
Format the date part (excluding time) <br> format YYYY-MM-DD
Source code Analysis 1
/** * Format the date part (excluding the time) <br> * Format YYYY-MM-DD **@paramDate Formatted date *@returnThe formatted character string */
public static String formatDate(Date date) {
if (null == date) {
return null;
}
return DatePattern.NORM_DATE_FORMAT.format(date);
}
Copy the code
First of all, it is a good habit to judge the null processing of the input parameter
Datepattern.norm_date_format.format (date) is then called to return the FastDateFormat object
For java8 only before the program, you can use FastDateFormat thread safety replace SimpleDateFormat thread is not safe — “source analysis
FastDateFormat is a thread-safe implementation source from Apache Commons Lang 3.5Copy the code
/** * Standard date format {@linkFastDateFormat} : yyyy - MM - dd * /
public static final FastDateFormat NORM_DATE_FORMAT = FastDateFormat.getInstance(NORM_DATE_PATTERN);
Copy the code
Convert to fastDateformat.format (date), source analysis see above
Dateutil. formatTime(java.util.date)
Methods described
Format time <br> Format HH:mm: SS
Source code Analysis 1
/** * Format time <br> * Format HH:mm:ss **@paramDate Formatted date *@returnFormatted string *@since3.0.1 * /
public static String formatTime(Date date) {
if (null == date) {
return null;
}
return DatePattern.NORM_TIME_FORMAT.format(date);
}
Copy the code
First of all, it is a good habit to judge the null processing of the input parameter
Datepattern.norm_time_format.format (date) is then called to return the FastDateFormat object
For java8 only before the program, you can use FastDateFormat thread safety replace SimpleDateFormat thread is not safe — “source analysis
FastDateFormat is a thread-safe implementation source from Apache Commons Lang 3.5Copy the code
/** * Standard time format {@linkFastDateFormat} : HH: mm: ss * /
public static final FastDateFormat NORM_TIME_FORMAT = FastDateFormat.getInstance(NORM_TIME_PATTERN);
Copy the code
Convert to fastDateformat.format (date), source analysis see above
Dateutil.formathttpdate (java.util.date)
Methods described
The standard date format follows the RFC 1123 specification in a format similar to: Fri, 31 Dec 1999 23:59:59 GMT
Source code Analysis 1
* The standard date format follows the RFC 1123 specification in a format similar to: Fri, 31 Dec 1999 23:59:59 GMT **@paramDate Formatted date *@returnHTTP Standard date string */
public static String formatHttpDate(Date date) {
if (null == date) {
return null;
}
return DatePattern.HTTP_DATETIME_FORMAT.format(date);
}
Copy the code
First of all, it is a good habit to judge the null processing of the input parameter
Then call datepattern.http_datetime_format.format (date) to return the FastDateFormat object
For java8 only before the program, you can use FastDateFormat thread safety replace SimpleDateFormat thread is not safe — “source analysis
FastDateFormat is a thread-safe implementation source from Apache Commons Lang 3.5Copy the code
/** * HTTP header date-time format {@linkFastDateFormat} : EEE, dd MMM YYYY HH:mm:ss z */
public static final FastDateFormat HTTP_DATETIME_FORMAT = FastDateFormat.getInstance(HTTP_DATETIME_PATTERN, TimeZone.getTimeZone("GMT"), Locale.US);
Copy the code
Convert to fastDateformat.format (date), source analysis see above
Method name: DateUtil formatChineseDate (Java. Util. Date, Boolean, Boolean)
Methods described
Format to Chinese date format, if isUppercase is false, return similar to October 24, 2018, otherwise Return October 24, 2018
Source code Analysis 1
If isUppercase is false, return something like October 24, 2018, otherwise Return October 24, 2018@paramDate Formatted date *@paramIsUppercase Specifies whether to use uppercase *@paramWithTime contains the time part *@returnChinese date string *@since5.3.9 * /
public static String formatChineseDate(Date date, boolean isUppercase, boolean withTime) {
if (null == date) {
return null;
}
if (false == isUppercase) {
return (withTime ? DatePattern.CHINESE_DATE_TIME_FORMAT : DatePattern.CHINESE_DATE_FORMAT).format(date);
}
return CalendarUtil.formatChineseDate(CalendarUtil.calendar(date), withTime);
}
Copy the code
First of all, it is a good habit to judge the null processing of the input parameter
When not capitalized
Perform * * (withTime? DatePattern.CHINESE_DATE_TIME_FORMAT : DatePattern.CHINESE_DATE_FORMAT).format(date)**
Datepattern.chinese_date_time_format. format(date) if the time part is included. If the time part is not included, Call the DatePattern. CHINESE_DATE_FORMAT. The format (date)
/** * Standard date format {@linkFastDateFormat: YYYY Year MM month DD day HH MM minute ss second */
public static final FastDateFormat CHINESE_DATE_TIME_FORMAT = FastDateFormat.getInstance(CHINESE_DATE_TIME_PATTERN);
/** * Standard date format {@linkFastDateFormat: YYYY Year MM month DD */
public static final FastDateFormat CHINESE_DATE_FORMAT = FastDateFormat.getInstance(CHINESE_DATE_PATTERN);
Copy the code
As you can see from the source code above, both return FastDateFormat objects.
For java8 only before the program, you can use FastDateFormat thread safety replace SimpleDateFormat thread is not safe — “source analysis
FastDateFormat is a thread-safe implementation source from Apache Commons Lang 3.5Copy the code
/** * HTTP header date-time format {@linkFastDateFormat} : EEE, dd MMM YYYY HH:mm:ss z */
public static final FastDateFormat HTTP_DATETIME_FORMAT = FastDateFormat.getInstance(HTTP_DATETIME_PATTERN, TimeZone.getTimeZone("GMT"), Locale.US);
Copy the code
Convert to fastDateformat.format (date), source analysis see above
When you use uppercase
Perform CalendarUtil. FormatChineseDate (CalendarUtil. The calendar (date), withTime);
Can be broken down into two parts:
-
CalendarUtil. Calendar (Date): Converts date objects to calendar objects
-
CalendarUtil. FormatChineseDate (Calendar Calendar, Boolean withTime) : specifies the Calendar time formatted into pure Chinese form, for example
2018-02-24 12:13:14 convert to February 24, 2018 (withTime is false) 2018-02-24 12:13:14 convert to February 24, 2018 12:13 minutes 14 seconds (withTime is true)Copy the code
Calendarutil. calendar(Date)
/** * converts to Calendar object **@paramDate Date object *@returnThe Calendar object * /
public static Calendar calendar(Date date) {
if (date instanceof DateTime) {
return ((DateTime) date).toCalendar();
} else {
returncalendar(date.getTime()); }}Copy the code
If the DateTime type is provided by Hutool, it can be directly converted to obtain.
If it is of the date type, it is converted to a Calendar object by * cal.setTimeInmillis.
/** * converts to Calendar object **@paramMillis timestamp *@returnThe Calendar object * /
public static Calendar calendar(long millis) {
final Calendar cal = Calendar.getInstance();
cal.setTimeInMillis(millis);
return cal;
}
Copy the code
Some of you will find that this is not the same as the calendar. setTime(Date Date) that we usually use. Look at the source code
//Calendar
public final void setTime(Date date) {
setTimeInMillis(date.getTime());
}
Copy the code
It’s essentially the same thing. SetTimeInMillis is also called in the setTime method.
CalendarUtil. FormatChineseDate (Calendar Calendar, Boolean withTime) source code analysis:
/** * Format the specified Calendar time in pure Chinese, for example: * * <pre> * 2018-02-24 12:13:14 convert to 2018-02-24 12:13:14 (withTime is false) * 2018-02-24 12:13:14 convert to 2018-02-24 12:13:14 February 24/12/13/14sec (withTime is true) * </pre> * *@param calendar {@link Calendar}
* @paramWithTime contains the time part *@returnFormatted string *@since5.3.9 * /
public static String formatChineseDate(Calendar calendar, boolean withTime) {
final StringBuilder result = StrUtil.builder();
/ / year
String year = String.valueOf(calendar.get(Calendar.YEAR));
final int length = year.length();
for (int i = 0; i < length; i++) {
result.append(NumberChineseFormatter.numberCharToChinese(year.charAt(i), false));
}
result.append('years');
/ / month
int month = calendar.get(Calendar.MONTH) + 1;
result.append(NumberChineseFormatter.format(month, false));
result.append('month');
/ /,
int day = calendar.get(Calendar.DAY_OF_MONTH);
result.append(NumberChineseFormatter.format(day, false));
result.append('day');
if (withTime) {
/ /
int hour = calendar.get(Calendar.HOUR_OF_DAY);
result.append(NumberChineseFormatter.format(hour, false));
result.append('when');
/ / points
int minute = calendar.get(Calendar.MINUTE);
result.append(NumberChineseFormatter.format(minute, false));
result.append('points');
/ / SEC.
int second = calendar.get(Calendar.SECOND);
result.append(NumberChineseFormatter.format(second, false));
result.append('秒');
}
return result.toString().replace('zero'.'〇');
}
Copy the code
According to the source code, it is converted by year, month, day, minute, second, each field.