百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 编程字典 > 正文

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

toyiye 2024-07-08 22:51 15 浏览 0 评论

前言

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

背景

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

组件效果展示

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

  • 标准时间:程序执行时刻的时间表示,见图1中的a。
  • 格式化时间:将日期/时间格式转换为预先定义的日期/时间格式,见图1中的b。
  • 一段时间:在程序执行时刻的基础上,增加一段时间后的起始时间和结果时间显示,见图1中的c。
  • 一段时间的相对表示:未来或者在过去的某个时间段表示,见图1中的d。
  • 一段时间的相对字符串表示:在程序执行时刻的基础上,增加一段时间的结果时间显示,见图1中的e。
  • 相对时间:在程序执行时刻的基础上,增加一段时间后的结果时间和时间段表示,见图1中的f。

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

  • 当前时间:程序执行时刻的年月日表示。同时也可以给出在当前时间的基础上增加一段 时间后的结果表示,如图2的a所示。
  • 是否为今天:可以判断程序执行的日期是否为今天、是否为昨天、是否为明天,如图2的b所示。

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

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

Sample解析

1、工程结构

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

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

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

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

2、时间的获取

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

1、导入相关类

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

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

2、设置时间显示布局

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

DirectionalLayout directionalLayout = new DirectionalLayout(this);
......
@Override
protected void onStart(Intent intent) {
    super.onStart(intent);
    //设置Layout的宽和高
    directionalLayout.setWidth(ComponentContainer.LayoutConfig.MATCH_PARENT);
	directionalLayout.setHeight(ComponentContainer.LayoutConfig.MATCH_PARENT);
    directionalLayout.setPadding(32, 32, 80, 80); //设置Layout填充距离
    ShapeElement element = new ShapeElement();
    element.setRgbColor(new RgbColor(255, 255, 255));
    directionalLayout.setBackground(element); //设置Layout背景
    ......
}

3、设置时间显示控件

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

List<String> text = new ArrayList<String>();

4、获取日期和时间值

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

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

5、 添加控件到布局中

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

directionalLayout.addComponent(textT);

3、日期和时间常用类

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

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

  • DateTime类:是JodaTime_ohos的核心类,能够确定在时间轴上的位置。使用此类的时间格式有标准时间(sampleDateTimeslice)、格式化时间(sampleFormatDateTimeslice)、一段时间间隔(sampleDateRangeslice)、相对时间(sampleGetRelativeDateTimeStringslice)、一段时间的相对表示(sampleGetRelativeTimeSpanStringslice)、一段相对时间的字符串表示(sampleGetRelativeTimeSpanStringWithPrepositionslice)。
  • LocalDate类:表示本地的日期,不包含时间部分,因此适合强调日期的情况如纪念日。使用此类的时间格式有当前时间(sampleLocalDateslice)、今日时间(sampleIsTodayslice)。
  • LocalTime:表示本地的时间,不包含日期部分,因此适合强调时间的情况如上下班时间。
  • LocalDateTime:表示本地的日期和时间,因此适用于同时强调日期和时间的情况,如考试时间。

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

Library解析

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

  • JodaTimeAndroid类负责初始化相关操作,在开始使用JodaTime_ohos组件之前,都需要通过此类的init()方法进行初始化操作,否则将不能正常访问组件中的类和方法;
  • ResourceZoneInfoProvide类负责监控时区变化,但是此处需要注意的是,鸿蒙里没有提示时区变化的intent;
  • TimeZoneChangedReceiver类则负责处理监控到的时区变化;
  • DateUtils类主要负责将获取到的日期和时间值进行处理得到多种格式。

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

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

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

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

(1)两个参数

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

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

(2)三个参数:

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

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

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

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

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

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

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

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

项目贡献人

陈丛笑 郑森文 朱伟 陈美汝 李珂

相关推荐

为何越来越多的编程语言使用JSON(为什么编程)

JSON是JavascriptObjectNotation的缩写,意思是Javascript对象表示法,是一种易于人类阅读和对编程友好的文本数据传递方法,是JavaScript语言规范定义的一个子...

何时在数据库中使用 JSON(数据库用json格式存储)

在本文中,您将了解何时应考虑将JSON数据类型添加到表中以及何时应避免使用它们。每天?分享?最新?软件?开发?,Devops,敏捷?,测试?以及?项目?管理?最新?,最热门?的?文章?,每天?花?...

MySQL 从零开始:05 数据类型(mysql数据类型有哪些,并举例)

前面的讲解中已经接触到了表的创建,表的创建是对字段的声明,比如:上述语句声明了字段的名称、类型、所占空间、默认值和是否可以为空等信息。其中的int、varchar、char和decimal都...

JSON对象花样进阶(json格式对象)

一、引言在现代Web开发中,JSON(JavaScriptObjectNotation)已经成为数据交换的标准格式。无论是从前端向后端发送数据,还是从后端接收数据,JSON都是不可或缺的一部分。...

深入理解 JSON 和 Form-data(json和formdata提交区别)

在讨论现代网络开发与API设计的语境下,理解客户端和服务器间如何有效且可靠地交换数据变得尤为关键。这里,特别值得关注的是两种主流数据格式:...

JSON 语法(json 语法 priority)

JSON语法是JavaScript语法的子集。JSON语法规则JSON语法是JavaScript对象表示法语法的子集。数据在名称/值对中数据由逗号分隔花括号保存对象方括号保存数组JS...

JSON语法详解(json的语法规则)

JSON语法规则JSON语法是JavaScript对象表示法语法的子集。数据在名称/值对中数据由逗号分隔大括号保存对象中括号保存数组注意:json的key是字符串,且必须是双引号,不能是单引号...

MySQL JSON数据类型操作(mysql的json)

概述mysql自5.7.8版本开始,就支持了json结构的数据存储和查询,这表明了mysql也在不断的学习和增加nosql数据库的有点。但mysql毕竟是关系型数据库,在处理json这种非结构化的数据...

JSON的数据模式(json数据格式示例)

像XML模式一样,JSON数据格式也有Schema,这是一个基于JSON格式的规范。JSON模式也以JSON格式编写。它用于验证JSON数据。JSON模式示例以下代码显示了基本的JSON模式。{"...

前端学习——JSON格式详解(后端json格式)

JSON(JavaScriptObjectNotation)是一种轻量级的数据交换格式。易于人阅读和编写。同时也易于机器解析和生成。它基于JavaScriptProgrammingLa...

什么是 JSON:详解 JSON 及其优势(什么叫json)

现在程序员还有谁不知道JSON吗?无论对于前端还是后端,JSON都是一种常见的数据格式。那么JSON到底是什么呢?JSON的定义...

PostgreSQL JSON 类型:处理结构化数据

PostgreSQL提供JSON类型,以存储结构化数据。JSON是一种开放的数据格式,可用于存储各种类型的值。什么是JSON类型?JSON类型表示JSON(JavaScriptO...

JavaScript:JSON、三种包装类(javascript 包)

JOSN:我们希望可以将一个对象在不同的语言中进行传递,以达到通信的目的,最佳方式就是将一个对象转换为字符串的形式JSON(JavaScriptObjectNotation)-JS的对象表示法...

Python数据分析 只要1分钟 教你玩转JSON 全程干货

Json简介:Json,全名JavaScriptObjectNotation,JSON(JavaScriptObjectNotation(记号、标记))是一种轻量级的数据交换格式。它基于J...

比较一下JSON与XML两种数据格式?(json和xml哪个好)

JSON(JavaScriptObjectNotation)和XML(eXtensibleMarkupLanguage)是在日常开发中比较常用的两种数据格式,它们主要的作用就是用来进行数据的传...

取消回复欢迎 发表评论:

请填写验证码