Java 日期和随机数

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 的毫秒数对其进行初始化

代码示例:

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类附有两大功能:

  1. 允许用年、月、日、时、分、秒来解释日期
  2. 允许对表示日期的字符串进行格式化和句法分析

在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两者之间的转换。

例如:

// 太平洋时区的ID为PST
TimeZone tz0 = TimeZone.getTimeZone("PST");
// getDefault() 可以获取主机所处时区对象
TimeZone tz1 = TimeZone.getDefault();

Locale只是一种机制,它用来标识一个特定的地理、政治或文化区域获取一个Locale对象的构造方法:

// 调用 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;

一个简单的示例代码:

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(日期和时间)等,他们的使用方式都差不多。下面来实际编写一下。

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种子创建一个新的随机数生成器

普通方法原型

//该方法是设定基值 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

你可能感兴趣的:(Java 日期和随机数)