文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

鸿蒙开源第三方组件—日期和时间处理组件JodaTime-ohos

2024-12-03 03:22

关注

想了解更多内容,请访问:

51CTO和华为官方合作共建的鸿蒙技术社区

https://harmonyos.51cto.com

前言

基于安卓平台的日期和时间处理组件JodaTime-ohos(https://github.com/dlew/joda-time-android), 实现鸿蒙化迁移和重构。代码已经开源到(https://gitee.com/isrc_ohos/joda-time_ohos),欢迎各位下载使用并提出宝贵意见!

背景

JodaTime-ohos是一个日期和时间处理组件,可以获取标准时间、当前时间、相对时间、格式化时间等多种形式的时间,并支持对各类时间进行计算和判断。该组件易于使用、可扩展性强、拥有全面的功能集 ,支持多种日历系统,被广泛应用于时间显示类应用。

组件效果展示

(1)显示“标准时间”“一段时间”“格式化时间”“一段时间的相对表示”“一段时间的相对的字符串表示”“相对时间”

 

图1 显示“标准时间”“一段时间”“格式化时间”“一段时间的相对表示”“一段时间的相对的字符串表示”“相对时间”

(2)显示“当前时间”、“是否为今天”


图2 显示“当前时间”、“是否为今天”

(3)显示“一段时间的格式化表示”

“一段时间的格式化表示”:将一段时间用对应的单位表示出来。


图3 显示“一段时间的格式化表示”

Sample解析

1、工程结构


图4 Sample的工程结构

从上图可以看出,Sample的工程结构主要分为三个部分: 图中第①部分的MainAbilitySlice主要负责构建组件应用的主页面布局。主页面上有9个按钮,点击不同的按钮,会跳转到不同的导航界面,每个界面显示不同的时间格式,如图5所示。


图5 组件应用的主页面布局

图中第②部分的内容包含多个AbilitySlice,每一个AbilitySlice都对应①中的一个导航界面。界面中会包含特定格式的时间显示,如图6所示。


图6 按钮导航界面

图中第③部分内容包含两个文件:MainAbility是一切应用的入口,通过setMainRoute()设置路由,将组件应用的主界面设置为MainAbilitySlice。JodaTime则是为了创建示例接收时区变换的广播。

  1. // JodaTime 
  2. try { 
  3.     JodaTimeAndroid.init(this); //init方法用于创建示例接收时区变换的广播 
  4. } catch (RemoteException e) { 
  5.     e.printStackTrace(); 

2、时间的获取

JodaTime-ohos可以为开发者提供9种不同格式的时间,下面我们以sampleGetRelativeTimeSpanStringslice为例,展示“一段时间的相对表示”时间的获取,效果如上述图1中的d所示。其余几种时间格式的使用方法同理,不再赘述。

(1)导入相关类

在sampleGetRelativeTimeSpanStringslice导入DateTime类,并得到实例化对象,该类是时间日期获取工具类。

  1. //导入相关类DateTime 
  2. import org.joda.time.DateTime; 
  3. ...... 
  4. //实例化类对象 
  5. DateTime now = DateTime.now(); 

(2)设置时间显示布局

在sampleGetRelativeTimeSpanStringslice中创建一个DirectionalLayout布局,用于显示获取到的时间。

  1. DirectionalLayout directionalLayout = new DirectionalLayout(this); 
  2. ...... 
  3. @Override 
  4. protected void onStart(Intent intent) { 
  5.     super.onStart(intent); 
  6.     //设置Layout的宽和高 
  7.     directionalLayout.setWidth(ComponentContainer.LayoutConfig.MATCH_PARENT); 
  8.     directionalLayout.setHeight(ComponentContainer.LayoutConfig.MATCH_PARENT); 
  9.     directionalLayout.setPadding(32, 32, 80, 80); //设置Layout填充距离 
  10.     ShapeElement element = new ShapeElement(); 
  11.     element.setRgbColor(new RgbColor(255, 255, 255)); 
  12.     directionalLayout.setBackground(element); //设置Layout背景 
  13.     ...... 

(3)设置时间显示控件

由于需要在布局中显示多个时间结果,所以此处创建一个List,内部元素为String类型,每个String元素表示一个时间结果。

  1. List text = new ArrayList(); 

(4)获取日期和时间值

通过上述创建的DateTime 类对象,分别调用类中不同的方法如plusMinutes()、minusMinutes(),在起始时间点的基础上增加或减少一个固定的时间;后使用DateUtils类的getRelativeTimeSpanString()方法将获得到日期和时间值以对应的单位(时、分或秒)表示出来。

  1. text.add("Short future: " + DateUtils.getRelativeTimeSpanString(this, now.plusMinutes(25)));//目前时间值基础上增加分钟数 
  2. text.add("Medium future: " + DateUtils.getRelativeTimeSpanString(this, now.plusHours(5)));//目前时间值基础上增加小时数 
  3. text.add("Long future: " + DateUtils.getRelativeTimeSpanString(this, now.plusDays(3)));//目前时间值基础上增加天数 
  4. text.add("Short past: " + DateUtils.getRelativeTimeSpanString(this, now.minusMinutes(25)));//目前时间值基础上减少分钟数 
  5. text.add("Medium past: " + DateUtils.getRelativeTimeSpanString(this, now.minusHours(5)));//目前时间值基础上减少小时数 
  6. text.add("Long past: " + DateUtils.getRelativeTimeSpanString(this, now.minusDays(3)));//目前时间值基础上减少天数 

 (5)添加控件到布局中

将获取到的日期和时间值添加到时间显示布局DirectionalLayout中。

  1. directionalLayout.addComponent(textT); 

3、日期和时间常用类

第2小节的例子通过DateTime来获取时间,通常情况下,在使用JodaTime_ohos组件的过程中,使用最多的日期时间获取类共有5种,分别是:Instant类、DateTime类、LocalDate类、LocalTime类和LocalDateTime类。根据要获取日期和时间值的格式不同,需要引入的类也会有所差别,以下分别对这几个类的功能做简单介绍:

Instant:用来表示时间轴上一个瞬时的点,即一个事件发生的时间戳,可以忽略其使用的日历系统或所在时区。

上述五个类都是不可变的类,不论怎样对它进行修改和处理,所有日期和时间相关操作的 API 都将返回一个全新的JodaTime_ohos 实例,类似Java的String类。除了上述5种常用类,本Sample中还使用到了Duration类,涉及到此类的时间格式是一段时间的格式化表示(sampleFormatDurationslice)。

Library解析

JodaTime-ohos组件的整个library分为五个部分,如图7所示。


图7 library组成结构

其中,DateUtils类是最核心的时间格式处理类,是经过封装的工具类。如图8所示,在Sample中使用到的日期和时间类是DateTime类、LocalDate类和Duration类,共三种,在通过DateUtils类中相应方法将获取到日期和时间值进行处理之后,可以得到多达7种格式的日期和时间表现形式。


图8 时间格式处理核心类

1、方法重载实现多时间格式

在DateUtils类中,包含很多时间格式转换的方法,其中有些方法通过方法重载存在多种参数形式,在使用时可以根据需求传入不同个数的参数,从而得到不同格式的日期和时间,增加了程序的可读性。

以getRelativeTimeSpanString()方法为例,此方法用于获得相对时间的跨度,如“20分钟前”、“20分钟内”。 通过方法重载的方式,调用此方法根据参数的不同能够得到两种,分别有两个参数和三个参数两种形式:

(1)两个参数

当传入参数分别是time和flags时,得到的时间格式是一段时间的相对表示,效果如上述图1.1中的d图所示。在获取到传入的原始时间值之后,进行时、分、秒的判断,从而完成相应的处理。

  1. public static CharSequence getRelativeTimeSpanString(Context context, ReadableInstant timeint flags) throws NotExistException, WrongTypeException, IOException { 
  2.         boolean abbrevRelative = (flags & (FORMAT_ABBREV_RELATIVE | FORMAT_ABBREV_ALL)) != 0; 
  3.    //将传入的原始时间值转换为DateTime类型 
  4.         DateTime now = DateTime.now(time.getZone()).withMillisOfSecond(0); 
  5.         //获取原始时间值    
  6.    DateTime timeDt = new DateTime(time).withMillisOfSecond(0); 
  7.         boolean past = !now.isBefore(timeDt); 
  8.         Interval interval = past ? new Interval(timeDt, now) : new Interval(now, timeDt); 
  9.         ... 
  10.         //进行时、分、秒的判断,完成相应处理 
  11.         if (Minutes.minutesIn(interval).isLessThan(Minutes.ONE)) {...} 
  12.         else if (Hours.hoursIn(interval).isLessThan(Hours.ONE)) {...} 
  13.         else if (Days.daysIn(interval).isLessThan(Days.ONE)) {...} 
  14.         else if (Weeks.weeksIn(interval).isLessThan(Weeks.ONE)) {...} 
  15.         ... 
  16.         return String.format(format, count);//返回处理结果 

(2)三个参数:

当传入参数分别是time、flags和withPrepositon时,得到的时间格式是一段相对时间的字符串表示,效果如上述图1.1中的e图所示。先获取传入的原始时间值,将其转换为LocalDate格式,之后分别针对时、分、秒进行判断,从而完成处理返回相应的时间格式。

  1. public static CharSequence getRelativeTimeSpanString(Context ctx, ReadableInstant time, boolean withPreposition) throws NotExistException, WrongTypeException, IOException { 
  2.     String result; 
  3.     LocalDate now = LocalDate.now();//实例化LocalDate对象,获取本地时间 
  4.     LocalDate timeDate = new LocalDate(time);//将传入的原始时间值转换为LocalDate类型 
  5.     int prepositionId; 
  6.     //针对时、分、秒进行判断,完成处理 
  7.     if (Days.daysBetween(now, timeDate).getDays() == 0) {...} 
  8.     else if (Years.yearsBetween(now, timeDate).getYears() != 0) {...} 
  9.     else {...} 
  10.     if (withPreposition) { 
  11.         result = ctx.getResourceManager().getElement(prepositionId).getString(result); 
  12.     } 
  13.     return result;//返回处理结果 

2、同方法中通过判断实现多时间格式

除了上述通过方法重载实现不同时间格式的情况,DateUtils类中还有另一种实现多时间格式的方式,即在同一个方法中,通过判断不同类型的原始时间数据进行相应的处理,从而得到不同类型的时间值。

以一段时间的格式化表示的sampleFormatDurationslice类为例,效果如上述图1.4。开发者在Sample中使用的时候,在分别通过standardSeconds()、standardMinutes()、standardHours()方法按需获取不同时间值即秒、分钟、小时之后,再调用DateUtils中的formatDuration()方法:

  1. text.add("Seconds: " + DateUtils.formatDuration(this, Duration.standardSeconds(25)));//获取25秒的标准时间值 
  2. text.add("Minutes: " + DateUtils.formatDuration(this, Duration.standardMinutes(5)));//获取5分钟的标准时间值 
  3. text.add("Hours: " + DateUtils.formatDuration(this, Duration.standardHours(3)));//获取3小时的标准时间值 

 在formatDuration()方法中,若原始时间数据包含小时,则进行第一个判断,返回小时类型的时间处理结果;若原始时间数据包含分钟,则进行第二个判断,返回分钟类型的时间处理结果;若原始时间数据包含秒,则不进入判断直接返回秒类型的时间处理结果。

  1. public static CharSequence formatDuration(Context context, ReadableDuration readableDuration) throws IOException, NotExistException, WrongTypeException { 
  2.     ResourceManager res = context.getResourceManager(); 
  3.     Duration duration = readableDuration.toDuration();//将传入的原始时间值转换为Duration类型 
  4.     final int hours = (int) duration.getStandardHours();//获取传入的原始时间值 
  5.     if (hours != 0) {//判断传入时间值中是否包含小时 
  6.         return //返回时间值包含小时的时间格式res.getElement(net.danlew.android.joda.ResourceTable.Plural_joda_time_android_duration_hours).getPluralString(hours, hours); 
  7.     } 
  8.     final int minutes = (int) duration.getStandardMinutes(); 
  9.     if (minutes != 0) {//判断传入时间值中是否包含分钟 
  10.         return //返回时间值包含分钟的时间格式res.getElement(net.danlew.android.joda.ResourceTable.Plural_joda_time_android_duration_minutes).getPluralString(minutes, minutes); 
  11.     } 
  12.     final int seconds = (int) duration.getStandardSeconds(); 
  13.     return //传入时间值中包含秒则直接返回处理后的结果res.getElement(net.danlew.android.joda.ResourceTable.Plural_joda_time_android_duration_seconds).getPluralString(seconds, seconds); 

想了解更多内容,请访问:

51CTO和华为官方合作共建的鸿蒙技术社区

https://harmonyos.51cto.com

[[407816]]

 

来源:鸿蒙社区内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯