编程开发 购物 网址 游戏 小说 歌词 地图 快照 股票 美女 新闻 笑话 | 汉字 软件 日历 阅读 下载 图书馆 开发 租车 短信 China
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
多播视频美女直播
↓电视,电影,美女直播,迅雷资源↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
移动开发 架构设计 编程语言 互联网 开发经验 Web前端 开发总结
开发杂谈 系统运维 研发管理 数据库 云 计 算 Java开发
VC(MFC) Delphi VB C++(C语言) C++ Builder 其它开发语言 云计算 Java开发 .Net开发 IOS开发 Android开发 PHP语言 JavaScript
ASP语言 HTML(CSS) HTML5 Apache MSSQL数据库 Oracle数据库 PowerBuilder Informatica 其它数据库 硬件及嵌入式开发 Linux开发资料
  编程开发知识库 -> Java开发 -> java date time问题总结 -> 正文阅读
 

[Java开发]java date time问题总结[第1页]

问题描述
    最近因为要在工程中用到日期相关的东西,需要将一些表示日期的字符串转换成日期类型并计算该日期的前一天。粗看起来这个问题还是比较简单的,主要就是对于方法api的使用。主要的变换过程就是String--->日期类型---->运算---->String。这么一个过程。
    于是,在经过一番搜索之后,得到了一段如下的代码:

String yesterday(String checkOut) throws ParseException {
    SimpleDateFormat formatter = new SimpleDateFormat("yyyy-mm-dd");
    Date date = formatter.parse(checkOut);
    int dayInMills = 1000 * 60 * 60 * 24;
    return formatter.format(date.getTime() - dayInMills);
}

   在上述代码里,因为我们要输入如2015-12-23等这种格式的字符串,于是首先通过SimpleDateFormat将它解析成Date类型,然后再用这个Date对象减去一个整天的毫秒数。这样就可以得到我们想要的日期了。
    如果我们输入的数据为"2015-12-23",这个时候得到的结果是"2015-12-22"。嗯,这样结果看起来没有问题。实际上这种转换还是有问题的,比如说如果我们输入"2015-02-01",那么将出现什么结果呢?结果程序运行的结果是"2014-02-31"!
    可见,这种想当然的去用时间减毫秒数的办法并不可行,而且隐藏的问题不容易发觉。那么有没有什么简单易用的办法来解决呢?
Java8 time
     Java里面对日期的支持一直不理想,而且以前的Date类型还是mutable的,这意味着该类型还不是线程安全的。在java 8里引入的新的包对它有一个明显的改进。比如说对于上述的问题,在java 8里需要怎么做呢?

public String yesterday(String checkOut) {
    LocalDate date = LocalDate.parse(checkOut);
    return date.minusDays(1).format(DateTimeFormatter.ISO_LOCAL_DATE);
}

   针对我们前面的问题,这里只需要两行代码就解决了。这里引入了新的类型LocalDate, DateTimeFormatter等。那么上面这两行代码表示什么意思呢?首先,前面的LocalDate.parse()方法将输入的字符串转换成LocalDate类型。由于LocalDate对象的默认显示格式就是"yyyy-mm-dd"这种样式的,所以对于本文中的问题就可以直接转换过来。
    后续的LocalDate有一个minusDays方法,用它减去1则得到前一天的日期。然后再调用它的format方法得到新的日期的String类型。由于它默认的格式是我们期望的类型,我们返回它的toString()方法也会得到同样的结果。
    如果从解决前面这个问题的角度来说,可以说到这里就结束了。既然Java 8引入了新的date time类型,顺便也做一个小小的总结吧。
LocalDate
    我们可能接触的最多的类型就是LocalDate了,它和前面的Date类型不一样,本身是immutable的,这意味着它是线程安全的。每次我们调用一些方法,比如前面的minusDays()方法,它实际上是返回一个新的对象而不是修改原有对象本身。
创建LocalDate对象:
由于创建LocalDate对象没有构造函数方法,所有创建改对象必须通过工厂方法的方式,一种方法如下:

LocalDate date = LocalDate.of(2016, 2, 1);

  当然,还有一种就是我们前面通过parse方法解析字符串的方式,这种方式在后面会详细讨论。
访问年,月,日

int year = date.getYear();
Month month = date.getMonth();
int mon = date.getMonthValue();
int day = date.getDayOfMonth();
day = date.getDayOfYear();
DayOfWeek dow = date.getDayOfWeek();

    上述这些是一些比较常用的访问年月日的方法,比如我们需要访问某个月,如果期望是返回数字的话,可以使用date.getMonthValue()方法,而使用getMonth()方法返回的是一个Month类型,当然Month类型也提供有返回对应月份数值的方法。返回具体某一日的方法有getDayOfMonth, getDayOfYear()以及getDayOfWeek。
    由于LocalDate的api比较灵活,如果我们相用一个看起来更加统一的方式来访问年、月和日的话,也有如下的办法:

int year = date.get(ChronoField.YEAR);
int mon = date.get(ChronoField.MONTH_OF_YEAR);
int day = date.get(ChronoField.DAY_OF_MONTH);

     其中的ChronoField是一个enum类型,里面列举了各种日期相关的值。
修改年、月、日
    和前面获取年月日相关,LocalDate里也有增加或者减少年月日的api,比如:

date.plusDays(10);
date.plusMonths(10);
date.plusWeeks(10);
date.plusYears(10);

    也有一种比较通用的写法就是:

date.plus(10, ChronoUnit.DAYS);
date.plus(10, ChronoUnit.MONTHS);

    相应的,减少日期的api有如下:

date.minusDays(10);
date.minusMonths(10);
date.minusWeeks(10);
date.minusYears(10);
date.minus(10, ChronoUnit.YEARS);

字符串解析
    在前面的示例里已经看到过一种解析的办法,就是LocalDate.parse()。这种方法默认的输入String类型是"yyyy-mm-dd"样式的。但是对于我们不同的格式需要,比如2015/02/11这种类型的该怎么处理呢?实际上这里还有一个方法就是LocalDate.parse(String, DateTimeFormatter)。由DateTimeFormatter来设定字符串的格式。
    所以对于上述格式的解析可以采用如下的方式:

LocalDate.parse("2016/02/01", DateTimeFormatter.ofPattern("yyyy/MM/dd"));

    实际上,因为国际上有不同表示日期的格式,在DateTimeFormatter里也提供了很多种类型的参数,比如BASIC_ISO_DATE, ISO_LOCAL_DATE, ISO_DATE等。因为这里定义了不同日期类型的格式,所以对于有些字符串的解析可以采用类似如下的方式:

date1 = LocalDate.parse("20140319", DateTimeFormatter.BASIC_ISO_DATE);

    既然是牵涉到日期和字符串之间的解析转换,这里肯定就牵涉到他们格式的设定。从String类型到LocalDate类型的转换需要 设定DateTimeFormatter,而从LocalDate转换成字符串呢?前面已经说到过,LocalDate默认的输出字符串类型是"yyyy-mm-dd"格式的。那么要将它的输出设定为我们指定的格式,也需要用到DateTimeFormatter。
    

String str = date.format(DateTimeFormatter.ofPattern("yyyy/MM/dd");

   出了上述定义的DateTimeFormatter来定义日期的格式,还有一种办法就是使用DateTimeFormatterBuilder。它构建一个DateTimeFormatter的方式类似于一个builder模式。一个典型的用法如下:

DateTimeFormatter formatter1 = new DateTimeFormatterBuilder()
    			.appendText(ChronoField.DAY_OF_MONTH)
    			.appendLiteral(".")
    			.appendText(ChronoField.MONTH_OF_YEAR)
    			.appendLiteral(" ")
    			.appendText(ChronoField.YEAR)
    			.parseCaseInsensitive()
    			.toFormatter(Locale.CHINA);

System.out.println(date1.format(formatter1));

   运行程序的话将得到如下的输出: 
    

20.三月 2014

   
LocalTime
    有了前面对LocalDate的总结之后,我们再来看LocalTime的部分就很简单了。它默认的格式是"hh:mm:ss"。所以一些典型的方法如下:

LocalTime time = LocalTime.of(13, 45, 20);
int hour = time.getHour();
int minute = time.getMinute();
int second = time.getSecond();
time = LocalTime.parse("13:45:20");
time = LocalTime.parse("21/45/20", DateTimeFormatter.ofPattern("HH/mm/ss"));

JodaTime
    在最开始的问题中,如果采用java 8的LocalDate的话,需要将系统升级到jdk8才行。对于有的存在具体困难的情况下,也可以用第三方的库。最典型的就是JodaTime。实际上java8里面time包的很多实现就是基于这个库的移植。
    JodaTime库的依赖定义如下:
    

<dependency>
    <groupId>joda-time</groupId>
    <artifactId>joda-time</artifactId>
    <version>2.9.1</version>
</dependency>

    采用它的实现和我们前面的方式非常接近,具体的实现方法如下:

String yesterday(String checkOut) {
    DateTimeFormatter formatter =
           ISODateTimeFormat.yearMonthDay().withZoneUTC();
    DateTime time = DateTime.parse(checkOut, formatter).minusDays(1);
    return time.toString(formatter);
}

    由于比较简单,就不详细解释了。
总结
     Java 从1.1开始对日期和时间的类库支持就不够好,一直到java 8的出现才有所好转。在新的java 8的类库里,重点的两个类分别就是LocalDate, LocalTime。他们分别表示日期和时间。一个包含的元素有年月日,一个表示的是时分秒。他们都是immutable的类型。构造的方式都是采用of方法或者采用parse方法解析字符串。而且现在对于时间的各种加减操作也非常方便了。里面提供的plusxx, minusxx就是专门为这些服务。对于具体解析和格式转换他们都是通过DateTimeFormatter,里面定义的各种日期和时间格式都是为了方便我们的使用。
参考材料
java 8 in action
http://docs.oracle.com/javase/8/docs/api/java/time/format/DateTimeFormatter.html
  Java开发 最新文章
nvm每次启动终端都要设置nvm use
单页面应用优缺点分析
微信小程序开发入门
jQueryEasyUi验证
CSS标签属性之position
ReactElement
Webpack+Babel+React的快速搭建
关于mongo 日期查询
Spring Boot基础教程8-web应用开发-模板引擎
java date time问题总结
上一篇文章      下一篇文章      查看所有文章
加:2016-05-28 20:05:52  更:2016-06-03 16:01:43 
VC(MFC) Delphi VB C++(C语言) C++ Builder 其它开发语言 云计算 Java开发 .Net开发 IOS开发 Android开发 PHP语言 JavaScript
ASP语言 HTML(CSS) HTML5 Apache MSSQL数据库 Oracle数据库 PowerBuilder Informatica 其它数据库 硬件及嵌入式开发 Linux开发资料
360图书馆 软件开发资料 文字转语音 购物精选 软件下载 美食菜谱 新闻资讯 电影视频 小游戏 Chinese Culture 股票 租车
生肖星座 三丰软件 视频 开发 短信 中国文化 网文精选 搜图网 美图 阅读网 多播 租车 短信 看图 日历 万年历 2018年7日历
2018-7-19 0:41:49
多播视频美女直播
↓电视,电影,美女直播,迅雷资源↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  编程开发知识库