声明:本面试复习都基于一本未署名的Java面试宝典所述,根据自己的理解写出了这一专栏的复习博客
如何获取年月日,时分秒?
我们所熟知的日期和时间相关的类应该是date类和calendar类,看到这个题的事后第一时间想到了date类,但是date类获取到的是一个具体的时间,返回的是一个固定的时间,精确到了时分秒甚至毫秒,但是却似乎无法满足这个题的需要,那么如和获取单个的年月日,时分秒呢?紧接着联想到了calendar类,而calendar类是可以的,二者的区分如下:
更具体的内容区分可以参考链接:
https://www.cnblogs.com/buwuliao/p/9810338.html
我们来先回顾下date类的一些常用方法:
getTime(): //返回自 1970 年 1 月 1 日 00:00:00 GMT 以来此 Date 对象 表示的毫秒数。
toString(): //把此 Date 对象转换为以下形式的 String: dow mon dd hh:mm:ss zzz yyyy 其中: dow 是一周中的某一天 (Sun, Mon, Tue, Wed, Thu, Fri, Sat),zzz是时间标准。
//其它很多方法都过时了。
import java.util.Date; Date date = new Date();
System.out.println(date);
System.out.println(System.currentTimeMillis());
System.out.println(date.getTime());
Date date1 = new Date(date.getTime());
System.out.println(date1.getTime());
System.out.println(date1.toString());
除了date之外,现如今我们用的最多的是SimpleDateFormat类,这是一个用于格式化日期的类。可以将日期格式化为文本,也可以将文本解析为日期。具体运用如下。
public static void main(String[] args) throws ParseException {
Date date = new Date();
long time = System.currentTimeMillis();
Date date1 = new Date(time);
System.out.println(date);
System.out.println(date1);
System.out.println(date.getTime());
// 时间的格式化
SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd");
String dateStr = sdf.format(date);
System.out.println(dateStr);
// 字符串类型的日期的解析
// 1 字符出类型的时间必须与格式化的格式一致
//2 字符串所表示的时间精度只能大于格式的时间精度
String strDate = "2019/11/16 17:14";
Date date3 = sdf.parse(strDate);
System.out.println(date3);
}
那题中的这里如何获取的,就要用到calendar中的相关方法了。
calendar中的一些方法如下(calendar是一个与计算日期相关的抽象基类):
//一个Calendar的实例是系统时间的抽象表示,通过get(int field)方法来取得想要的时间信息。
//比如YEAR、MONTH、DAY_OF_WEEK、HOUR_OF_DAY 、 MINUTE、SECOND
public void set(int field,int value)
public void add(int field,int amount)
public final Date getTime()
public final void setTime(Date date)
//获取月份时:一月是0,二月是1,以此类推,12月是11
//获取星期时:周日是1,周二是2 , 。。。。周六是7
Calendar calendar = Calendar.getInstance();
// 从一个 Calendar 对象中获取 Date 对象
Date date = calendar.getTime();
// 使用给定的 Date 设置此 Calendar 的时间
date = new Date(234234235235L);
calendar.setTime(date);
calendar.set(Calendar.DAY_OF_MONTH, 8);
System.out.println("当前时间日设置为8后,时间是:" + calendar.getTime());
calendar.add(Calendar.HOUR, 2);
System.out.println("当前时间加2小时后,时间是:" + calendar.getTime());
calendar.add(Calendar.MONTH, -2);
System.out.println("当前日期减2个月后,时间是:" + calendar.getTime());
//实操
public static void main(String[] args) {
Calendar c = Calendar.getInstance();
System.out.println(c);
//获取相应的属性
int year = c.get(Calendar.YEAR);
int month = c.get(Calendar.MONTH);
int day = c.get(Calendar.DAY_OF_MONTH);
int hour = c.get(Calendar.HOUR_OF_DAY);
int min = c.get(Calendar.MINUTE);
int sec = c.get(Calendar.SECOND);
System.out.println(year +"-"+ month +"-"+ day +" "+hour +":"+min+":"+sec);
//设置获取日历的方式
Calendar c1 = Calendar.getInstance(new Locale("en","us"));
System.out.println(c1);
}
上述都是java8之前的应用。
我们需要知道,JDK 1.0中包含了 一个java.util.Date类,但是它的大多数方法已经在JDK 1.1引入Calendar类之后被弃用 了。而Calendar并不比Date好多少。它们面临的问题是:
可变性:像日期和时间这样的类应该是不可变的。 偏移性:Date中的年份是从1900开始的,而月份都从0开始。 格式化:格式化只对Date有用,Calendar则不行。 此外,它们也不是线程安全的;不能处理闰秒等。总之,在之前的版本中,日期和时间总让人在开发的时候非常不舒服。
因此java8之后又推出了time类,这次在种种情况下相比之前都要更加舒服。
Java 8 吸收了 Joda-Time 的精华,以一个新的开始为 Java 创建优秀的 API。 新的 java.time 中包含了所有关于本地日期(LocalDate)、本地时间 (LocalTime)、本地日期时间(LocalDateTime)、时区(ZonedDateTime) 和持续时间(Duration)的类。历史悠久的 Date 类新增了 toInstant() 方法, 用于把 Date 转换成新的表示形式。这些新增的本地化时间日期 API 大大简 化了日期时间和本地化的管理。
java.time – 包含值对象的基础包
java.time.chrono – 提供对不同的日历系统的访问
java.time.format – 格式化和解析时间和日期
java.time.temporal – 包括底层框架和扩展特性
java.time.zone – 包含时区支持的类
说明:大多数开发者只会用到基础包和format包,也可能会用到temporal包。因此,尽 管有68个新的公开类型,大多数开发者,大概将只会用到其中的三分之一。
平常开发中在time类中用到的主要有这么几个:
.Instant——本质上是一个数字时间戳,底层实际上是对System.currentTimeMillis()进行了包装。
.LocalDate——不包含具体时间的日期,比如2014-01-14。它可以用来存储生日,周年纪念日,入职日期等。
.LocalTime——它代表的是不含日期的时间,格式为13:01:02.221。
.LocalDateTime——它包含了日期及时间,不过还是没有偏移信息或者说时区。
.Period——两个日期之间的天、月、年数差值,当然,我们也可以直接使用日期中的until方法来完成同样的效果。
.Duration——两个日期时间间隔的秒以及纳秒数。
.ZonedDateTime——这是一个包含时区的完整的日期时间,偏移量是以UTC/格林威治时间为基准的。
以上摘自https://www.iteye.com/blog/357029540-2398063
这篇博客对于具体的各种使用方法都有非常明确的说明,我在这里就不在赘述了。只粘贴一下我认为最常用的LocalDateTime的一些API方法。然后有一个简单的测试。
public static void main(String[] args) {
//LocalDateTime 对象
LocalDateTime ldt = LocalDateTime.now();
System.out.println(ldt);//2019-11-17T09:55:54.139
System.out.println(ldt.getYear());
System.out.println(ldt.getMonth());//NOVEMBER
System.out.println(ldt.getMonthValue());//1--12
System.out.println(ldt.getDayOfMonth());// 1 -31
System.out.println(ldt.getHour());
LocalDateTime ldt2 = ldt.withDayOfMonth(10);//设置当前日的值
System.out.println(ldt2.getDayOfMonth());
LocalDateTime ldt3 = ldt.plusDays(10);//为当前的年月日时分秒增加一定的数
System.out.println(ldt3.getDayOfMonth());
LocalDateTime ldt4 = ldt.minusDays(10);//为当前的年月日时分秒减一定的数
System.out.println(ldt4.getDayOfMonth());
}
在借助这个题复习完成的最后,粘贴上宝典作者的解答:
如何获取从1970年一月一日0时0分0秒到现在的毫秒数。
想要完成这个题目,需要我们对整个日期的获取方式有足够的了解。
了解的有三种方法:
第一种方式是通过java.lang.System类 下所提供的一个currentTimeMillis()方法实现的,他返回的就是这个时间距今的时间差。
第二种方式,也可以通过calendar类中的方法获取。
第三种方式,Java8中的新特性(看了之后才了解的)
//第一种方式
long time = System.currentTimeMillis();
//第二种方式
Calendar.getInstance().getTimeInMills();
//第三种方式
Clock.systemDefaultZone().millis();
如何获取某个月的最后一天?
作者的解答:
观察代码后发现作者涉及到了一个add方法,这里他这个方法的意思是用add方法做加法运算得到的结果,但由于后面参数设置为0,于是是当前系统时间加0,意思就这样得到了当前月份,而不用再用set设置月份了,后续再将上面add处理后得到的系统日期用set天数处理,得到想要得到的第一天(其实感觉当前月份的话add这句是不是有点没必要啊!他在后面的获取当前最后一天的方法中又没有用,困扰了我半天,有点难受:( .)
还有就是这里作者的代码是有些纰漏,一般情况下不会发生问题,但是当是平年的时候,就会出错,原因很简单,平年二月有28天没问题,但是闰年会有29天而getActualMaximum(month) 这个方法是非常自动且全能的,但是他能得到的最大天数只有三个,28,30,31.。我们发现29是他得不到的,那就肯定会出错,所以我们需要进行优化。还有我们需要了解:
getLeastMaximum(Calendar.DAY_OF_MONTH) 得出的是28,29,就得在特殊情况下调用它,
getMaximum(Calendar.DAY_OF_MONTH) 得出的总是31,
这里getMaximum是对全年各月份的日数进行比较,取出最大值;
而getLeastMaximum是取出最小值。
所以我们要做的改进也非常简单,加一个判断调用不同的方法就可以了。
//用伪代码的形式
if(set后的参数值为1,也就是是二月的时候){
calendar.getLeastMaximum(Calendar.DAY_OF_MONTH);使用这个获取
}else{
使用原方法。
}
至于java8,对比一下就会发现的确方便了许多。
如何格式化日期?
这个相当普遍的应用了,SimpleDateFormat就可以解决。
并可以设置格式化的格式,具体的格式为:yyyy-MM-dd HH-mm-ss;这是常用的日期格式,当然还有其他的:
作者的答案:Java8中用一个ofPattern来解决。
打印昨天的当前时刻。
这个其实就是日期的计算,将天数-1就可以了,可以用add函数设置为-1,将天数减一。
Java8中有新的方法,上面已经叙述过了,就是plus和minus。
文章的最后,粘贴作者对于Java8中日期时间API的一些叙述,供今后学习工作参考。