Java 日期和随机数
这一章节 我们主要学习 java.util 中的 Date 类、Calendar 类,Random 类以及 java.time 包中的 LocalTime 类。
java.util 和 java.time 包 ava.util 包提供了一些实用的方法和数据结构。比如日期类 Date,日历类 Calendar 以及随机数类 Random,同时包里还提供了 collection 框架,像堆栈 Stack、向量 Vector、位集合 Bitset 以及哈希表 Hashtable 等表示数据结构的类。而 java.time 包是 java8 新提供的包,里面对时间和日期提供了新的 api,弥补了 java.util 包对日期和时间操作的不足。
Date Date 类表示时间和日期,里面封装了操作日期和时间的方法. Date类经常用来获取系统当前时间。
Date中当前未过时的构造方法:
构造方法
说明
Date()
构造一个Date对象并对其进行初始化以反映当前时间
Date(long date)
构造一个Date对象,并根据相对于GMT1970年1月1日 00:00:00 的毫秒数对其进行初始化
代码示例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 import java.util.*; public class DateDemo { public static void main(String[] args) throws ClassNotFoundException { String strDate, strTime = ""; Date objDate = new Date(); System.out.println("今天的日期是:" + objDate); long time = objDate.getTime(); System.out.println("自 1970 年 1 月 1 日起以毫秒为单位的时间(GMT):" + time); strDate = objDate.toString(); //提取 GMT 时间 strTime = strDate.substring(11,(strDate.length() - 4)); //按小时、分钟和秒提取时间 strTime = "时间:" + strTime.substring(0,8); System.out.println(strTime); } }
温馨提示 Date 很多方法在JDK1.1开始就已经过时了.想要了解可以去官网查询
Calendar 在早期的JDK版本中,Date类附有两大功能:
允许用年、月、日、时、分、秒来解释日期
允许对表示日期的字符串进行格式化和句法分析
在JDK1.1中提供了类Calendar来完成第一种功能,类DateFormat来完成第二项功能。DateFormat是java.text包中的一个类。与Date类有所不同的是,DateFormat类可以接受用各种语言和不同习惯表示的日期字符串。
但是Calendar类是一个抽象类,它完成Date类与普通日期表示法之间的转换,而我们更多的是使用Calendar类的子类GregorianCalendar类。它实现了世界上普遍的公历系统。当然我们也可以继承Calendar类,然后自己定义实现日历的方法.
GregorianCalendar 构造方法:
构造方法
说明
GregorianCalendar
创建的对象中的相关值被设置成指定时区,缺省地点的当前时间,即程序运行时所处的时区、地点的当前时间
GregorianCalendar(TimeZone zone)
创建的对象中的相关值被设置成指定时区zone,缺省地点的当前时间
GregorianCalendar(Locale aLocale)
创建的对象中的相关值被设置成缺省的时区,指定地点aLocale的当前时间
GregorianCalendar(TimeZone zone,Locale aLocale)
year - 创建的对象中的相关值被设置成指定时区,指定地点的当前时间
TimeZone是java.util包中的一个类,其中封装了有关时区的信息。每一个时区对应一组ID。类TimeZone提供了一些方法完成时区与对应ID两者之间的转换。
例如:
1 2 3 4 // 太平洋时区的ID为PST TimeZone tz0 = TimeZone.getTimeZone("PST"); // getDefault() 可以获取主机所处时区对象 TimeZone tz1 = TimeZone.getDefault();
Locale只是一种机制,它用来标识一个特定的地理、政治或文化区域获取一个Locale对象的构造方法:
1 2 3 4 5 6 7 // 调用 Locale 类的构造方法 Locale 10 = new Locale(String language); Locale 11 = new Locale(String language,String country); Locale 12 = new Locale(String language, String country, String variant); // 调用 Locale 类中定义的常量 Locale 11 = Locale.CHINA;
一个简单的示例代码:
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 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 import java.util.*; import java.text.*; public class CalendarDemo { public static void main(String[] args) { // 得到日期格式对象 // Date date = fmt.parse(strDateMake); System.out.println("完整显示日期时间:"); // 字符串转换日期格式 DateFormat fdate = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); String str =fdate.format(new Date()); System.out.println(str); // 创建 Calendar 对象 Calendar calendar = Calendar.getInstance(); // 初始化 Calendar 对象,但并不必要,除非需要重置时间 calendar.setTime(new Date()); // 显示年份 System.out.println("年: " + calendar.get(Calendar.YEAR)); // 显示月份 (从 0 开始,实际显示要加一) System.out.println("月: " + calendar.get(Calendar.MONTH)); // 当前分钟数 System.out.println("分钟: " + calendar.get(Calendar.MINUTE)); // 今年的第 N 天 System.out.println("今年的第 " + calendar.get(Calendar.DAY_OF_YEAR) + "天"); // 本月第 N 天 System.out.println("本月的第 " + calendar.get(Calendar.DAY_OF_MONTH) + "天"); // 3 小时以后 calendar.add(Calendar.HOUR_OF_DAY, 3); System.out.println("三小时以后的时间: " + calendar.getTime()); // 格式化显示 str = (new SimpleDateFormat("yyyy-MM-dd HH:mm:ss:SS")).format(calendar.getTime()); System.out.println(str); // 重置 Calendar 显示当前时间 calendar.setTime(new Date()); str = (new SimpleDateFormat("yyyy-MM-dd HH:mm:ss:SS")).format(calendar.getTime()); System.out.println(str); // 创建一个 Calendar 用于比较时间 Calendar calendarNew = Calendar.getInstance(); // 设定为 5 小时以前,后者大,显示 -1 calendarNew.add(Calendar.HOUR, -5); System.out.println("时间比较:" + calendarNew.compareTo(calendar)); // 设定 7 小时以后,前者大,显示 1 calendarNew.add(Calendar.HOUR, +7); System.out.println("时间比较:" + calendarNew.compareTo(calendar)); // 退回 2 小时,时间相同,显示 0 calendarNew.add(Calendar.HOUR, -2); // calendarNew 创建时间点 System.out.println((new SimpleDateFormat("yyyy-MM-dd HH:mm:ss:SS")).format(calendarNew.getTime())); // calendar 创建时间点 System.out.println((new SimpleDateFormat("yyyy-MM-dd HH:mm:ss:SS")).format(calendar.getTime())); System.out.println("时间比较:" + calendarNew.compareTo(calendar)); } }
其实 month 的含义与 Date 类相同,0 代表 1 月,11 代表 12 月。
有的人可能不明白最后一个的输出为什么有时是 0 ,有时是 1,在这里会涉及到 calendarNew 与 calendar 的创建时间点, calendarNew 经过增加和减少时间后恢复到原来的时间点,也就是最终比较的是谁先创建好,时间点靠后的大一些,而 calendarNew 创建的时间点只有可能是大于等于 calendar 的,需要根据实际的创建时间点进行比较。
java.time 因为 java8 之前的日期和时间 api 饱受诟病,比如线程安全问题,比如 Date 的月份是从 0 开始的!而 java.time 包中将月份封装成为了枚举类型。接下来来看看如何使用这个新的时间报
首先了解一下 LocalTime 类,LocalTime 类是一个不可变类(也就是用 final 修饰的类),和 String 类一样,所以它是线程安全的。除了 LocalTime 还有 LocalDate(日期)、LocalDateTime(日期和时间)等,他们的使用方式都差不多。下面来实际编写一下。
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 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 import java.time.*; import java.time.temporal.ChronoUnit; public class TimeDemo { public static void main(String[] args) { // 获得当前的日期和时间 LocalDateTime currentTime = LocalDateTime.now(); System.out.println("current date and time: " + currentTime); // 输出当前时间的本地值(本时区) LocalDate date1 = currentTime.toLocalDate(); System.out.println("local date: " + date1); Month month = currentTime.getMonth(); int day = currentTime.getDayOfMonth(); int seconds = currentTime.getSecond(); // 由当前时间对象获得各个字段,输出结果 System.out.println("month: " + month +"day: " + day +"seconds: " + seconds); // 由当前时间附带月份和年再输出 LocalDateTime date2 = currentTime.withDayOfMonth(10).withYear(2012); System.out.println("date 2: " + date2); // 输出 2016 年圣诞节的日期 LocalDate date3 = LocalDate.of(2016, Month.DECEMBER, 25); System.out.println("date 3: " + date3); // 输出新闻联播的开始时间 LocalTime date4 = LocalTime.of(19, 00); System.out.println("date 4: " + date4); // 转化为字符串,再输出 LocalTime date5 = LocalTime.parse("20:15:30"); System.out.println("date 5: " + date5); // 将字符串代表的时区信息转化 ZonedDateTime date6 = ZonedDateTime.parse("2016-04-20T19:22:15+01:30[Europe/Paris]"); System.out.println("date1: " + date6); // 设定地区 ID 为亚洲的加尔各答(位于印度),并输出 ZoneId id = ZoneId.of("Asia/Kolkata"); System.out.println("ZoneId: " + id); // 获得系统默认的当前地区并输出 ZoneId currentZone = ZoneId.systemDefault(); System.out.println("CurrentZone: " + currentZone); // 获得当前的日期并输出 LocalDate today = LocalDate.now(); System.out.println("Current date: " + today); // 在当前日期的基础上增加两周时间再输出 LocalDate nextWeek = today.plus(2, ChronoUnit.WEEKS); System.out.println("two weeks after now: " + nextWeek); // 在当前日期的基础上增加 6 个月的时间再输出 LocalDate nextMonth = today.plus(6, ChronoUnit.MONTHS); System.out.println("6 months after now: " + nextMonth); // 在当前日期的基础上增加 5 年的时间再输出 LocalDate nextYear = today.plus(5, ChronoUnit.YEARS); System.out.println("5 years after now: " + nextYear); // 在当前日期的基础上增加 20 年的时间再输出(一个 Decade 为 10 年) LocalDate nextDecade = today.plus(2, ChronoUnit.DECADES); System.out.println("20 years after now: " + nextDecade); } }
Random java实用工具类库中的类 java.util.Random 提供了昌盛各种类型随机的方法。它可以产生int、long、float、double 以及Gaussian等类型的随机数。这也是它与java.lang.Math 中的方法Random() 最大的不同之处,后者只产生double型的随机数
构造方法
说明
Random()
产生一个随机数需要基数,这里将系统时间作为seed
Random(long seed)
使用单个long种子创建一个新的随机数生成器
普通方法原型
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 //该方法是设定基值 seed public synchronized void setSeed(long seed) //该方法是产生一个整型随机数 public int nextInt() //该方法是产生一个 long 型随机数 public long nextLong() //该方法是产生一个 Float 型随机数 public float nextFloat() //该方法是产生一个 Double 型随机数 public double nextDouble() //该方法是产生一个 double 型的 Gaussian 随机数 public synchronized double nextGaussian() /* synchronized 是 Java 语言的关键字,当它用来修饰一个方法或者一个代码块的时候,能够保证在同一时刻最多只有一个线程执行该段代码 */
大家可以验证和尝试一下引入上面所讲的所有类,调用一下里面的各种方法
参考链接 在线文档-jdk-zh