学习一下java8中的新时间类型
JDK1.7中的时间日期类型主要有 Date Calendar TimeZone
//时间
Date date = new Date();
System.out.println(date);
//日期
Calendar calendar = Calendar.getInstance();
System.out.println(calendar);
//时区
TimeZone tz = TimeZone.getDefault();
System.out.println(tz);
显示如下:
Sat Oct 19 16:19:50 CST 2019
java.util.GregorianCalendar[time=1571473190198,areFieldsSet=true,areAllFieldsSet=true,lenient=true,zone=sun.util.calendar.ZoneInfo[id="Asia/Shanghai",offset=28800000,dstSavings=0,useDaylight=false,transitions=29,lastRule=null],firstDayOfWeek=1,minimalDaysInFirstWeek=1,ERA=1,YEAR=2019,MONTH=9,WEEK_OF_YEAR=42,WEEK_OF_MONTH=3,DAY_OF_MONTH=19,DAY_OF_YEAR=292,DAY_OF_WEEK=7,DAY_OF_WEEK_IN_MONTH=3,AM_PM=1,HOUR=4,HOUR_OF_DAY=16,MINUTE=19,SECOND=50,MILLISECOND=198,ZONE_OFFSET=28800000,DST_OFFSET=0]
sun.util.calendar.ZoneInfo[id="Asia/Shanghai",offset=28800000,dstSavings=0,useDaylight=false,transitions=29,lastRule=null]
/** * The classDate
represents a specific instant in time, with millisecond precision. * Although theDate
class is intended to reflect * coordinated universal time (UTC), it may not do so exactly, * depending on the host environment of the Java Virtual Machine. * Nearly all modern operating systems assume that 1 day = * 24 × 60 × 60 = 86400 seconds * in all cases. In UTC, however, about once every year or two there * is an extra second, called a "leap second." The leap * second is always added as the last second of the day, and always * on December 31 or June 30. For example, the last minute of the * year 1995 was 61 seconds long, thanks to an added leap second. * Most computer clocks are not accurate enough to be able to reflect * the leap-second distinction. ** Some computer standards are defined in terms of Greenwich mean * time (GMT), which is equivalent to universal time (UT). GMT is * the "civil" name for the standard; UT is the * "scientific" name for the same standard. The * distinction between UTC and UT is that UTC is based on an atomic * clock and UT is based on astronomical observations, which for all * practical purposes is an invisibly fine hair to split. Because the * earth's rotation is not uniform (it slows down and speeds up * in complicated ways), UT does not always flow uniformly. Leap * seconds are introduced as needed into UTC so as to keep UTC within * 0.9 seconds of UT1, which is a version of UT with certain * corrections applied. There are other time and date systems as * well; for example, the time scale used by the satellite-based * global positioning system (GPS) is synchronized to UTC but is * not adjusted for leap seconds.
/** * TheCalendar
class is an abstract class that provides methods * for converting between a specific instant in time and a set of {@link * #fields calendar fields} such asYEAR
,MONTH
, *DAY_OF_MONTH
,HOUR
, and so on, and for * manipulating the calendar fields, such as getting the date of the next * week. An instant in time can be represented by a millisecond value that is * an offset from the Epoch, January 1, 1970 * 00:00:00.000 GMT (Gregorian).
/** *TimeZone
represents a time zone offset, and also figures out daylight * savings. * ** Typically, you get a
TimeZone
usinggetDefault
* which creates aTimeZone
based on the time zone where the program * is running. For example, for a program running in Japan,getDefault
* creates aTimeZone
object based on Japanese Standard Time.
Date Calendar TimeZone都不是线程安全的,特别是在进行时间解析时,会出现并发异常
使用SimpleDateFormat来并发解析时间
@Test
public void testDateFormat() {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
ExecutorService executorService = Executors.newFixedThreadPool(5);
for(int i=0; i<20; i++){
//executorService.execute(() -> System.out.println(sdf.format(date)));
executorService.execute(() -> {
try {
//多线程解析会出现问题
sdf.parse("2019-10-19 14:51:50");
} catch (ParseException e) {
e.printStackTrace();
}
});
}
}
会出现异常如下
Exception in thread "pool-1-thread-3" Exception in thread "pool-1-thread-6" Exception in thread "pool-1-thread-4" java.lang.NumberFormatException: For input string: "11001.11001EE22"
at sun.misc.FloatingDecimal.readJavaFormatString(FloatingDecimal.java:2043)
at sun.misc.FloatingDecimal.parseDouble(FloatingDecimal.java:110)
at java.lang.Double.parseDouble(Double.java:538)
at java.text.DigitList.getDouble(DigitList.java:169)
at java.text.DecimalFormat.parse(DecimalFormat.java:2089)
at java.text.SimpleDateFormat.subParse(SimpleDateFormat.java:1869)
at java.text.SimpleDateFormat.parse(SimpleDateFormat.java:1514)
at java.text.DateFormat.parse(DateFormat.java:364)
at com.java.date.DateTest.lambda$testDateFormat$0(DateTest.java:62)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at java.lang.Thread.run(Thread.java:748)
可以使用ThreadLocal来避免并发错误
public class DateFormatThreadLocal {
private static final ThreadLocal threadLocal = ThreadLocal.withInitial(
() -> new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"));
public static Date convert(String str) throws ParseException {
return threadLocal.get().parse(str);
}
}
使用如下
@Test
public void testThreadLocal(){
ExecutorService executorService = Executors.newFixedThreadPool(5);
for(int i=0; i<20; i++){
executorService.execute(() -> {
try {
//使用ThreadLocal来避免多线程并发问题
DateFormatThreadLocal.convert("2019-10-19 14:51:50");
} catch (ParseException e) {
e.printStackTrace();
}
});
}
}
Java8中时间主要有
用户本地时间LocalDateTime
/** * A date-time without a time-zone in the ISO-8601 calendar system, * such as {@code 2007-12-03T10:15:30}. ** {@code LocalDateTime} is an immutable date-time object that represents a date-time, * often viewed as year-month-day-hour-minute-second. Other date and time fields, * such as day-of-year, day-of-week and week-of-year, can also be accessed. * Time is represented to nanosecond precision.
时间戳Instant
/** * An instantaneous point on the time-line. ** This class models a single instantaneous point on the time-line. * This might be used to record event time-stamps in the application. *
* The range of an instant requires the storage of a number larger than a {@code long}. * To achieve this, the class stores a {@code long} representing epoch-seconds and an * {@code int} representing nanosecond-of-second, which will always be between 0 and 999,999,999. * The epoch-seconds are measured from the standard Java epoch of {@code 1970-01-01T00:00:00Z} * where instants after the epoch have positive values, and earlier instants have negative values. * For both the epoch-second and nanosecond parts, a larger value is always later on the time-line * than a smaller value.
带时差的时间OffsetDateTime
/** * A date-time with an offset from UTC/Greenwich in the ISO-8601 calendar system, * such as {@code 2007-12-03T10:15:30+01:00}. ** {@code OffsetDateTime} is an immutable representation of a date-time with an offset. * This class stores all date and time fields, to a precision of nanoseconds, * as well as the offset from UTC/Greenwich. For example, the value * "2nd October 2007 at 13:45.30.123456789 +02:00" can be stored in an {@code OffsetDateTime}.
带时区的时间ZonedDateTime
/** * A date-time with a time-zone in the ISO-8601 calendar system, * such as {@code 2007-12-03T10:15:30+01:00 Europe/Paris}. ** {@code ZonedDateTime} is an immutable representation of a date-time with a time-zone. * This class stores all date and time fields, to a precision of nanoseconds, * and a time-zone, with a zone offset used to handle ambiguous local date-times. * For example, the value * "2nd October 2007 at 13:45.30.123456789 +02:00 in the Europe/Paris time-zone" * can be stored in a {@code ZonedDateTime}.
举例如下:
LocalDateTime 2019-10-19T16:48:16.764
Instant 2019-10-19T08:48:16.764Z
OffsetDateTime 2019-10-19T16:48:16.764+08:00
ZonedDateTime 2019-10-19T16:48:16.764+08:00[Asia/Shanghai]
Duration时间之间的间隔
/**
* A time-based amount of time, such as '34.5 seconds'.
*
* This class models a quantity or amount of time in terms of seconds and nanoseconds.
* It can be accessed using other duration-based units, such as minutes and hours.
* In addition, the {@link ChronoUnit#DAYS DAYS} unit can be used and is treated as
* exactly equal to 24 hours, thus ignoring daylight savings effects.
* See {@link Period} for the date-based equivalent to this class.
Period日期之间的间隔
/** * A date-based amount of time in the ISO-8601 calendar system, * such as '2 years, 3 months and 4 days'. ** This class models a quantity or amount of time in terms of years, months and days. * See {@link Duration} for the time-based equivalent to this class.
日期转换以及格式化示例如下:
@Test
public void testJava8NewDate(){
Instant i1 = Instant.now();
//时间戳 默认获取UTC时间 0时区时间
System.out.println(Instant.now());
//epoch 纪元 时代
System.out.println(Instant.now().toEpochMilli());
//进行时区转换,获取转换后时间 带有时差信息
OffsetDateTime offsetDateTime = Instant.now().atOffset(ZoneOffset.ofHours(8));
System.out.println(offsetDateTime);
Instant i2 = Instant.now();
//两个时间之间的间隔
Duration d = Duration.between(i1, i2);
System.out.println(d.toNanos());
//两个日期之间的间隔
Period p = Period.between(LocalDate.now(), LocalDate.of(2019, 11, 29));
System.out.println(p);
System.out.println(p.getMonths());
System.out.println(p.getDays());
//时间校正期
LocalDateTime ldt3 = LocalDateTime.now();
System.out.println(ldt3);
//指定日期为本月10号
System.out.println(ldt3.withDayOfMonth(10));
//下一个周六
System.out.println(ldt3.with(TemporalAdjusters.next(DayOfWeek.SATURDAY)));
//时间格式化
DateTimeFormatter isoZonedDateTime = DateTimeFormatter.ISO_DATE_TIME;
System.out.println(LocalDateTime.now().format(isoZonedDateTime));
DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
System.out.println(LocalDateTime.now().format(dateTimeFormatter));
//带时区的时间
ZonedDateTime z = ZonedDateTime.now();
System.out.println(z);
System.out.println(z.toLocalDateTime());
System.out.println("LocalDateTime " + LocalDateTime.now());
System.out.println("Instant " + Instant.now());
System.out.println("OffsetDateTime " + OffsetDateTime.now());
System.out.println("ZonedDateTime " + ZonedDateTime.now());
}
参考地址:https://www.bilibili.com/video/av35195879/?p=21