Java中的时间和日期(上)
自从JDK 1.0开始,Java就提供了Date来处理时间和日期,作为老古董自然有很多东西是过时的。然后出现了Calendar
来解决了很多问题,但是Calendar
使用比较复杂,并且有些反人类的地方。直到Java 8的出现,它吸收了Joda-Time库的经验,使得Java处理时间和日期变得比较”人性化”了。本篇就来谈谈Java中的Date、Calendar,以及SimpleDateFormat的使用。在Java中的时间和日期(下)里面再对比一下Java 8中的日期处理。
古老的Date
查看一下Date类的源码,可以看到6个构造方法中,有4个已经添加了@Deprecated
的标签了,剩下没过时的只有两个:
public Date() {this(System.currentTimeMillis());
}public Date(long var1) {this.fastTime = var1;
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
其中,第一个构造方法调用的是System.currentTimeMillis()
方法,这个方法返回的是一个long整数,表示GMT 1970年1月1日 00:00:00到现在所经历的毫秒数。这个毫秒数我们暂且称之为milliseconds
值,这个值很重要,无论是在Date类中还是Calendar类中,milliseconds
值都是计算时间日期的基准。
怎么获得这个长整型的数呢?需要调用getTime()
方法,注意并不是调用toString()
方法,它们两者的差异可以重下面的代码中体现出来:
public static void main(String[] args) {Date date = new Date();System.out.println(date.getTime()); // 1467628171312System.out.println(date.toString()); // Mon Jul 04 18:29:31 CST 2016
}
- 1
- 2
- 3
- 4
- 5
而第二个构造方法的参数,表示创建的Date对象与GMT 1970年1月1日 00:00:00的时间差。比如,3600 * 1000毫秒是一小时,那么我们用getTime()
来验证一下:
public static void main(String[] args) {Date date = new Date(3600 * 1000);System.out.println(date.getTime()); // 3600000
}
- 1
- 2
- 3
- 4
没问题,然后我们调用一下toString()
方法,看看返回的是什么:
public static void main(String[] args) {Date date = new Date(3600 * 1000);System.out.println(date.toString()); // Thu Jan 01 09:00:00 CST 1970
}
- 1
- 2
- 3
- 4
嗯?竟然是9点,为什么不是1点呢?怎么差了8个小时?有此疑问的童鞋都是看书不仔细的。而看书仔细的童鞋则会问“CST和GMT是什么关系”之类的。因为CST是指的北京时间
(China Standard Time),而GMT是指的是格林尼治标准时间
(Greenwich Mean Time)。由于北京处于东八区,比GMT早8小时,所以打印的时间指的是北京时间1970年1月1日上午9点。
谈完了构造方法,下面说说Date这个古老的类中可以使用的方法。
- getTime()
这个方法之前我们已经用到了,它返回的是从GMT 1970年1月1日 00:00:00到这个类创建的毫秒数。 - setTime(long time)
设置该Date对象的时间。参数time表示从GMT 1970年1月1日 00:00:00后的毫秒数。 - after(Date when)
测试该日期是否是在指定的日期(when)之后。 - before(Date when)
测试该日期是否是在指定的日期(when)之前。
一段代码解释上面的方法:
public static void main(String[] args) {Date nowaday = new Date();System.out.println(nowaday.getTime()); // 1467633231471System.out.println(nowaday.toString()); // Mon Jul 04 19:53:51 CST 2016Date date = new Date(3600 * 1000);System.out.println(nowaday.before(date)); // falseSystem.out.println(nowaday.after(date)); // truenowaday.setTime(3600 * 1000);System.out.println(nowaday); // Thu Jan 01 09:00:00 CST 1970
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
Date类中的构造方法和常用的未过时的方法基本就是这些了。看了之后是不是觉得其实Date类能用的东西很少?很多日期的操作,比如获取年月日啊,取这周周一的日期啊什么的都很难实现,这时候就要使用到Calendar类,或者使用更牛逼的Java 8中的时间日期包。
庞大的Calendar
Calendar类的构造方法
与Date类不同,Calendar类是一个抽象类。其直接子类是GregorianCalendar
。既然Calendar类是抽象类,那么如获取Calendar对象呢?可以使用下面的代码来创建一个Calendar对象:
Calendar rightNow = Calendar.getInstance();
- 1
和Date一样,创建好对象之后,便包含了当前日期和时间的信息。
其实,getInstance()
这个静态方法还有三个重载方法,在源码中我们可以看到它们4个欢聚一堂的情景:
public static synchronized Calendar getInstance() {return new GregorianCalendar();
}
public static synchronized Calendar getInstance(Locale locale) {return new GregorianCalendar(locale);
}
public static synchronized Calendar getInstance(TimeZone timezone) {return new GregorianCalendar(timezone);
}
public static synchronized Calendar getInstance(TimeZone timezone, Locale locale) {return new GregorianCalendar(timezone, locale);
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
估计大家都能看出来,这4个重载方法的区别在于时区和地区的不同。而它们都是通过创建子类(GregorianCalendar)的对象来返回一个Calendar对象,这其实是多态的一种应用,也是设计模式中工厂模式的应用。也就是说,我们也可以像下面那样来创建一个Calendar对象:
Calendar myCalendar = new GregorianCalendar();
- 1
关于时区和地区这里不做详细的介绍,只展示一下其用法:
public static void main(String[] args) {TimeZone timeZone = TimeZone.getTimeZone("GMT");Locale locale = Locale.CHINA;Calendar calendar = Calendar.getInstance(timeZone, locale);
}
- 1
- 2
- 3
- 4
- 5
Calendar的常用方法
get()和set()方法
在之前的介绍中,Date对象可以通过getTime()
方法和toString()
方法,能很容易的取到对应的时间信息。而在Calendar对象中,获取到时间和日期貌似并不这么直接。在Calendar对象中,getTime()
方法返回的是一个Date对象,至于toString()
方法返回的东西嘛,你们感受一下:
java.util.GregorianCalendar[ time=1467638240540,areFieldsSet=true,areAllFieldsSet=true,lenient=true,zone=sun.util.calendar.ZoneInfo [ id="Asia/Shanghai",offset=28800000,dstSavings=0,useDaylight=false,transitions=19,lastRule=null],firstDayOfWeek=1,minimalDaysInFirstWeek=1,ERA=1,YEAR=2016,MONTH=6,WEEK_OF_YEAR=28,WEEK_OF_MONTH=2,DAY_OF_MONTH=4,DAY_OF_YEAR=186,DAY_OF_WEEK=2,DAY_OF_WEEK_IN_MONTH=1,AM_PM=1,HOUR=9,HOUR_OF_DAY=21,MINUTE=17,SECOND=20,MILLISECOND=540,ZONE_OFFSET=28800000,DST_OFFSET=0
]
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
虽然这从侧面反映了Calendar比Date强大,能提供更多的信息,不过估计你们轻易不会使用Calendar的toString()
方法的吧?其实在Calendar类中,有一点和Date类是一样的:它们都会保存一个milliseconds
的值。Calendar类对于时间日期的各种计算都是基于这个值来的。你看toString()
方法返回的第一个值就是它,足以说明这个值的重要性。
要获取Calendar对象所提供的信息,需要调用get()
方法。在源码中,get()
方法做了如下的事情:
public int get(int field) {complete();return fields[field];
}
- 1
- 2
- 3
- 4
在complete()
方法中,会调用computeTime()
和computeFields()
方法,这两个方法都是抽象方法,由子类GregorianCalendar
实现。在computeTime()
方法中,计算出年月日时分秒等等时间相关的信息,而在computeFields()
方法中获取到对应的时区地区等信息。这两个方法会将所计算出来的信息保存在一个int类型的数组中,这个数组的名字,没错,就是fields。fields数组保存的信息如下所示:
public static final int ERA = 0;
public static final int YEAR = 1;
public static final int MONTH = 2;
public static final int WEEK_OF_YEAR = 3;
public static final int WEEK_OF_MONTH = 4;
public static final int DATE = 5;
public static final int DAY_OF_MONTH = 5;
public static final int DAY_OF_YEAR = 6;
public static final int DAY_OF_WEEK = 7;
public static final int DAY_OF_WEEK_IN_MONTH = 8;
public static final int AM_PM = 9;
public static final int HOUR = 10;
public static final int HOUR_OF_DAY = 11;
public static final int MINUTE = 12;
public static final int SECOND = 13;
public static final int MILLISECOND = 14;
public static final int ZONE_OFFSET = 15;
public static final int DST_OFFSET = 16;
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
嗯,一共18个常量(注意第6个和第7个的值是一样的)。也就是说,get()
方法中你可以传入的参数就是上述18个常量之一。你既可以传常量名(如YEAR等),也可以传数字进去(如1)。当然为了可读性,一般都传入常量名。其中有几个参数可能需要解释一下:
- ERA
表示该日期是在公元纪年(公元0年)之前还是之后,如果返回0表示在公元纪年之前,返回1表示在公元纪年之后。 - AM_PM
表示该时间是在中午12点之前还是之后,如果返回0表示在中午12点之前,返回1表示在中午12点之后。 - DST_OFFSET
表示该时间距夏令时的毫秒数。
下面就举个简单的例子来说明一下吧:
public static void main(String[] args) {Calendar calendar = Calendar.getInstance();System.out.println(calendar.get(Calendar.YEAR)); // 2016System.out.println(calendar.get(Calendar.MONTH)); // 6System.out.println(calendar.get(Calendar.DAY_OF_MONTH)); // 6System.out.println(calendar.get(Calendar.ERA)); // 1
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
有一点要注意的是,由于Calendar类中的常量比较多,你可能传入的常量名不是上述18个之一,那么就可能发生一些意想不到的结果,比如,在get()
方法中如果我们传入一个月份,这么写:
public static void main(String[] args) {Calendar calendar = Calendar.getInstance();System.out.println(calendar.get(Calendar.DECEMBER)); // 22
}
- 1
- 2
- 3
- 4
返回的22是什么鬼?其实是因为Calendar.DECEMBER
的值是11,它返回的其实是HOUR_OF_DAY
的返回值,也就是22点钟。用代码解释就是下面那样:
public static void main(String[] args) {Calendar calendar = Calendar.getInstance();System.out.println(calendar.getTime().toString()); // Mon Jul 04 22:24:08 CST 2016System.out.println(calendar.get(Calendar.HOUR_OF_DAY)); // 22System.out.println(calendar.get(Calendar.DECEMBER)); // 22
}
- 1
- 2
- 3
- 4
- 5
- 6
如果你不小心在Calendar.get()方法中传入了类似Calendar.DECEMBER)
的参数,那么编译器会发出警告,这时候你就可以看看是不是弄错了。当然,如果你对警告置之不理,那只能后果自负。
谈完了get()方法,该说说set()方法了。get()方法是获取时间信息,那么set()方法则是对当前的calendar对象设置时间和日期。那么我们看看set()方法有那些重载的方法:
public void set(int field, int value) {fields[field] = value;isSet[field] = true;areFieldsSet = isTimeSet = false;if (field > MONTH && field < AM_PM) {lastDateFieldSet = field;}if (field == HOUR || field == HOUR_OF_DAY) {lastTimeFieldSet = field;}if (field == AM_PM) {lastTimeFieldSet = HOUR;}
}
public final void set(int year, int month, int day) {set(YEAR, year);set(MONTH, month);set(DATE, day);
}
public final void set(int year, int month, int day, int hourOfDay, int minute) {set(year, month, day);set(HOUR_OF_DAY, hourOfDay);set(MINUTE, minute);
}
public final void set(int year, int month, int day, int hourOfDay, int minute, int second) {set(year, month, day, hourOfDay, minute);set(SECOND, second);
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
很简单,就是将我们传入的值存放到fields数组中。调用set()方法会改变当前Calendar对象的时间和日期。下面用一段简单的代码说明用法:
public static void main(String[] args) {Calendar calendar = Calendar.getInstance();calendar.set(Calendar.MONTH, 5);System.out.println(calendar.get(Calendar.MONTH)); // 5calendar.set(2016, Calendar.JANUARY, 2);System.out.println(calendar.get(Calendar.YEAR)); // 2016System.out.println(calendar.get(Calendar.MONTH)); // 0System.out.println(calendar.get(Calendar.DAY_OF_MONTH)); // 2}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
add()和roll()方法
使用get()和set()方法可以获取当前时间和日期,也可以设置Calendar对象的时间和日期。但是一些简单的时间日期的计算我们仍然无法快速获得。比如昨天的日期?这时,就需要使用到add()和roll()方法了。
add(int field, int value)
方法接受两个参数,第一个参数表示你想改变的字段,这个字段是fields数组中的一个。第二个参数是改变的值。下面用代码看看效果:
public static void main(String[] args) {Calendar calendar = Calendar.getInstance();System.out.println(calendar.getTime().toString()); // Wed Jul 06 10:41:10 CST 2016calendar.add(Calendar.MONTH, 2);System.out.println(calendar.get(Calendar.MONTH)); // 8calendar.set(Calendar.MONTH, 9);System.out.println(calendar.get(Calendar.MONTH)); // 9calendar.add(Calendar.MONTH, 4);System.out.println(calendar.get(Calendar.MONTH)); // 1calendar.set(2016, Calendar.FEBRUARY, 28);calendar.add(Calendar.DAY_OF_MONTH, 3);System.out.println(calendar.getTime().toString()); //Wed Mar 02 13:18:02 CST 2016calendar.set(2016, Calendar.JANUARY, 2);calendar.add(Calendar.DAY_OF_MONTH, -3);System.out.println(calendar.getTime().toString()); // Wed Dec 30 13:18:02 CST 2015
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
上面这段代码看懂了吗?第4行代码打印了当前时间,当前是7月,第5行代码将月份增加了2个月,第6行代码打印了增加之后的月份,嗯?八月?其实不是的。由于在Calendar中月份计数是从0开始的,一月是0,那么8代表的就是九月。同理,第8行将月份设置的是10月,将月份增加4个月后,就是第二年的2月,也就是返回的1。
第14行代码,将二月份的日期加三天,则变成了三月二日(2016年2月有29天)。第18行代码,将1月2日减三天,变成了上一年的12月30日。
由于月份是从0开始计算的,所以计算月份的时候需要特别小心。这就是Calendar反人类的地方之一。
总结一下,使用add()方法有几点需要注意的:
- 月份是从0开始计数的。
- add()方法的第二个参数如果为正,则数据增加;如果为负,则数据减少。
- 当增加的数目超过法定额度时,会自动向更高一级的单位加1。反之亦然。
然后我们再来看看roll()方法。将上面的代码中的add()方法全部替换为roll()方法,结果如下:
public static void main(String[] args) {Calendar calendar = Calendar.getInstance();System.out.println(calendar.getTime().toString()); // Wed Jul 06 13:24:10 CST 2016calendar.roll(Calendar.MONTH, 2);System.out.println(calendar.get(Calendar.MONTH)); // 8calendar.set(Calendar.MONTH, 9);System.out.println(calendar.get(Calendar.MONTH)); // 9calendar.roll(Calendar.MONTH, 4);System.out.println(calendar.get(Calendar.MONTH)); // 1calendar.set(2016, Calendar.FEBRUARY, 28);calendar.roll(Calendar.DAY_OF_MONTH, 3);System.out.println(calendar.getTime().toString()); // Tue Feb 02 13:24:10 CST 2016calendar.set(2016, Calendar.JANUARY, 2);calendar.roll(Calendar.DAY_OF_MONTH, -3);System.out.println(calendar.getTime().toString()); // Sat Jan 30 13:24:10 CST 2016
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
前面的没问题,和add()效果时一样的,后面涉及到进位和退位的时候,就和add()方法表现得不一样了。在roll()方法中不会进行进位和退位运算。这一点是和add()方法最主要的区别。
其它几个有趣的方法
上面介绍的4个方法,set(),get(),add(),roll()是日常使用频率比较高的。但是有几个方法,其实还是比较有趣的,在特定的场合能减少你的代码量。
1.getMaximum(int field)
和getMinimum(int field)
这两个方法,返回Calendar对象的fields数组中对应数据的最大值和最小值。也就是说,如果我想知道Calendar.DAY_OF_MONTH
这个字段能取到的最大值是多少,就可以使用calendar.getMaximum(Calendar.DAY_OF_MONTH)
来获取,返回的值是31,因为一个月最多可以有31天。
2.getActualMaximum(int field)
和getActualMinimum(int field)
这两个方法名字同上面两个方法相比,多了一个Actual
单词,表示返回Calendar对象的fields数组中,在当前日期的环境条件下,对应数据的最大值和最小值。也就是说,如果Calendar对象表示的是2016年的2月,那么使用calendar.getActualMaximum(Calendar.DAY_OF_MONTH)
返回的就是29,因为2016年的2月最多只有29天。
上面的方法,用代码解释如下:
public static void main(String[] args) {Calendar calendar = Calendar.getInstance();System.out.println(calendar.getMaximum(Calendar.MONTH)); // 11System.out.println(calendar.getMinimum(Calendar.HOUR_OF_DAY)); // 0System.out.println(calendar.getActualMaximum(Calendar.DATE)); // 31System.out.println(calendar.getActualMinimum(Calendar.DATE)); // 1
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
这几个方法有什么用呢?比如需要让用户输入本月的一个日期的话,就可以使用getActualMaximum(int field)
方法来进行输入验证,判断用户输入的日期是否合法。
那么fields数组中的各个字段的最大值和最小值分别是多少呢?下面是从源码中找出来的,自己可以对照着上面的fields数组字段名称欣赏一下。
private static int[] maximums = new int[] { 1, 292278994, 11, 53, 6, 31,366, 7, 6, 1, 11, 23, 59, 59, 999, 14 * 3600 * 1000, 7200000 };private static int[] minimums = new int[] { 0, 1, 0, 1, 0, 1, 1, 1, 1, 0,0, 0, 0, 0, 0, -13 * 3600 * 1000, 0 };
- 1
- 2
- 3
- 4
- 5
和Date类的关系
做为对Date类的补充和替代,当然得和Date进行相互转化。
1.使用getTime()
方法,从Calendar对象中获取Date对象。
public static void main(String[] args) {Calendar calendar = Calendar.getInstance();Date date = calendar.getTime();System.out.println(date.toString()); // Mon Jul 04 21:08:27 CST 2016
}
- 1
- 2
- 3
- 4
- 5
2.使用setTime()
方法,将Date对象得值赋值给Calendar对象。
public static void main(String[] args) {Calendar calendar = Calendar.getInstance();System.out.println(calendar.getTimeInMillis()); // 1467637991365Date date = new Date(3600 * 1000);calendar.setTime(date);System.out.println(calendar.getTimeInMillis()); // 3600000
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
还记得介绍Date类时说过,Date的构造方法中,有4个构造方法已经过时了。其实它们是被Calendar类的相关方法给替代了。比如:
- Date(int year, int month, int date)
由Calendar.set(year + 1900, month, date)
代替。 - Date(int year, int month, int date, int hrs, int min)
由Calendar.set(year + 1900, month, date, hrs, min)
代替 - Date(int year, int month, int date, int hrs, int min, int sec)
由Calendar.set(year + 1900, month, date, hrs, min, sec)
代替 - Date(String s)
由DateFormat.parse(String s)
代替
SimpleDateFormat
有了Date和Calendar,我们能获取和设置时间和日期,也能对时间和日期进行简单的计算。但是获取时间信息还不够直接,总不能一个一个地调用Calendar对象的get()
方法,然后再进行转换吧?这时候需要使用到SimpleDateFormat这个类了。顾名思义,这是一个格式化日期和时间的类。
比如想要获得当前时间,输出是哪年哪月几号星期几,几时几分几秒,就可以用下面的代码来实现:
public static void main(String[] args) {Date d = new Date();SimpleDateFormat sdf = new SimpleDateFormat("现在是yyyy年MM月dd日E, kk点mm分ss秒");String dateStr = sdf.format(d); System.out.println(d.toString()); // Wed Jul 06 14:18:35 CST 2016System.out.println(dateStr); // 现在是2016年07月06日星期三, 14点18分35秒
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
先看一下构造方法,SimpleDateFormat类的构造方法有四个,分别是:
- SimpleDateFormat()
- SimpleDateFormat(String pattern)
- SimpleDateFormat(String pattern, DateFormatSymbols formatSymbols)
- SimpleDateFormat(String pattern, Locale locale)
参数pattern有点类似正则表达式的意思,就是说需要将日期格式化成什么模样。这个参数非常重要。如果SimpleDateFormat使用的是第一个空参数构造方法,那么需要调用applyPattern(String pattern)
方法来将pattern传入。也就是说,下面两段代码效果是相同的:
SimpleDateFormat sdf = new SimpleDateFormat();
String partner = "现在是yyyy年MM月dd日E, kk点mm分ss秒";
sdf.applyPattern(partner);// 与上面一段代码的效果相同
SimpleDateFormat sdf = new SimpleDateFormat("现在是yyyy年MM月dd日E, kk点mm分ss秒");
- 1
- 2
- 3
- 4
- 5
- 6
得到了pattern参数后,SimpleDateFormat对象就具有了格式化日期的能力了,这时只需要调用format()
方法,将Date对象传入该方法中,返回的字符串就是格式化后的结果。
那里面的的yyyy和MM等这些符号是什么呢,其实是一些约定好的单位符号,比如上面的yyyy就表示年,ss表示秒。具体的API可以看下表,内容来自官网API文档,我就不翻译了,因为懒。
Letter | Date or Time Component | Presentation | Examples |
---|---|---|---|
G | Era designator | Text | AD |
y | Year | Year | 1996; 96 |
Y | Week year | Year | 2009; 09 |
M | Month in year (context sensitive) | Month | July; Jul; 07 |
L | Month in year (standalone form) | Month | July; Jul; 07 |
w | Week in year | Number | 27 |
W | Week in month | Number | 2 |
D | Day in year | Number | 189 |
d | Day in month | Number | 10 |
F | Day of week in month | Number | 2 |
E | Day name in week | Text | Tuesday; Tue |
u | Day number of week (1 = Monday, …, 7 = Sunday) | Number | 1 |
a | Am/pm marker | Text | PM |
H | Hour in day (0-23) | Number | 0 |
k | Hour in day (1-24) | Number | 24 |
K | Hour in am/pm (0-11) | Number | 0 |
h | Hour in am/pm (1-12) | Number | 12 |
m | Minute in hour | Number | 30 |
s | Second in minute | Number | 55 |
S | Millisecond | Number | 978 |
z | Time zone | General time zone | Pacific Standard Time; PST; GMT-08:00 |
Z | Time zone | RFC 822 time zone | -0800 |
X | Time zone | ISO 8601 time zone | -08; -0800; -08:00 |
注意区分大小写。
有了上面的表格后,对照着写,基本上需要的信息都能满足了。
SimpleDateFormat类除了能将Date对象进行格式化返回字符串,也能将一个日期字符串解析返回成一个Date对象,比如:
public static void main(String[] args) {String s = "2016#08#01";SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy#MM#dd");try {Date date = simpleDateFormat.parse(s);System.out.println(date.toString()); // Mon Aug 01 00:00:00 CST 2016} catch (ParseException e) {e.printStackTrace();}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
嗯,估计大家看出来了,这里需要使用#
符号来进行分割数据。
最后说一点,SimpleDateFormat类不是线程安全的,如果有多个线程需要使用到SimpleDateFormat对象,建议每个线程单独创建,如果多个线程要获取同一个SimpleDateFormat对象,记得要加锁!
文章的末尾,给大家出道题目,看看大家掌握得怎么样?有兴趣的可以试一下:
- 给出一个8位数的日期字符串,比如“20160701”,返回前一天的8位数日期字符串“20160630”。
Java中的时间和日期(上)相关推荐
- Java中的时间和日期(下)
转载请注明出处:http://blog.csdn.net/wl9739/article/details/51882913 在上篇文章Java中的时间和日期(上)里面,简单介绍了Java中的Date类, ...
- 在java中原始时间_Java 日期时间
Java 日期时间 java.util包提供了Date类来封装当前的日期和时间. Date类提供两个构造函数来实例化Date对象. 第一个构造函数使用当前日期和时间来初始化对象. Date( ) 第二 ...
- java中,根据指定日期显示出前n天的日期
大家好,我是雄雄,欢迎关注微信公众号:雄雄的小课堂 今天分享的是:在java中,根据指定日期显示出前n天的日期 效果如下: 大家注意观察上面的时间,我传入的时间是:2022年5月9日21:28:03, ...
- Java中的时间与时区__java
转:https://yq.aliyun.com/ziliao/245667 摘要: 本文讲的是Java中的时间与时区__java, 0. 前言: 时间格式: //世界标准时间,其中 ...
- JAVA中的时间大小比较
原文地址为: JAVA中的时间大小比较 1.时间的比较 import java.text.DateFormat; import java.text.ParseException; import jav ...
- java中比较两个日期的先后
java中比较两个日期的先后 String beginTime=new String("2014-08-15 10:22:22"); String endTime=new Str ...
- vue中解决时间在ios上显示NAN的问题
vue中解决时间在ios上显示NAN的问题 参考文章: (1)vue中解决时间在ios上显示NAN的问题 (2)https://www.cnblogs.com/wzs5800/p/9580785.ht ...
- C标准函数库中获取时间与日期、对时间与日期数据操作及格式化
表示时间的三种数据类型[编辑] 日历时间(calendar time),是从一个标准时间点(epoch)到现在的时间经过的秒数,不包括插入闰秒对时间的调整.开始计时的标准时间点,各种编译器一般使用19 ...
- linux时间与日期函数,Shell中关于时间和日期的函数总结
shell下获取系统时间的方法直接调用系统变量 获取今天时期:`date +%Y%m%d` 或 `date +%F` 或 $(date +%y%m%d) 获取昨天时期:`date -d yesterd ...
最新文章
- php的基础知识(四)
- 分享一波 ZooKeeper 面试题
- 剪切粘贴时总是上次的内容_如何关闭 iOS 14 的粘贴通知
- 【数据结构与算法】之深入解析“石子游戏III”的求解思路与算法示例
- ASP.NET MVC Action向视图传值之匿名类型
- Wildfly Swarm,朝着成熟和一小部分贡献
- java异常处理,需要考虑的流程
- 自定义安装mysql linux_linux下 安装mysql 问题
- 安装chrome_Chrome 离线安装包下载
- Python自动化部署环境
- 基于 koajs 的前后端分离实践
- Dropout原理介绍
- IT从业人员的10个专业论坛
- 提高效率的十款Blender快捷键,更多快捷键等着你去探索
- QT实现Qt3D材质系统加载PBR材料
- PBI Report Builder 报表设计与可视化
- V831基础-切换屏幕
- android接收红外传感器发送的脉冲信号,esp8266_sdk_ir_rx_tx红外遥控示例
- 站在山顶上看golang的前世今生与未来展望
- vscode中编写代码时tab键不能用