本文链接:https://rainmonth.github.io/posts/A180208.html
Android 时间选择相关系统控件
概述
日期时间选择,在App开发中十分常见,因此android系统对日期、时间等都做了最基本的封装,同样也提供了丰富的API供开发者进行实际开发。
Date
Java中Date类有如下两个:
java.sql.Date extends java.util.Date;
java.util.Date;
前者主要是构造SQL语句的时候调用,比如读写数据库的时候,大多情况下使用的后者,二者的用法基本相同。
Date构造
无参数
| 1 | Date date = new Date() | 
带long型构造
long类型指的是自1970年1月1日00:00:00这一时刻开始所经历的毫秒数
| 1 | Date now = new Date(System.currentTimeMillis()); | 
上面两个构造方法比较常用,且尚未废弃,其他构造不建议使用。具体可参考源码。
Date使用
Date的比较常见的使用方式有:
- 格式化,满足界面展示的需求;
- 时间比较,由于Date实现了Comparable接口,比较只要调用compareTo()方法即可;
- 类型转换,通常是Date与String类型之间的转化,多数用在输出或界面展示上。
格式化
日期格式化主要使用DateFormat类,但该类是抽象类,所以大多情况使用的SimpleDateFormat类,先看简单实用实例,如下:
| 1 | SimpleDateFormat format1 = new SimpleDateFormat("YYYY-MM-dd HH:mm:ss"); | 
将有如下输出:
| 1 | 2017-03-16 11:45:23 | 
SimpleDateFormat中构造函数格式字符的参考(表格来源Java官方文档)如下:
| 字母 | 日期或时间元素 | 表示 | 示例 | 
|---|---|---|---|
| G | Era 标志符 | Text | AD | 
| y | 年 | Year | 1996;96 | 
| M | 年中的月份 | Month | July;Jul;07 | 
| w | 年中的周数 | Number | 27 | 
| W | 月份中的周数 | Number | 2 | 
| D | 年中的天数 | Number | 189 | 
| d | 月份中的天数 | Number | 10 | 
| F | 月份中的星期 | Number | 2 | 
| E | 星期中的天数 | Text | Tuesday;Tue | 
| a | Am/pm 标记 | Text | PM | 
| H | 一天中的小时数(0-23) | Number | 0 | 
| k | 一天中的小时数(1-24) | Number | 24 | 
| K | am/pm 中的小时数(0-11) | Number | 0 | 
| h | am/pm 中的小时数(1-12) | Number | 12 | 
| m | 小时中的分钟数 | Number | 30 | 
| s | 分钟中的秒数 | Number | 55 | 
| S | 毫秒数 | Number | 978 | 
| z | 时区 | General time zone | Pacific Standard Time;PST;GMT-08:00 | 
| Z | 时区 | RFC 822 time zone | -0800 | 
根据以上解释,可以轻松构造输出格式了,如
| 1 | SimpleDateFormat sdf = new SimpleDateFormat("yyyy年mm月dd日 HH:mm:ss 是第D天 在第w周"); | 
将有如下输出:
| 1 | 2017年43月16日 11:43:58 是第75天 在第11周 | 
时间比较
- 比较时间先后 - 1 
 2
 3
 4
 5
 6
 7
 8- /** 
 * @param date1 date1
 * @param date2 date2
 * @return true if date1 is after date2
 */
 private static boolean greater(Date date1, Date date2) {
 return date1.compareTo(date2) > 0;
 }
- 返回当前时间前(或后)n天(n>0表示后n天,n<0表示前n天) - 1 
 2
 3
 4
 5
 6
 7- /** 
 * @param n number of date
 * @return the date before (n<0) or after(n>0) current date
 */
 private static Date duration(int n) {
 return new Date(new Date().getTime() + n * 24 * 60 * 60 * 1000);
 }
- 几分钟前(几小时前等) - 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- /** 
 * 返回发布时间距离当前的时间
 *
 * @param createdTime the create time
 * @return the result string
 */
 private static String timeAgo(Date createdTime) {
 SimpleDateFormat format = new SimpleDateFormat("MM-dd HH:mm", Locale.CHINA);
 if (createdTime != null) {
 long agoTimeInMin = (new Date(System.currentTimeMillis()).getTime() - createdTime.getTime()) / 1000 / 60;
 //如果在当前时间以前一分钟内
 if (agoTimeInMin <= 1) {
 return "刚刚";
 } else if (agoTimeInMin <= 60) {
 //如果传入的参数时间在当前时间以前10分钟之内
 return agoTimeInMin + "分钟前";
 } else if (agoTimeInMin <= 60 * 24) {
 return agoTimeInMin / 60 + "小时前";
 } else if (agoTimeInMin <= 60 * 24 * 2) {
 return agoTimeInMin / (60 * 24) + "天前";
 } else {
 return format.format(createdTime);
 }
 } else {
 return format.format(new Date(0));
 }
 }
类型转换
主要是Date与String间的转化,代码如下:
| 1 | /** | 
Calendar
Calendar本身是个抽象类,因此不能直接获取其对象实例,其提供的一系列静态获取实例的重载方法getInstance()得到的都是GregorianCalendar对象的实例,该类是Calendar的子类。Calendar提供了多的方法来处理日期时间,因此官方建议使用Calendar来替换Date(好多Date的方法都废弃了)
构造
提供了两个protected 形式构造方法,由于本身为抽象类,这两个方法通常提供给其子类GregorianCalendar调用,获取Calendar实例可以通过如下方法:
| 1 | Calendar.getInstance() | 
该方法有多个重载实现。
使用
使用比较简单,像这类工具类,最好使用时能查看下源码。
| 1 | import java.text.DateFormat; | 
注意,Calendar获取的实例已经做了本地化操作,使用起来比Date方便,建议使用Calendar代替Date。
DatePicker
TimePicker
DatePickerDialog
DatePickerDialog继承与AlertDialog,维护了一个DatePicker实例,提供了一个OnDateSetListener接口
使用时分简单,具体如下:
| 1 | Calendar calendar = Calendar.getInstance(); | 
TimePickerDialog
TimePickerDialog同DatePickerDialog一样,只不过维护的是TimePicker实例而已,使用方法如下:
| 1 | final TimePickerDialog timePickerDialog = new TimePickerDialog(this, new TimePickerDialog.OnTimeSetListener() { |