Java 中,怎么在java 日期格式化 时区的日期中显示时区

博客分类:
java编程的过程中,一般都会用到日期时间的处理,既然涉及到时间,那肯定就存在时区的问题。一般情况下,我们都是使用操作系统的时区,所以不用指定时区,java会自动使用系统的时区作为缺省时区。应用代码中也就不涉及到指定时区的问题了。
但是,在aws公有云ec2实例里面运行的java程序,就需要格外注意缺省时区的问题了,因为ec2本身属于虚拟机,启动实例的时候需要指定ami镜像,也就是操作系统镜像,这个镜像如果没有配置时区,那么很可能是utc时区,或者是别的时区,所以,你的java 程序用的缺省时区可能就不是你所期望的时区了。这样你的日期相关的程序就会出现问题。可能在本地开发的时候,你的本地环境是本地的时区,而放到生产环境下,时区就不一定了。 所以,在开发aws云应用的时候,要特别注意在你的java 程序里面指定缺省时区,或者通过java入口参数来指定。
还有一种情况,如果你的程序需要部署到docker 里面运行,也存在这个问题。
一般在main 方法的一开始就指定缺省时区,TimeZone.setDefault(TimeZone.getTimeZone("GMT"))
blogzhoubo
浏览: 118028 次
来自: 大连
赞一个! 好文,但实际测试后发现第一次 浏览器也木有把url
写的很好啊~~~
小蝶兒 写道这样子和直接放在head里有什么区别呐,还是没有解 ...
(window.slotbydup=window.slotbydup || []).push({
id: '4773203',
container: s,
size: '200,200',
display: 'inlay-fix'博客分类:
一 获取DateTimeFormatter对象的三种方式
直接使用静态常量创建DateTimeFormatter格式器
使用代码不同风格的枚举值来创建DateTimeFormatter格式器
根据模式字符串来创建DateTimeFormatter格式器
二 DateTimeFormatter完成格式化1 代码示例
import java.time.*;
import java.time.format.*;
public class NewFormatterTest
public static void main(String[] args)
DateTimeFormatter[] formatters = new DateTimeFormatter[]{
// 直接使用常量创建DateTimeFormatter格式器
DateTimeFormatter.ISO_LOCAL_DATE,
DateTimeFormatter.ISO_LOCAL_TIME,
DateTimeFormatter.ISO_LOCAL_DATE_TIME,
// 使用本地化的不同风格来创建DateTimeFormatter格式器
DateTimeFormatter.ofLocalizedDateTime(FormatStyle.FULL, FormatStyle.MEDIUM),
DateTimeFormatter.ofLocalizedTime(FormatStyle.LONG),
// 根据模式字符串来创建DateTimeFormatter格式器
DateTimeFormatter.ofPattern("Gyyyy%%MMM%%dd HH:mm:ss")
LocalDateTime date = LocalDateTime.now();
// 依次使用不同的格式器对LocalDateTime进行格式化
for(int i = 0 ; i & formatters. i++)
// 下面两行代码的作用相同
System.out.println(date.format(formatters[i]));
System.out.println(formatters[i].format(date));
2 运行结果
12:18:33.55712:18:33.557T12:18:33.557T12:18:33.557日 星期日 12:18:33日 星期日 12:18:33下午12时18分33秒下午12时18分33秒公元2016%%九月%%04 12:18:33公元2016%%九月%%04 12:18:333 代码说明
上面代码使用3种方式创建了6个DateTimeFormatter对象,然后程序中使用不同方式来格式化日期。
三 DateTimeFormatter解析字符串1 代码示例
import java.time.*;
import java.time.format.*;
public class NewFormatterParse
public static void main(String[] args)
// 定义一个任意格式的日期时间字符串
String str1 = " 01时06分09秒";
// 根据需要解析的日期、时间字符串定义解析所用的格式器
DateTimeFormatter fomatter1 = DateTimeFormatter
.ofPattern("yyyy==MM==dd HH时mm分ss秒");
// 执行解析
LocalDateTime dt1 = LocalDateTime.parse(str1, fomatter1);
System.out.println(dt1); // 输出 T01:06:09
// ---下面代码再次解析另一个字符串---
String str2 = "2014$$$四月$$$13 20小时";
DateTimeFormatter fomatter2 = DateTimeFormatter
.ofPattern("yyy$$$MMM$$$dd HH小时");
LocalDateTime dt2 = LocalDateTime.parse(str2, fomatter2);
System.out.println(dt2); // 输出 T20:00
2 运行结果
T01:06:09T20:00
3 代码说明
上面代码定义了两个不同格式日期、时间字符串。为了解析他们,代码分别使用对应的格式字符串创建了DateTimeFormatter对象,这样DateTimeFormatter即可按照格式化字符串将日期、时间字符串解析成LocalDateTime对象。
浏览: 347390 次
来自: 西安
你不如直接把mdn的连接放上来, 看的格式还清楚些...S ...
最常用的都列举出来了,很好
这都能上首页博文推荐,javaeye真不行了
(window.slotbydup=window.slotbydup || []).push({
id: '4773203',
container: s,
size: '200,200',
display: 'inlay-fix'Java 日期时间
java.util 包提供了 Date 类来封装当前的日期和时间。
Date 类提供两个构造函数来实例化 Date 对象。
第一个构造函数使用当前日期和时间来初始化对象。
第二个构造函数接收一个参数,该参数是从日起的毫秒数。
Date(long millisec)
Date对象创建以后,可以调用下面的方法。
方法和描述
boolean after(Date date)
若当调用此方法的Date对象在指定日期之后返回true,否则返回false。
boolean before(Date date)
若当调用此方法的Date对象在指定日期之前返回true,否则返回false。
Object clone( )
返回此对象的副本。
int compareTo(Date date)
比较当调用此方法的Date对象和指定日期。两者相等时候返回0。调用对象在指定日期之前则返回负数。调用对象在指定日期之后则返回正数。
int compareTo(Object obj)
若obj是Date类型则操作等同于compareTo(Date) 。否则它抛出ClassCastException。
boolean equals(Object date)
当调用此方法的Date对象和指定日期相等时候返回true,否则返回false。
long getTime( )
返回自 1970 年 1 月 1 日 00:00:00 GMT 以来此 Date 对象表示的毫秒数。
int hashCode( )
&返回此对象的哈希码值。
void setTime(long time)
用自日00:00:00 GMT以后time毫秒数设置时间和日期。
String toString( )
把此 Date 对象转换为以下形式的 String: dow mon dd hh:mm:ss zzz yyyy 其中: dow 是一周中的某一天 (Sun, Mon, Tue, Wed, Thu, Fri, Sat)。
获取当前日期时间
Java中获取当前日期和时间很简单,使用 Date 对象的 toString() 方法来打印当前日期和时间,如下所示:
import java.util.Date;
public class DateDemo {
public static void main(String args[]) {
Date date = new Date();
System.out.println(date.toString());
以上实例编译运行结果如下:
Mon May 04 09:51:52 CDT 2013
Java使用以下三种方法来比较两个日期:
使用 getTime() 方法获取两个日期(自日经历的毫秒数值),然后比较这两个值。
使用方法 before(),after() 和 equals()。例如,一个月的12号比18号早,则 new Date(99, 2, 12).before(new Date (99, 2, 18)) 返回true。
使用 compareTo() 方法,它是由 Comparable 接口定义的,Date 类实现了这个接口。
使用 SimpleDateFormat 格式化日期
SimpleDateFormat 是一个以语言环境敏感的方式来格式化和分析日期的类。SimpleDateFormat 允许你选择任何用户自定义日期时间格式来运行。例如:
import java.util.*;
import java.text.*;
public class DateDemo {
public static void main(String args[]) {
Date dNow = new Date( );
SimpleDateFormat ft = new SimpleDateFormat (&E yyyy.MM.dd 'at' hh:mm:ss a zzz&);
System.out.println(&Current Date: & + ft.format(dNow));
SimpleDateFormat ft = new SimpleDateFormat ("E yyyy.MM.dd 'at' hh:mm:ss a zzz");
这一行代码确立了转换的格式,其中 yyyy 是完整的公元年,MM 是月份,dd 是日期,HH:mm:ss 是时、分、秒。
注意:有的格式大写,有的格式小写,例如 MM 是月份,mm 是分;HH 是 24 小时制,而 hh 是 12 小时制。
以上实例编译运行结果如下:
Current Date: Wed
at 08:23:19 AM UTC
日期和时间的格式化编码
时间模式字符串用来指定时间格式。在此模式中,所有的 ASCII 字母被保留为模式字母,定义如下:
July or 07
一个月的日期
&A.M./P.M. (1~12)格式小时
一天中的小时 (0~23)
一年中的日子
一个月中第几周的周几
2 (second Wed. in July)
一年中第几周
一个月中第几周
A.M./P.M. 标记
一天中的小时(1~24)
&A.M./P.M. (0~11)格式小时
Eastern Standard Time
文字定界符
使用printf格式化日期
printf 方法可以很轻松地格式化时间和日期。使用两个字母格式,它以 %t 开头并且以下面表格中的一个字母结尾。
转& 换& 符
包括全部日期和时间信息
星期六 十月 27 14:21:20 CST 2007
"年-月-日"格式
"月/日/年"格式
"HH:MM:SS PM"格式(12时制)
02:25:51 下午
"HH:MM:SS"格式(24时制)
"HH:MM"格式(24时制)
更多 printf 解析可以参见:
import java.util.Date;
public class DateDemo {
public static void main(String args[]) {
Date date = new Date();
System.out.printf(&全部日期和时间信息:%tc%n&,date);
System.out.printf(&年-月-日格式:%tF%n&,date);
System.out.printf(&月/日/年格式:%tD%n&,date);
System.out.printf(&HH:MM:SS PM格式(12时制):%tr%n&,date);
System.out.printf(&HH:MM:SS格式(24时制):%tT%n&,date);
System.out.printf(&HH:MM格式(24时制):%tR&,date);
以上实例编译运行结果如下:
全部日期和时间信息:星期一 九月 10 10:43:36 CST 2012
年-月-日格式:
月/日/年格式:09/10/12
HH:MM:SS PM格式(12时制):10:43:36 上午
HH:MM:SS格式(24时制):10:43:36
HH:MM格式(24时制):10:43
如果你需要重复提供日期,那么利用这种方式来格式化它的每一部分就有点复杂了。因此,可以利用一个格式化字符串指出要被格式化的参数的索引。
索引必须紧跟在%后面,而且必须以$结束。例如:
import java.util.Date;
public class DateDemo {
public static void main(String args[]) {
Date date = new Date();
System.out.printf(&%1$s %2$tB %2$td, %2$tY&,
&Due date:&, date);
以上实例编译运行结果如下:
Due date: February 09, 2014
或者,你可以使用 & 标志。它表明先前被格式化的参数要被再次使用。例如:
import java.util.Date;
public class DateDemo {
public static void main(String args[]) {
Date date = new Date();
System.out.printf(&%s %tB %&te, %&tY&,
&Due date:&, date);
以上实例编译运行结果如下:
Due date: February 09, 2014
定义日期格式的转换符可以使日期通过指定的转换符生成新字符串。这些日期转换符如下所示:
import java.util.*;
public class DateDemo {
public static void main(String args[]) {
Date date=new Date();
String str=String.format(Locale.US,&英文月份简称:%tb&,date);
System.out.println(str);
System.out.printf(&本地月份简称:%tb%n&,date);
str=String.format(Locale.US,&英文月份全称:%tB&,date);
System.out.println(str);
System.out.printf(&本地月份全称:%tB%n&,date);
str=String.format(Locale.US,&英文星期的简称:%ta&,date);
System.out.println(str);
System.out.printf(&本地星期的简称:%tA%n&,date);
System.out.printf(&年的前两位数字(不足两位前面补0):%tC%n&,date);
System.out.printf(&年的后两位数字(不足两位前面补0):%ty%n&,date);
System.out.printf(&一年中的天数(即年的第几天):%tj%n&,date);
System.out.printf(&两位数字的月份(不足两位前面补0):%tm%n&,date);
System.out.printf(&两位数字的日(不足两位前面补0):%td%n&,date);
System.out.printf(&月份的日(前面不补0):%te&,date);
输出结果为:
英文月份简称:May
本地月份简称:五月
英文月份全称:May
本地月份全称:五月
英文星期的简称:Thu
本地星期的简称:星期四
年的前两位数字(不足两位前面补0):20
年的后两位数字(不足两位前面补0):17
一年中的天数(即年的第几天):124
两位数字的月份(不足两位前面补0):05
两位数字的日(不足两位前面补0):04
月份的日(前面不补0):4
解析字符串为时间
SimpleDateFormat 类有一些附加的方法,特别是parse(),它试图按照给定的SimpleDateFormat 对象的格式化存储来解析字符串。例如:
import java.util.*;
import java.text.*;
public class DateDemo {
public static void main(String args[]) {
SimpleDateFormat ft = new SimpleDateFormat (&yyyy-MM-dd&);
String input = args.length == 0 ? && : args[0];
System.out.print(input + & Parses as &);
t = ft.parse(input);
System.out.println(t);
} catch (ParseException e) {
System.out.println(&Unparseable using & + ft);
以上实例编译运行结果如下:
$ java DateDemo
Parses as Wed Nov 11 00:00:00 GMT 1818
$ java DateDemo
Parses as Sat Dec 01 00:00:00 GMT 2007
Java 休眠(sleep)
sleep()使当前线程进入停滞状态(阻塞当前线程),让出CPU的使用、目的是不让当前线程独自霸占该进程所获的CPU资源,以留一定时间给其他线程执行的机会。
你可以让程序休眠一毫秒的时间或者到您的计算机的寿命长的任意段时间。例如,下面的程序会休眠3秒:
import java.util.*;
public class SleepDemo {
public static void main(String args[]) {
System.out.println(new Date( ) + &\n&);
Thread.sleep(1000*3);
System.out.println(new Date( ) + &\n&);
} catch (Exception e) {
System.out.println(&Got an exception!&);
以上实例编译运行结果如下:
Thu Sep 17 10:20:30 CST 2015
Thu Sep 17 10:20:33 CST 2015
下面的一个例子表明如何测量时间间隔(以毫秒为单位):
import java.util.*;
public class DiffDemo {
public static void main(String args[]) {
long start = System.currentTimeMillis( );
System.out.println(new Date( ) + &\n&);
Thread.sleep(5*60*10);
System.out.println(new Date( ) + &\n&);
long end = System.currentTimeMillis( );
long diff = end - start;
System.out.println(&Difference is : & + diff);
} catch (Exception e) {
System.out.println(&Got an exception!&);
以上实例编译运行结果如下:
Fri Jan 08 09:48:47 CST 2016
Fri Jan 08 09:48:50 CST 2016
Difference is : 3019
Calendar类
我们现在已经能够格式化并创建一个日期对象了,但是我们如何才能设置和获取日期数据的特定部分呢,比如说小时,日,或者分钟? 我们又如何在日期的这些部分加上或者减去值呢? 答案是使用Calendar 类。
Calendar类的功能要比Date类强大很多,而且在实现方式上也比Date类要复杂一些。
Calendar类是一个抽象类,在实际使用时实现特定的子类的对象,创建对象的过程对程序员来说是透明的,只需要使用getInstance方法创建即可。
创建一个代表系统当前日期的Calendar对象
Calendar c = Calendar.getInstance();//默认是当前日期
创建一个指定日期的Calendar对象
使用Calendar类代表特定的时间,需要首先创建一个Calendar的对象,然后再设定该对象中的年月日参数来完成。
//创建一个代表日的Calendar对象
Calendar c1 = Calendar.getInstance();
c1.set(2009, 6 - 1, 12);
Calendar类对象字段类型
Calendar类中用以下这些常量表示不同的意义,jdk内的很多类其实都是采用的这种思想
Calendar.YEAR年份
Calendar.MONTH月份
Calendar.DATE日期
Calendar.DAY_OF_MONTH日期,和上面的字段意义完全相同
Calendar.HOUR12小时制的小时
Calendar.HOUR_OF_DAY24小时制的小时
Calendar.MINUTE分钟
Calendar.SECOND秒
Calendar.DAY_OF_WEEK星期几
Calendar类对象信息的设置
如:Calendar c1 = Calendar.getInstance();
public final void set(int year,int month,int date)
c1.set(2009, 6 - 1, 12);//把Calendar对象c1的年月日分别设这为:
利用字段类型设置
如果只设定某个字段,例如日期的值,则可以使用如下set方法:
public void set(int field,int value)
把 c1对象代表的日期设置为10号,其它所有的数值会被重新计算
c1.set(Calendar.DATE,10);
把c1对象代表的年份设置为2008年,其他的所有数值会被重新计算
c1.set(Calendar.YEAR,2008);
其他字段属性set的意义以此类推
Calendar c1 = Calendar.getInstance();
把c1对象的日期加上10,也就是c1也就表示为10天后的日期,其它所有的数值会被重新计算
c1.add(Calendar.DATE, 10);
把c1对象的日期减去10,也就是c1也就表示为10天前的日期,其它所有的数值会被重新计算
c1.add(Calendar.DATE, -10);
其他字段属性的add的意义以此类推
Calendar类对象信息的获得
Calendar c1 = Calendar.getInstance();
int year = c1.get(Calendar.YEAR);
int month = c1.get(Calendar.MONTH) + 1;
int date = c1.get(Calendar.DATE);
int hour = c1.get(Calendar.HOUR_OF_DAY);
int minute = c1.get(Calendar.MINUTE);
int second = c1.get(Calendar.SECOND);
int day = c1.get(Calendar.DAY_OF_WEEK);
GregorianCalendar类
Calendar类实现了公历日历,GregorianCalendar是Calendar类的一个具体实现。
Calendar 的getInstance()方法返回一个默认用当前的语言环境和时区初始化的GregorianCalendar对象。GregorianCalendar定义了两个字段:AD和BC。这是代表公历定义的两个时代。
下面列出GregorianCalendar对象的几个构造方法:
构造函数和说明
GregorianCalendar()
在具有默认语言环境的默认时区内使用当前时间构造一个默认的 GregorianCalendar。
GregorianCalendar(int year, int month, int date)
在具有默认语言环境的默认时区内构造一个带有给定日期设置的 GregorianCalendar
GregorianCalendar(int year, int month, int date, int hour, int minute)
为具有默认语言环境的默认时区构造一个具有给定日期和时间设置的 GregorianCalendar。
GregorianCalendar(int year, int month, int date, int hour, int minute, int second)
& 为具有默认语言环境的默认时区构造一个具有给定日期和时间设置的 GregorianCalendar。
GregorianCalendar(Locale aLocale)
在具有给定语言环境的默认时区内构造一个基于当前时间的 GregorianCalendar。
GregorianCalendar(TimeZone zone)
在具有默认语言环境的给定时区内构造一个基于当前时间的 GregorianCalendar。
GregorianCalendar(TimeZone zone, Locale aLocale)
&在具有给定语言环境的给定时区内构造一个基于当前时间的 GregorianCalendar。
这里是GregorianCalendar 类提供的一些有用的方法列表:
方法和说明
void add(int field, int amount)
根据日历规则,将指定的(有符号的)时间量添加到给定的日历字段中。
protected void computeFields()
转换UTC毫秒值为时间域值
protected void computeTime()
覆盖Calendar ,转换时间域值为UTC毫秒值
boolean equals(Object obj)
比较此 GregorianCalendar 与指定的 Object。
int get(int field)
获取指定字段的时间值
int getActualMaximum(int field)
返回当前日期,给定字段的最大值
int getActualMinimum(int field)
返回当前日期,给定字段的最小值
int getGreatestMinimum(int field)
&返回此 GregorianCalendar 实例给定日历字段的最高的最小值。
Date getGregorianChange()
获得格里高利历的更改日期。
int getLeastMaximum(int field)
返回此 GregorianCalendar 实例给定日历字段的最低的最大值
int getMaximum(int field)
返回此 GregorianCalendar 实例的给定日历字段的最大值。
Date getTime()
获取日历当前时间。
long getTimeInMillis()
获取用长整型表示的日历的当前时间
TimeZone getTimeZone()
获取时区。
int getMinimum(int field)
返回给定字段的最小值。
int hashCode()
重写hashCode.
boolean isLeapYear(int year)
确定给定的年份是否为闰年。
void roll(int field, boolean up)
在给定的时间字段上添加或减去(上/下)单个时间单元,不更改更大的字段。
void set(int field, int value)
用给定的值设置时间字段。
void set(int year, int month, int date)
设置年、月、日的值。
void set(int year, int month, int date, int hour, int minute)
设置年、月、日、小时、分钟的值。
void set(int year, int month, int date, int hour, int minute, int second)
设置年、月、日、小时、分钟、秒的值。
void setGregorianChange(Date date)
设置 GregorianCalendar 的更改日期。
void setTime(Date date)
用给定的日期设置Calendar的当前时间。
void setTimeInMillis(long millis)
用给定的long型毫秒数设置Calendar的当前时间。
void setTimeZone(TimeZone value)
用给定时区值设置当前时区。
String toString()
返回代表日历的字符串。
import java.util.*;
public class GregorianCalendarDemo {
public static void main(String args[]) {
String months[] = {
&Jan&, &Feb&, &Mar&, &Apr&,
&May&, &Jun&, &Jul&, &Aug&,
&Sep&, &Oct&, &Nov&, &Dec&};
GregorianCalendar gcalendar = new GregorianCalendar();
System.out.print(&Date: &);
System.out.print(months[gcalendar.get(Calendar.MONTH)]);
System.out.print(& & + gcalendar.get(Calendar.DATE) + & &);
System.out.println(year = gcalendar.get(Calendar.YEAR));
System.out.print(&Time: &);
System.out.print(gcalendar.get(Calendar.HOUR) + &:&);
System.out.print(gcalendar.get(Calendar.MINUTE) + &:&);
System.out.println(gcalendar.get(Calendar.SECOND));
if(gcalendar.isLeapYear(year)) {
System.out.println(&当前年份是闰年&);
System.out.println(&当前年份不是闰年&);
以上实例编译运行结果如下:
Date: Apr 22 2009
Time: 11:25:27
当前年份不是闰年
关于 Calender 类的完整列表,你可以参考标准的 。
6个月前 (11-22)
感谢您的支持,我会继续努力的!
扫码打赏,你说多少就多少
记住登录状态
重复输入密码Java中的时间和日期(下)
在上篇文章中的时间和日期(上)里面,简单介绍了Java中的Date类,Calendar类以及用于格式化的SimpleDateFormater类。使用这些的时候我们会明显地感受到其中的不便之处,比如,Calendar类的月份是从0开始计数的;日期格式输出不够友好,很多情况下都需要使用SimpleDateFormater类来格式化;一些简单得日期计算也比较麻烦等等。所以就有了joda-time这种第三方库来简化java对于时间和日期的操作。为了改变这种情况,java 8中对时间和日期对处理就吸收了joda-time库的特性。那么新的时间日期处理会带来怎样的便捷呢?这便是本篇文章所要聊的内容。
月份和星期的枚举类
在以前使用Java的时候,你一定痛恨了月份的表示和计算,最主要的原因就是因为一月份是从0开始计数的。而在Java 8中为了改变这一现状,增加了一个Month枚举类来表示月份。使用这个枚举类甚至还可以直接进行月份的加减运算!
of(int month)
这是一个静态方法,用于创建一个Month对象。传入的参数当然是从1开始计数啦,1表示一月,12表示十二月。当传入的参数小于1或者大于12时,就会抛出异常。
getValue()
返回该Month对象当前的值。一月份返回1,二月份返回2,依次类推。
minus(long months)
这个是用来做月份的减法计算的。传入的参数表示你想在该Month对象的基础上减去几个月。如果是1月份减去2个月,返回的当然是11月份。
plus(long months)
用来计算月份的加法。传入的参数表示你想在该Month对象的基础上增加几个月。比如12月加2个月就变成了二月份。
maxLength(), minLength()和length(boolean leapYear)
用来获取Month对象表示的该月的日期数。其中,length(boolean leapYear)中的参数表示是否为闰年。其实这三个方法返回的结果在很多情况下都是一样的,返回的都是当月的日期数,30或者31。只有二月份除外,当Month对象表示二月份时,maxLength()和length(true)返回29,minLength()和length(false)返回28。
下面用代码来说明上述方法的使用:
public static void main(String[] args) {
System.out.println(Month.DECEMBER);
// DECEMBER
System.out.println(Month.of(2));
// FEBRUARY
Month month = Month.FEBRUARY;
System.out.println(month.getValue());
System.out.println(month.minus(3));
// NOVEMBER
System.out.println(month.plus(2));
System.out.println(month.length(false));
System.out.println(month.length(true));
有时候我们希望返回月份是中文,而不是英文。毕竟程序员大多都比较懒,能少转化一次自然是很好的。又或者你需要显示的是月份的英文缩写?Java 8都为你想到了。只要调用getDisplayName(TextStyle, Locale)方法就行,该方法第一个参数是文本类型,也就是说你想显示完整的名称还是缩写;第二个参数表示地区,如果没有特殊要求,传入Locale.getDefault()就行。就像下面的代码演示的那样:
public static void main(String[] args) {
Month month = Month.APRIL;
System.out.println(month.getDisplayName(TextStyle.FULL, Locale.getDefault()));
System.out.println(month.getDisplayName(TextStyle.SHORT, Locale.getDefault()));
System.out.println(month.getDisplayName(TextStyle.NARROW, Locale.getDefault()));
System.out.println(month.getDisplayName(TextStyle.FULL, Locale.ENGLISH));
System.out.println(month.getDisplayName(TextStyle.SHORT, Locale.ENGLISH));
System.out.println(month.getDisplayName(TextStyle.NARROW, Locale.ENGLISH));
DayOfWeek枚举类用来表示一个周的七天。常用的方法和Month枚举类的几乎一致,包括of(int dayOfWeek)静态方法用于创建DayOfWeek对象;getValue()方法用来获取该对象的值;plus(long days)和minus(long days)方法用来进行加减法计算。也可以使用getDisplayName(TextStyle style, Locale locale)来格式化输出。代码演示如下:
public static void main(String[] args) {
System.out.println(DayOfWeek.FRIDAY);
System.out.println(DayOfWeek.of(7));
DayOfWeek dayOfWeek = DayOfWeek.TUESDAY;
System.out.println(dayOfWeek.getValue());
System.out.println(dayOfWeek.plus(3));
System.out.println(dayOfWeek.minus(2));
Locale defaultLocal = Locale.getDefault();
System.out.println(dayOfWeek.getDisplayName(TextStyle.FULL, defaultLocal));
System.out.println(dayOfWeek.getDisplayName(TextStyle.SHORT, defaultLocal));
System.out.println(dayOfWeek.getDisplayName(TextStyle.NARROW, defaultLocal));
Locale locale = Locale.ENGLISH;
System.out.println(dayOfWeek.getDisplayName(TextStyle.FULL, locale));
// Tuesday
System.out.println(dayOfWeek.getDisplayName(TextStyle.SHORT, locale));
System.out.println(dayOfWeek.getDisplayName(TextStyle.NARROW, locale));
但是呢,在DayOfWeek枚举类中,是没有maxLength(), minLength()和length(boolean leapYear)这三个方法的,相信你们也知道是为什么。
最后说一句,由于Month和DayOfWeek只是枚举类,它们并不持有当前时间信息,所以就别妄想使用这两个枚举类来解决&今天是星期几&,&明天是几号&等问题了。
源码中的加减法计算
刚开始学Java的时候,计算月份/星期几乎是必备作业,不过当时用的是Date/Calendar类来计算,相当麻烦,Java 8使用枚举来表示月份和星期之后,进行相应的加减法计算就变的相对简单了,我们可以看一下是怎么实现的。
由于月份的计算和星期的计算原理是一样的,我们就只看Month的加减法计算。
private static final Month[] ENUMS = Month.values();
public Month plus(long months) {
int amount = (int) (months % 12);
return ENUMS[(ordinal() + (amount + 12)) % 12];
public Month minus(long months) {
return plus(-(months % 12));
这里的处理方法很巧妙,减法直接调用加法的处理逻辑,当年我就没想到过,哈哈,值得学习。
重头戏来了,现在开始隆重介绍Java 8的常用的时间日期类:LocalDate和LocalTime。使用LocalDate可以获取当前日期(注意只是日期,不包含时间),并可以进行相应处理。使用LocalTime可以获取当前时间(注意只是时间,不包含日期)并进行相应处理。这样就更好的符合&单一职责原则&。
根据不同的需求,提供了不同的创建方式,主要包括两个静态方法now()和of()方法。其实,在后面我们会看到,在Java 8中,创建时间和日期几乎都会用的这两个方法。
public static void main(String[] args) {
LocalDate date1 = LocalDate.now();
LocalDate date2 = LocalDate.of();
LocalDate date3 = LocalDate.ofEpochDay(180);
System.out.println(date1);
System.out.println(date2);
System.out.println(date3);
LocalTime time1 = LocalTime.now();
LocalTime time2 = LocalTime.now().withNano(0);
LocalTime time3 = LocalTime.of(12, 30);
LocalTime time4 = LocalTime.ofSecondOfDay(60 * 60 * 2);
System.out.println(time1);
// 10:56:04.772
System.out.println(time2);
// 10:56:04
System.out.println(time3);
System.out.println(time4);
withNano()方法会在后面提及,主要是修改当前对象表示的纳秒数的值。在上面的代码中,有几点需要注意的地方:
ofEpochDay(long epochDay)方法中的参数,指的是距日那天的时间间隔。 在Java 8中,时间和日期的格式是按照ISO-8061的时间和日期标准来显示的。年份为4位数,月日时分秒都是2位数,不足两位用0补齐。
还记得之前说过的,DayOfWeek枚举类不持有当前时间信息,所以你无法单独使用它来得到今天是星期几这种信息。然而如果获取到了当前日期的LocalDate对象后,问题就迎刃而解了。
LocalDate提供了大量的方法来进行日期信息的获取和计算。有了这一个LocalDate对象,你不仅可以知道这个对象是哪年几月几日星期几,还能够对于年月日进行加减法计算,甚至你可以以周为单位进行日期的加减法计算,比如,你可以轻松解决两个周前的今天是几月几日这类问题。
下面,我就将常用的方法以表格的形式列举出来,注意列举的只是常用方法,并不是所有方法。想知道所有方法,请自行查阅API文档
返回值类型
对该方法的解释
获取当前日期的年份
getMonth()
获取当前日期的月份对象
getMonthValue()
获取当前日期是第几月
getDayOfWeek()
表示该对象表示的日期是星期几
getDayOfMonth()
表示该对象表示的日期是这个月第几天
getDayOfYear()
表示该对象表示的日期是今年第几天
withYear(int year)
修改当前对象的年份
withMonth(int month)
修改当前对象的月份
withDayOfMonth(int dayOfMonth)
修改当前对象在当月的日期
isLeapYear()
是否是闰年
lengthOfMonth()
这个月有多少天
lengthOfYear()
该对象表示的年份有多少天(365或者366)
plusYears(long yearsToAdd)
当前对象增加指定的年份数
plusMonths(long monthsToAdd)
当前对象增加指定的月份数
plusWeeks(long weeksToAdd)
当前对象增加指定的周数
plusDays(long daysToAdd)
当前对象增加指定的天数
minusYears(long yearsToSubtract)
当前对象减去指定的年数
minusMonths(long monthsToSubtract)
当前对象减去注定的月数
minusWeeks(long weeksToSubtract)
当前对象减去指定的周数
minusDays(long daysToSubtract)
当前对象减去指定的天数
compareTo(ChronoLocalDate other)
比较当前对象和other对象在时间上的大小,返回值如果为正,则当前对象时间较晚,
isBefore(ChronoLocalDate other)
比较当前对象日期是否在other对象日期之前
isAfter(ChronoLocalDate other)
比较当前对象日期是否在other对象日期之后
isEqual(ChronoLocalDate other)
比较两个日期对象是否相等
列出这么多方法,不是要你死记硬背记住它们,而是要在脑海有个印象,知道有哪些常用方法,可以做什么。概括起来,LocalDate类中常用的方法有四种:获取日期信息,修改日期信息,加减法运算和日期对象间的比较。记住了这些,以后在工作中就可以查阅使用,而不用自己在造一遍轮子。
有几点需要注意的地方:
上面列表里面有一个ChronoLocalDate,它是一个接口,LocalDate类实现了这个接口,所以直接传一个LocalDate类对象即可。 isEqual(ChronoLocalDate other)这个方法,如果两个对象是同一个对象,或者这两个对象的值相等(同年同月同日),则返回true,否则返回false。 当一个方法返回的是LocalDate对象时,便可以使用链式调用。举个例子,获取昨天的日期,我们可以直接这样写:LocalDate.now().minusDays(1)。
下面用代码演示几个方法:
public static void main(String[] args) {
LocalDate now = LocalDate.now();
System.out.println(now.getYear());
System.out.println(now.getDayOfWeek());
System.out.println(now.getDayOfMonth());
System.out.println(now.withMonth(3));
System.out.println(now.minusWeeks(2));
System.out.println(now.plusDays(10));
LocalDate firstDayOfYear = LocalDate.of();
System.out.println(now.compareTo(firstDayOfYear));
System.out.println(now.isAfter(firstDayOfYear));
System.out.println(now.isEqual(firstDayOfYear));
LocalDate类中的方法和LocalDate中的类似,同样可以分为:获取时间信息,修改时间信息,加减法运算和时间对象间的比较。方法的具体描述我就不写了。根据LocalDate类中列举的常用方法,你也能猜得出在LocalTime类中有哪些对应的常用方法。下面还是用代码演示几个方法:
public static void main(String[] args) {
LocalTime now = LocalTime.now();
System.out.println(now.getHour());
System.out.println(now.getMinute());
System.out.println(now.getSecond());
System.out.println(now.getNano());
System.out.println(now.withNano(0));
// 14:15:22
System.out.println(now.minusHours(3));
// 11:15:22.881
System.out.println(now.minusMinutes(15));
// 14:00:22.881
System.out.println(now.minusSeconds(20));
// 14:15:02.881
LocalTime halfOfDay = LocalTime.of(12 ,0);
System.out.println(now.compareTo(halfOfDay));
System.out.println(now.isAfter(halfOfDay));
不过有几点需要说明:
LocalTime中没有isEqual()方法。 在getNano()中,nano指的是纳秒(毫微秒),1秒等于1亿纳秒。
或许有人觉得,将日期和时间分开处理有些不方便。我想将时间和日期一起处理怎么办?当然可以,Java 8中还提供了LocalDateTime来满足你的这个需求。
和前面的类似,可以使用静态方法now()和静态方法of()来创建一个LocalDateTime对象。比如:
public static void main(String[] args) {
LocalDateTime now = LocalDateTime.now();
System.out.println(now);
// T14:27:20.169
LocalDateTime dateTime1 = LocalDateTime.of(, 12, 3);
LocalDateTime dateTime2 = LocalDateTime.of(, 8, 4, 20);
System.out.println(dateTime1);
System.out.println(dateTime2);
// T08:04:20
通常,你需要在of()方法中传入6个参数,表示年月日时分秒。关于月份,既可以传入Month对象,也可以传入int值(当然1表示一月份)。也可以将秒这个参数省略了,传入5个参数。也可以增加一个纳秒参数,变为7个参数。
这个不想再说了,和LocalDate及LocalTime类似。
LocalDateTime既然是&集LocalDate和LocalTime的大成者&,自然能将LocalDateTime转化位LocalDate或者LocalTime,而且方法很简单,只需要调用toLocalDate()或者toLocalTime()方法,就像下面演示的那样:
public static void main(String[] args) {
LocalDateTime dateTime = LocalDateTime.now();
System.out.println(dateTime);
// T16:57:41.217
LocalDate date = dateTime.toLocalDate();
LocalTime time = dateTime.toLocalTime();
System.out.println(date);
System.out.println(time);
// 16:57:41.217
解析和格式化
在Date和Calendar统治的时代,想要格式化一个日期,只能用Date来格式化,并且SimpleDateFormat还有线程安全隐患,无疑很麻烦。而现在,在Java 8中,这些问题都不复存在了。
有一点需要再次强调,再Java 8中,时间日期的格式是按照ISO-8061的时间和日期标准来显示的。年份为4位数,月日时分秒都是2位数,不足两位用0补齐,日期之间需要用短横线连接,时间之间要用:连接。必须按照此规则来进行解析,比如:
public static void main(String[] args) {
LocalDate date = LocalDate.parse(&&);
LocalTime time = LocalTime.parse(&12:24:43&);
System.out.println(date);
System.out.println(time);
// 12:24:43
当然,Java是宽容的,如果你不按照ISO-8061的格式传入,也有解决办法,这个可以使用parse(CharSequence text, DateTimeFormatter formatter)这个方法,第二个参数传入你所想要的格式类型。
或者,你也可以使用如下的方法,来解析一个日期字符串
public static void main(String[] args) {
String input = &&;
DateTimeFormatter formatter =
DateTimeFormatter.ofPattern(&yyyyMMdd&);
LocalDate date = LocalDate.parse(input, formatter);
System.out.printf(&%s%n&, date);
然后,格式化一个时间日期对象也很简单,就想下面一样:
public static void main(String[] args) {
DateTimeFormatter format = DateTimeFormatter.ofPattern(&MMM d yyyy
hh:mm a&);
LocalDateTime date = LocalDateTime.now();
String dateStr = date.format(format);
System.out.println(dateStr);
// 七月 11
调节器(Temporal Adjuster)
如果说,新版的时间日期处理方法,和我们以前使用的Date和Calendar类有什么使用上的区别的话,最明显的使用区别就是调节器的使用了。调节器有什么用呢?比如要获取下周星期一的日期,用之前的方法不容易获得,而这时使用调节器就能轻松解决。
先看一下使用方法:
public static void main(String[] args) {
LocalDate date = LocalDate.now();
DayOfWeek dotw = date.getDayOfWeek();
System.out.printf(&%s is on a %s%n&, date, dotw);
is on a MONDAY
System.out.printf(&Next Monday: %s%n&,
date.with(TemporalAdjusters.next(DayOfWeek.MONDAY)));// Next Monday:
System.out.printf(&First day of Month: %s%n&,
date.with(TemporalAdjusters.firstDayOfMonth()));
// First day of Month:
System.out.printf(&First Monday of Month: %s%n&,
date.with(TemporalAdjusters.firstInMonth(DayOfWeek.MONDAY)));// First Monday of Month:
很简单,得到LocalDate对象后,调用with()方法,传入一个TemporalAdjusters对象即可。TemporalAdjusters类有许多静态工厂方法来创建该对象,比如:
firstDayOfMonth() lastDayOfMonth() firstDayOfNextMonth() firstDayOfYear() lastDayOfYear() firstDayOfNextYear() firstInMonth(DayOfWeek dayOfWeek) lastInMonth(DayOfWeek dayOfWeek) dayOfWeekInMonth(int ordinal, DayOfWeek dayOfWeek) next(DayOfWeek dayOfWeek) nextOrSame(DayOfWeek dayOfWeek) previous(DayOfWeek dayOfWeek) previousOrSame(DayOfWeek dayOfWeek)
这些方法都见名知意,但是有可能这些方法并不能满足你的需求,这时,就需要自定义TemporalAdjusters了。
自定义调节器
自定义一个调节器很简单,创建一个类,实现TemporalAdjuster接口,重写adjustInto(Temporal input)方法,将你需要的逻辑都在里面实现。
假设一个场景,一个商店每个月进货两次,上半月一次,下半月一次,上半月的那次进货是在15号,如果实在下半月,则是该月的最后一天进货。如果进货的那天恰逢周六周日,则提前到该周周五进货(货车司机也要双休嘛),那么如何自定义一个调节器,计算下一次的进货时间呢?
我们可以使用下面的代码实现一个自定义调节器:
public class PurchaseAdjuster implements TemporalAdjuster {
public Temporal adjustInto(Temporal input) {
LocalDate date = LocalDate.from(input);
if (date.getDayOfMonth() & 15) {
day = date.with(TemporalAdjusters.lastDayOfMonth()).getDayOfMonth();
date = date.withDayOfMonth(day);
if (date.getDayOfWeek() == DayOfWeek.SATURDAY ||
date.getDayOfWeek() == DayOfWeek.SUNDAY) {
date = date.with(TemporalAdjusters.previous(DayOfWeek.FRIDAY));
return input.with(date);
这里面使用到了LocalDate.from(TemporalAccessor temporal)方法,该方法获取一个Temporal对象,返回一个LocalDate对象(LocalTime和LocalDateTime都有此静态方法),然后使用内置的TemporalAdjuster静态工厂方法完成逻辑处理,最后返回修改之后的Temporal对象。
让我们看看效果如何:
public static void main(String[] args) {
LocalDate date = LocalDate.now();
LocalDate nextPurchaseday = date.with(new PurchaseAdjuster());
System.out.println(nextPurchaseday);
LocalDate customDate = LocalDate.now().withDayOfMonth(18);
LocalDate otherPurchaseday = customDate.with(new PurchaseAdjuster());
System.out.println(otherPurchaseday);
7月29日是星期五,嗯,看来效果不错哈?
最后,其实还有很多没说完
聊了这么多,但是仍然有很多没聊完。Java 8中对时间和日期的处理比较复杂,涉及的东西比较广泛,本篇只说了一些常用的类和方法,希望通过这些方法,让你能熟悉使用Java 8中的时间和日期的处理。如果需要更多的信息,可以去查阅官方文档。}

我要回帖

更多关于 js日期显示格式化 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信