java获取时间t00:00:00.0z_全⾯解析Java⽇期时间API 时区
GMT(Greenwich Mean Time):格林尼治时间,格林尼治标准时间的正午是指当太阳横穿格林尼治⼦午线时(也就是在格林尼治上空最⾼点时)的时间。
UTC(Universal Time Coordinated):统⼀协调时间,其以原⼦时秒长为基础,在时刻上尽量接近于格林尼治标准时间,标准 UTC 时间格式 yyyy-MM-dd'T'HH:mm:ss.SSSXXX。
格林尼治时间已经不再被作为标准时间使⽤,UTC 是最主要的世界时间标准。
Java提供了获取当前时间的⽅法
System.currentTimeMillis(),返回当前时间,以毫秒为单位,表⽰的就是当前时刻⾄ 1970-01-01 00:00:00.000 的毫秒差值。返回的long值可以⽤来初始化java.util.Date, java.sql.Date, java.sql.Timestamp和java.util.GregorianCalendar对象。
System.nanoTime(),返回⼀个时间值(系统计时器的当前值),精确到纳秒。它是由 JVM 提供的⼀个时间,主要⽤来精确衡量两个时间段之间的时间
例如,要测量⼀些代码需要执⾏多长时间,实现如下,
long startTime = System.nanoTime();
//...the code being measured
long estimatedTime = System.nanoTime() - startTime;
时间粒度
事实上System.currentTimeMillis()⽅法的时间粒度是⼤于1毫秒的。如果你反复执⾏这个⽅法,你会发现短时间内得到的结果是相同的,随后⼜突然在某⼀次结果增加了⼏⼗毫秒(也可能更多)。这是很正常的,毕竟这个⽅法肯定不是世界上最精密的计时器。
旧的时间API
旧的时间API存在诸多问题,例如
Java的⽇期/时间类的定义并不⼀致,在java.util和java.sql的包中都有⽇期类,此外⽤于格式化和解析的类在包中定义。
java.util.Date同时包含⽇期和时间,⽽java.sql.Date仅包含⽇期,将其纳⼊java.sql包并不合理。另外这两个类都有相同的名字,这本⾝就是⼀个⾮常糟糕的设计。
对于时间、时间戳、格式化以及解析,并没有⼀些明确定义的类。对于格式化和解析的需求,我们有DateFormat抽象类,但通常情况下,SimpleDateFormat类被⽤于此类需求。
所有的⽇期类都是可变的,因此他们都不是线程安全的,这是Java⽇期类最⼤的问题之⼀。
⽇期类并不提供国际化,没有时区⽀持,因此Java引⼊了java.util.Calendar和java.util.TimeZone类,但他们同样存在上述所有的问题。
java.util.Date类
java.util.Date类⽤于封装⽇期及时间信息,⼀般仅⽤它显⽰某个⽇期,不对他作任何操作处理,作处理推荐⽤Calendar类,计算⽅便。以下已过时的⽅法没有列出,可⾃⾏查看jdk⽂档
构造⽅法
Date() :分配 Date对象并初始化此对象,以表⽰分配它的时间(精确到毫秒)。
Date(long date):分配 Date对象并初始化此对象,以表⽰⾃从标准基准时间(称为“历元(epoch)”,即 1970 年 1 ⽉ 1 ⽇ 00:00:00 GMT)以来的指定毫秒数。
//1、使⽤Date类获取当前系统时间
Date date = new Date();
System.out.println(date);
//由于Date类覆盖了toString()⽅法,所以可以直接输出Date类型的对象
//输出结果为Fri May 31 10:51:18 GMT+08:00 2019
/*给Date设置年份需要减去 1900
*输出结果Tue Jul 01 00:00:00 GMT+08:00 3919
*原来这⾥存在⼀个起始年份 1900,实际年份是要在你的年份参数上加上个起始年份。
*/
Date date1 = new Date(2019,5,31);
System.out.println(date1);
//2.分配 Date 对象并初始化此对象,以表⽰⾃从标准基准时间(称为“历元(epoch)”,即 1970 年 1 ⽉ 1 ⽇ 00:00:00 GMT)以来的指定毫秒数。
Date date2 = new Date(System.currentTimeMillis());//参数为19701⽉1⽇以来的毫秒数
Date date3 = new Date(1559284293556l); //long类型要加l
System.out.println(date2);
System.out.println(date3);
//其他Date⽅法摘要可查看api
Calendar类与GregorianCalendar
java.util.Calendar类⽤于封装⽇历信息,其主作⽤在于其⽅法可以对时间分量进⾏运算。Calendar类是⼀个抽象类,它为特定瞬间与⼀组诸如 YEAR、MONTH、DAY_OF_MONTH、HOUR 等 ⽇历字段之间的转换提供了⼀些⽅法,并为操作⽇历字段(例如获得下星期的⽇期)提供了⼀些⽅法。
由于Calendar类是抽象类,且Calendar类的构造⽅法是protected的,所以⽆法使⽤Calendar类的构造⽅法来创建对象,API中提供了getInstance⽅法⽤来创建对象。
Java只提供java.util.GregorianCalendar这⼀种java.util.Calendar的实现类,可以直接新建出来使⽤:
Calendar calendar = new GregorianCalendar();//新建出来的calendar默认时间为当前时间,或者说创建出这个对象的时间。
通过Calendar的静态⽅法获取⼀个实例该⽅法会根据当前系统所在地区来⾃⾏决定时区,帮我们创建Calendar实例,这⾥要注意,实际上根据不同的地区,Calendar有若⼲个⼦类实现。⽽Calendar本⾝是抽象类,不能被实例化!我们不需要关⼼创建的具体实例为哪个⼦类,我们只需要根据Calendar规定的⽅法来使⽤就可以了。
⽇历类所解决的根本问题是简化⽇期的计算,要想表⽰某个⽇期还应该使⽤Date类描述。Calendar是可以将其描述的时间转化为Date的,我们只需要调⽤其getTime()⽅法就可以获取描述的⽇期的Date对象了。
通过⽇历类计算时间:为⽇历类设置时间,⽇历类设置时间使⽤通⽤⽅法set。set(int field,int value),field为时间分量,Calendar提供了相应的常量值,value为对应的值。
只有⽉份从0开始:0为1⽉,以此类推,11为12⽉,其他时间是正常的从1开始。也可以使⽤Calendar的常量
calendar.NOVEMBER……等。
Calendar.DAY_OF_MONTH ⽉⾥边的天---号;
Calendar.DAY_OF_WEEK 星期⾥的天---星期⼏
Calendar.DAY_OF_YEAR 年⾥的天
Calendar Instance();//构造出来表⽰当前时间的⽇历类
Date Time();//获取⽇历所描述的⽇期
calendar.set(Calendar.YEAR, 2019);//设置⽇历表⽰2019年 calendar.set(Calendar.DAY_OF_MONTH,15);//设置⽇历表⽰15号
calendar.add(Calendar.DAY_OF_YEAR, 22);//想得到22天以后是哪天
calendar.add(Calendar.DAY_OF_YEAR, -5);//5天以前是哪天
calendar.add(Calendar.MONTH, 1);得到1个⽉后是哪天
System.out.Time());
获取当前⽇历表⽰的⽇期中的某个时间单位可以使⽤get⽅法。
int year = (Calendar.YEAR);
int month = (Calendar.MONTH)
int day = (Calendar.DAY_OF_MONTH);
System.out.println(year+"年"+(month+1)+"⽉"+day+"⽇");//month要处理
SimpleDateFormat类
常⽤构造⽅法
SimpleDateFormat(String pattern),pattern -为描述⽇期和时间格式的模式
⽤给定的模式和默认语⾔环境的⽇期格式符号构造 SimpleDateFormat。 注:此构造⽅法可能不⽀持所有语⾔环境。要覆盖所有语⾔环境,请使⽤ DateFormat 类中的⼯⼚⽅法。
常⽤⽅法
public final String format(Date date)将⼀个 Date 格式化为⽇期/时间字符串
public Date parse(String source)throws ParseException从给定字符串的开始解析⽂本,以⽣成⼀个⽇期。
字符串转成Date对象
//创建⼀个SimpleDateFormat并且告知它要读取的字符串格式
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
String dateFormat = "2019-05-31";//创建⼀个⽇期格式字符串
//将⼀个字符串转换为相应的Date对象
Date date = sdf.parse(dateFormat);//要先捕获异常
System.out.println(date);//输出这个Date对象
Date对象转成字符串
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
Date date = new Date();
String dateStr = sdf.format(date);//把⽇期对象传进去,继承⾃DateFormat类的⽅法。将⼀个Date格式化为⽇期/时间字符串
在⽇期格式中,-和空格⽆特殊意义。⽆特殊含义的都原样输出
//将当前系统时间转换为2012/05/14 17:05:22的效果
SimpleDateFormat format1 = new SimpleDateFormat("yyyy/MM/dd hh:mm:ss");
dateStr=format1.format(date);
System.out.println(dateStr);
DateFormat类
java.sql.Date
java.sql.Date继承java.util.Date,为了把前者转为后者,需要以下代码
Date date = new Date();
//java.sql.Date 不⽀持Date参数的构造器,传⼊long类型的时间
java.sql.Date d = new java.sql.Time());
System.out.println(d);
System.out.Hours());
输出结果
2019-05-31
Exception in thread "main" java.lang.IllegalArgumentException
at java.Hours(Unknown Source)
at DateTest.DateTest1.main(DateTest1.java:40)
这是由于java.sql.Date是SQL中的单纯的⽇期类型,没有时分秒。故⼀般通过JDBC插⼊java.sql.Date数据时,会发现时分秒都没有。因此,如果同时需要⽇期和时间,应该使⽤Timestamp。它也是 java.util.Date 的⼦类,Timestamp 则包含时间戳的完整信息。
java.sql.Timestamp是java.util.Date的派⽣类(继承),所以在java.util.Date上能做的事,也可以在java.sql.Timestamp上做。
如果当前是2019-06-01 14:35,你创建⼀个java.sql.Date 将只记下2019-06-01这个信息。若你需要保留时间进⾏JDBC操作,请使⽤java.sql.Timestamp代替。
long time = System.currentTimeMillis();
java.sql.Timestamp timestamp = new java.sql.Timestamp(time);
timestamp.setNanos(123456);
int nanos = Nanos(); // nanos = 123456
现在的Date类中⼤部分⽅法已经弃⽤,现在⼀般使⽤旧的API,Date只负责存储⼀个时间,并对Calendar和DateFormat提供操作接⼝。Calendar获取Date中特定的信息,对⽇期时间进⾏操作,SimpleDateFormat对⽇期时间进⾏格式化输⼊输出。
总的来说,Date、Calendar 和 DateFormat 已经能够处理⼀般的时间⽇期问题了。但是不可避免的是,它们依然很繁琐,不好⽤并且这些⽇期类都是可变且线程不安全的
Joda-Time
Java 8 时间⽇期API
特性
不变性:新的⽇期/时间API中,所有的类都是不可变的,这对多线程很有好处。
关注点分离:借鉴了Joda库的⼀些优点,新的API将⼈可读的⽇期时间和机器时间(unix timestamp)明确分离,它为⽇期(Date)、时间(Time)、⽇期时间(DateTime)、时间戳(unix timestamp)以及时区定义了不同的类。
清晰:在所有的类中,⽅法都被明确定义⽤以完成相同的⾏为。例如要拿到当前实例我们可以使⽤now()⽅法,在所有的类中都定义了format()和parse()⽅法,⽽不是像以前那样专门有⼀个独⽴的类。为了更好的处理问题,所有的类都使⽤了⼯⼚模式和策略模式,⼀旦你使⽤了其中某个类的⽅法,与其他类协同⼯作并不困难。
实⽤操作:所有新的⽇期/时间API类都实现了⼀系列⽅法⽤以完成通⽤的任务,如:加、减、格式化、解析、从⽇期/时间中提取单独部分,等等。
可扩展性:新的⽇期/时间API是⼯作在ISO-8601⽇历系统上的,但我们也可以将其应⽤在⾮IOS的⽇历上。
Java8⽇期时间的默认格式如下:
⼏个主要的核⼼类:
LocalDate:⽇期类,不带时间
LocalTime:时间类,不带⽇期
LocalDateTime:⽇期和时间类
ZonedDateTime:时区⽇期时间类
string转date的方法OffsetDateTime:按UTC时间偏移来得到⽇期时间
Clock:获取某个时区下当前的瞬时时间,⽇期或者时间
Instant:Unix时间,代表时间戳,⽐如 2018-01-14T02:20:13.592Z
Duration:两个时间之间,表⽰⼀个绝对的精确跨度,使⽤毫秒为单位
Period:两个⽇期之间
ZoneId:时区
DateTimeFormatter:格式化输出
TemporalAdjusters:获得指定⽇期时间等,如当⽉的第⼀天、今年的最后⼀天等等
下⾯看看这些类具体如何使⽤
LocalDate、LocalTime、LocalDateTime
LocalDate是不变的⽇期时间对象代表⼀个⽇期,往往被视为年⽉⽇。其他⽇期字段,如⼀年中的⼀天,⼀周和⼀周的⼀天,也可以访问。例如,“2007年10⽉2⽇”的值可以被存储在⼀个LocalDate。
LocalTime是不变的⽇期时间对象代表⼀个时间,往往被视为⼩时分钟秒。时间为代表的纳秒级精度。例如,
值“13:45.30.123456789”可以存储在⼀个LocalTime。
LocalDateTime是不变的⽇期时间对象代表⼀个⽇期时间,往往被视为年、⽉、⽇、时、分、秒。其
他⽇期和时间字段,如⼀年中的⼀天,⼀周和⼀周的⼀天,也可以访问。时间为代表的纳秒级精度。例如,值“2007年10⽉2⽇在13:45.30.123456789”可以存储在⼀个LocalDateTime。
//now()在默认时区中从系统时钟获取当前⽇期。
LocalDate today = w();
LocalDate nextWeek = today.plus(1, ChronoUnit.WEEKS); //等价于 today.plusWeeks(1)
//of(int year, int month, int dayOfMonth) 获得 LocalDate实例从⼀年、⽉、⽇。
LocalDate date = LocalDate.of(2019,5,31);
LocalTime time = LocalTime.of(20,31,20);
//of(LocalDate date, LocalTime time) 获得 LocalDateTime实例的⽇期和时间。
LocalDateTime dateTime = LocalDateTime.of(date,time);
System.out.println(dateTime);
//LocalDate结合LocalTime成⼀个LocalDateTime
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论