1.概述

在android app开发中,在项目中有些功能需求要求要获取当前时间精确到毫秒,已便于完成功能开发的需要,而在android 的系统api中提供了SimpleDateFormat和Calendar这两个常有获取时间的类,都可以获取时间到毫秒级别,今天就来
分享两种方法获取当前时间精确到毫秒的功能

2.SimpleDateFormat 的相关api的分析和解析

SimpleDateFormat,它是一个可以以国别方式格式化和分析时间的具体类。 它允许格式化 date -> text的转换,语法分析 (text -> date)和时间标准化的处理

SimpleDateFormat 允许以为日期-时间格式化选择任何用户指定的方式启动对时间的显示出来。 当用 DateFormat 中的getTimeInstance、 getDateInstance 或 getDateTimeInstance 创建一个日期-时间格式化的时候, 每个类方法返回一个以缺省格式化方式初始化的日期/时间格式化程序。 可以根据需要用 applyPattern 方法修改格式化方式。
SimpleDateFormat它是一种简单的格式, 构造时需要传入指定的参数, 包含参数名称和格式, 以匹配需要解析的字符串;

在使用 SimpleDateFormat(String pattern, Locale locale) 构造时间函数。它将接受一个附加参数 - 你要使用的语言环境。如果你想以一致的方式确保输出是机器可读的(始终看起来相同,无论用户的实际语言环境如何),你可以选择 Locale.US。如果你不关心机器的可红性,你可以明确地将其设置为使用 Locale.getDefault()。
具体代码如:

// for US
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("HH:mm:ss", Locale.US);

// or for default
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("HH:mm:ss", Locale.getDefault());

可以在第二个参数来设置当前是哪个国家,就会根据时区来显示当前时间

时间格式化
使用SimpleDateFormat格式化时间时就不得不先说下格式化时间是对应的字符 常用字符如下

yyyy:年

y" , “yyy” , “yyyy” 匹配的都是4位完整的年 如 : “2022”
“yy” 匹配的是年分的后两位 如 : “22”
超过4位,会在年份前面加"0"补位 如 “YYYYY"对应"02022”

MM(只能用大写):月

假设月份为10月 “M” 对应 “10” “MM” 对应 “10” “MMM” 对应 “Oct” “MMMM” 对应 “Oct” 超出3位,仍然对应 “October”

dd:日

“d” , “dd” 都对应 “22” 超出2位,会在数字前面加"0"补位. 例如 “dddd” 对应 “0022”

hh(小写为12小时制):1~12小时制(1-12)
HH(大写为24小时制):24小时制(0-23)
mm(只能用小写):分
ss(只能用小写):秒
S(只能用大写):毫秒
a : 代表上午or下午,上午对应英文 “AM” , 下午对应英文 “PM”

时间格式组合

yyMMdd 对应格式为:221006
    yyyyMMdd 对应格式为:20221006
    yyyyMMdd hh:mm a 对应格式为:20221006 04:35 AM
    带有格式的
    一般年月日的格式用"-"或者""隔开
    yy-MM-dd 对应格式为:22-10-06
    yyyy-MM-dd 对应格式为:2022-10-06
    yyyy-MM-dd 对应格式为:2022-10-06
    yyyy-MM-dd HH:mm 对应格式为:2022-10-06 16:35
    yyyy-MM-dd hh:mm a 对应格式为:2022-10-06 04:35 AM
    yyyy-MM-dd HH:mm:ss 对应格式为:2022-10-06 16:35:33
    yyyy-MM-dd hh:mm:ss a 对应格式为:2022-10-06 04:35:33 AM
    自定义格式 格式除了字符格式化外还可以用汉字格式化
    yyyy年MM月dd日 对应格式为:2022年10月06日
    yyyy年MM月dd日 HH时mm分 对应格式为:022年10月06日 16时35分

代码案例:

Date date = new Date(System.currentTimeMillis());
SimpleDateFormat format;
format = new SimpleDateFormat("yyyyMMdd");
Log.e(TAG,"yyyyMMdd ");
Log.e(TAG,format.format(date));
format = new SimpleDateFormat("yyyyMMdd hh:mm a");
Log.e(TAG,"yyyyMMdd hh:mm a ");
Log.e(TAG,format.format(date));
format = new SimpleDateFormat("yyyy-MM-dd");
Log.e(TAG,"yyyy-MM-dd ");
Log.e(TAG,format.format(date));
format = new SimpleDateFormat("yyyy-MM-dd HH:mm");
Log.e(TAG,"yyyy-MM-dd HH:mm ");
Log.e(TAG,format.format(date));
format = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss a");
Log.e(TAG,"yyyy-MM-dd hh:mm:ss a ");
Log.e(TAG,format.format(date));
format = new SimpleDateFormat("yyyy年MM月dd日");
Log.e(TAG,"yyyy年MM月dd日 ");
Log.e(TAG,format.format(date));
format = new SimpleDateFormat("yyyy年MM月dd日 HH时mm分");
Log.e(TAG,"yyyy年MM月dd日 HH时mm分 ");
Log.e(TAG,format.format(date));

2.2利用SimpleDateFormat 类获取当前时间

val df = SimpleDateFormat("yyyy-MM-dd HH:mm:ss:SSS")//设置日期格式精确到毫秒 SSS代表毫秒
val date= df.format(Date())// new Date()为获取当前系统时间
Log.e("MainActivity","当前时间:"+date)

3.Calendar的相关api的分析和解析

Calendar是Android开发中系统api提供的需要获取时间时必不可少的一个年月日时间工具类,
通过这个类可以获得的当前的时间年月日信息

初始化类的实例
private Calendar c = Calendar.getInstance();

获得当前的年份
Log.e(“MainActivity”, “当前的年份为:” + c.get(Calendar.YEAR));

获得当前的月份
Log.e(“MainActivity”,“当前的月份为:” + (c.get(Calendar.MONTH) + 1));

这个需要注意一下,月份在Calendar中是从0开始的,也就是说1月份的值为0,因此需要加1才是现实中表示的月份

获得今天是本月的第几天,有两种写法,结果是一样的

Log.e(“MainActivity”, “DATE:” + c.get(Calendar.DATE));
Log.e(“MainActivity”, “DAY_OF_MONTH:” + c.get(Calendar.DAY_OF_MONTH));

获得今天是本年的第几天
Log.e(“MainActivity”,“今天是今年的第” + c.get(Calendar.DAY_OF_YEAR) + “天”);

获得今天在本月的第几周
Log.e(“MainActivity”, “今天在本月的第” + c.get(Calendar.DAY_OF_WEEK_IN_MONTH) + “周”);

获得今天是周几,这里不能直接将返回值当做周几,而应该与Calendar用于表示周几的常量搭配使用,返回值为3不代表今天是周三

private void printDayOfWeek() {
    switch (c.get(Calendar.DAY_OF_WEEK)) {
        case Calendar.SUNDAY:
            Log.e("MainActivity", "今天是周日");
            break;
        case Calendar.MONDAY:
            Log.e("MainActivity", "今天是周一");
            break;
        case Calendar.TUESDAY:
            Log.e("MainActivity", "今天是周二");
            break;
        case Calendar.WEDNESDAY:
            Log.e("MainActivity", "今天是周三");
            break;
        case Calendar.THURSDAY:
            Log.e("MainActivity", "今天是周四");
            break;
        case Calendar.FRIDAY:
            Log.e("MainActivity", "今天是周五");
            break;
        case Calendar.SATURDAY:
            Log.e("MainActivity", "今天是周六");
            break;
        default:
            break;
    }
}

获得今天是几点,12小时制

Log.e(“MainActivity”, “现在是” + c.get(Calendar.HOUR) + “点”);

Android中Calendar类的用法总结[通俗易懂]

但现在其实是下午三点,所以需要区分是上午还是下午

if (c.get(Calendar.AM_PM) == Calendar.AM) {
        Log.e("MainActivity", "现在是上午");
    } else {
       Log.e("MainActivity", "现在是下午");
    }

使用Calendar.AM和Calendar.PM来帮助判断是上午还是下午,如果c.get(Calendar.AM_PM)获取到的值和Calendar.AM相等就是上午,如果和Calendar.PM相等就是下午

Calendar也提供了获取24小时制时间的方法

Log.e(“MainActivity”, “现在是” + c.get(Calendar.HOUR_OF_DAY) + “点”);

获得现在是几分

Log.e(“MainActivity”, “现在是” + c.get(Calendar.MINUTE) + “分”);

获得现在是几秒

Log.e(“MainActivity” ,“现在是” + c.get(Calendar.SECOND) + “秒”);

获得现在是几毫秒

Log.e(“MainActivity”, “现在是” + c.get(Calendar.MILLISECOND) + “毫秒”);

Calendar虽然不提供显示规范格式时间的方法,但是可以用SimpleDateFormat来输出规范的字符串,这里简单示范一下用法

SimpleDateFormat sdf = new SimpleDateFormat(“yyyy年MM月dd日”);
Log.e(“MainActivity”, sdf.format(c.getTime()));

关于SimpleDateFormat的更详细的用法之后会用另外一篇文章来讲

Calendar还提供了一些其它的方法,接下来关于时间的输出都是用SimpleDateFormat来输出的,就不贴输出的代码了。

增加日期中的某个域的值,比如想获得明天的日期,就需要向DAY域加1

c.add(Calendar.DAY_OF_MONTH, 1);

加之前

加之后

这样对程序员就比较方便,不用去考虑各种界限的问题

比较两个日期是否相等

private Calendar c = Calendar.getInstance();
private Calendar d = Calendar.getInstance();

Log.e(“MainActivity”, “c和d是否相等:” + c.equals(d));
c.add(Calendar.YEAR, 1);
Log.e(“MainActivity”,“c和d是否相等:” + c.equals(d));

比较两个日期哪个更靠后一些

private Calendar c = Calendar.getInstance();
private Calendar d = Calendar.getInstance();
private SimpleDateFormat sdf = new SimpleDateFormat(“yyyy年MM月dd日 HH:mm”);

d.add(Calendar.DAY_OF_MONTH, 1);
Log.e(“MainActivity”, “d在c后面:” + d.after©);

同样,有方法可以用来判断两个日期哪个更靠前

Log.e(“MainActivity”, “c在d前面:” + c.before(d));

清空某一个域并用这个域最小的值代替和清空所有的域然后全部用最小的值代替

c.clear(Calendar.MONTH);
d.clear();

Log.e(“MainActivity”, “c:” + sdf.format(c.getTime()));
Log.e(“MainActivity”,“d:” + sdf.format(d.getTime()));

获得Calendar对象的一个深拷贝

d = (Calendar) c.clone();

Log.e(“MainActivity”,“c:” + sdf.format(c.getTime()));
Log.e(“MainActivity”, “d:” + sdf.format(d.getTime()));

c.add(Calendar.YEAR, 1);

Log.e(“MainActivity”, “c:” + sdf.format(c.getTime()));
Log.e(“MainActivity”, “d:” + sdf.format(d.getTime()));

比较两个Calendar哪个在前哪个在后的方法
如果调用这个方法的Calendar实例比参数给出的Calendar实例要靠前一些,返回-1,如果要靠后一些,返回1,如果相等,返回0

d = (Calendar) c.clone();
Log.e(“MainActivity”,“比较的结果:” + c.compareTo(d));
c.add(Calendar.YEAR, 1);
Log.e(“MainActivity”, “比较的结果:” + c.compareTo(d));
d.add(Calendar.YEAR, 2);
Log.e(“MainActivity”,“比较的结果:” + c.compareTo(d));

3.2 利用Calendar 类获取当前时间

Calendar Cld = Calendar.getInstance();
        int YY = Cld.get(Calendar.YEAR) ;
        int MM = Cld.get(Calendar.MONTH)+1;
        int DD = Cld.get(Calendar.DATE);
        int HH = Cld.get(Calendar.HOUR_OF_DAY);
        int mm = Cld.get(Calendar.MINUTE);
        int SS = Cld.get(Calendar.SECOND);
        int MI = Cld.get(Calendar.MILLISECOND);//毫秒