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

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,287评论 6 498
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,346评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,277评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,132评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,147评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,106评论 1 295
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,019评论 3 417
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,862评论 0 274
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,301评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,521评论 2 332
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,682评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,405评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,996评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,651评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,803评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,674评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,563评论 2 352

推荐阅读更多精彩内容