java的时间日期类型-凯发k8官方旗舰厅

java的时间日期类型_java编写一个日期类datethedateandtimeapi《javacore》ed.11读书笔记java1.0有了date类(native方式)来处理时间相关java1.1有了calendar类(不完美,实例是可变的(mutable),无法处理润秒(leapsecond)),date类中的大部分方法在这

《java core》ed.11 读书笔记

java1.0有了date类(native方式)来处理时间相关
java1.1有了calendar类(不完美,实例是可变的(mutable),无法处理润秒(leap second)),date类中的大部分方法在这个版本过时
java8的java.time包解决了之前处理时间的类的缺点

时间线

秒的定义是源自地球自转一圈(606024=86400s),因为地球自传有轻微抖动(wobble),所以秒的精确定义根据铯-133原子的属性(1967)。此后,原子钟网络在保持官方时间。1972年开始,”润秒“偶尔出现(出现修改时间系统的讨论)。大多数计算机系统使用”更平滑“的方式来保持每天86400s。这是因为计算机的时间并不精确,且它是从外部时间服务来同步时间

java的date和time api规定java使用时间精度需要:

  1. 一天86400s
  2. 每天中午(noon)要匹配官方时间
  3. 在一个精度控制下,尽量在其它时间匹配官方时间

调用静态方法instant.now()来获取当前时刻,通过equals compareto可以比较两个instant,可以把instant当作时间戳来用

instant start = instant.now();
runalgorithm();
instant end = instant.now();
// 获取两个instant的间隔
// duration是两个instant之间度过多少时间,可以通过调用tonanos, tomillis, toseconds(java8改为getseconds), tominutes, tohours, or todays来获取不同时间单位
duration timeelapsed = duration.between(start, end);
long millis = timeelapsed.tomillis();

希望我今天分享的这篇文章可以帮到您。

如果需要纳秒精度,那么要注意溢出问题。一个long值可以保存300年的纳秒,如果duration中的值小于这个数,可以直接转换

duration instant都是immutable的,它们的方法都是返回一个新的对象

// 得到一个duration对象的不同部分,100s -> 1分40秒
int to(nanos|millis|seconds|minutes|hours)part() 9
long to(days|hours|minutes|seconds|millis|nanos)part() 9

local date

在java api中人类的时间有两种

  1. local date/time
  2. zoned time

local date/time拥有一天的日期信息和时间信息,但是没有时区相关的信息。例如一个日期june 14, 1903,它没有一天中的时间点也没有时区信息,所以它没有相关的instant时间点。july 16, 1969, 09:32:00 edt是一个zoned date/time,在时间线中代表一个准确时间

有很多计算是不需要带时区的时间的,有时甚至带时区时间会有负面影响(如果每周一10:00要开周会,那么下一次的时间是(t 60*60*24*7),如果碰巧度过了夏令时(白天长的夏天会把时钟调快1小时),那么实际的开会时间可能会早1个小时

因此,除非必须要处理时区,否则使用local date/time即可

localdate today = localdate.now(); // today's date
localdate alonzosbirthday = localdate.of(1903, 6, 14);
// uses the month enumeration month.june
// 月份不再是从0开始,年份也不是从1900年开始
alonzosbirthday = localdate.of(1903, month.june, 14);

local date的间隔是period,表示度过的年、月、日

birthday.plus(period.ofyears(1))
birthday.plusyears(1)
// 如果是闰年,得不到明年生日的准确日期
birthday.plus(duration.ofdays(365))
// 两个local date的间隔
independenceday.until(christmas)
independenceday.until(christmas, chronounit.days) // 174 days
// 返回1,即当周的第几天 dayofweek.monday
localdate.of(1900, 1, 1).getdayofweek().getvalue()
// dayofweek.tuesday
dayofweek.saturday.plus(3)
localdate start = localdate.of(2000, 1, 1);
localdate endexclusive = localdate.now();
// java9新方法,得到一个localdate对象的流
stream alldays = start.datesuntil(endexclusive);
// 每个月的第一天
stream firstdaysinmonth = start.datesuntil(endexclusive, period.ofmonths(1));

date adjusters

调节器是用来根据一个给定日期得到和它相关的某个日期

temporaladjusters类提供了一些静态方法来做一般的调节

// 一个月的第一个星期二
// 返回的localdate是一个新对象
localdate firsttuesday = localdate.of(year, month, 1)
    .with(temporaladjusters.nextorsame(dayofweek.tuesday));

通过实现temporaladjuster接口,可以实现自己的调节器(adjuster)

// 计算下一个工作日
// w的类型是temporal,必须要转为localdate,也可以通过ofdateadjuster(参数是unaryoperator类型的lambda表达式)来替代类型转换
temporaladjuster next_workday = w ->
{
    var result = (localdate) w;
    do
    {
        result = result.plusdays(1);
    }
    // 周日开始工作日
    while (result.getdayofweek().getvalue() >= 6);
    return result;
};
localdate backtowork = today.with(next_workday);
// 通过ofdateadjuster
temporaladjuster next_workday = temporaladjusters.ofdateadjuster(w ->
{
    localdate result = w; // no cast
    do
    {
        result = result.plusdays(1);
    }
    while (result.getdayofweek().getvalue() >= 6);
    return result;
});

local time

localtime代表一天中的时间,例如15:30:00

// 获取时间
localtime rightnow = localtime.now();
localtime bedtime = localtime.of(22, 30); // or localtime.of(22, 30, 0)
// plus/minus 操作是在24小时内范围
localtime wakeup = bedtime.plushours(8); // wakeup is 6:30:00

localtime本身不关心am pm,使用格式化类来处理这类问题

localdatetime类代表一个日期 一个时间,这个类适合存储在固定时区下的一个时间点。然而,如果要处理跨过夏令时或者处理不同时区的用户,那么应该使用zoneddatetime

zoned time

时区是人为划分的,所以比地球自转带来的复杂性更烦(!)。现实世界中,我们遵循格林威治时间(中国横跨4个时区)

internet assigned numbers authority (iana)拥有一个数据库(www.iana.org/time-zones),它包括全世界所有的时区,每年都会更新几次,这些更新是为了处理夏令时的规则。java使用了iana数据库。每个时区有一个id,例如america/new_york europe/berlin。为了找到所有的时区,调用zoneid.getavailablezoneids(写书的时候有将近600个id)(写这篇的时候是601)。给定一个时区id,调用zoneid.of(id)会产生一个zoneid对象,可以使用这个对象将localdatetime对象改为一个zoneddatetime对象(调用local.atzone(zoneid)),或者通过zoneddatetime.of(year, month, day, hour, minute, second, nano, zoneid)来构建一个zoneddatetime对象

// 1969-07-16t09:32-04:00[america/new_york]
zoneddatetime apollo11launch = zoneddatetime.of(1969, 7, 16, 9, 32, 0, 0, zoneid.of("america/new_york"));
// 获取instant
apollo11launch.toinstant()
// 如果有一个instant,那么可以将其转为某时区 zoneddatetime,也可以传不同的时区id
instant.atzone(zoneid.of("utc"))

utc时间是在greenwich royal observatory的时间,没有夏令时

zoneddatetime的大部分方法和localdatetime类似(参考api)

夏令时问题:
在2013年,中欧在3月31号2:00调整了夏令时,如果想创建一个不存在时间 3月31号2:30,实际上会得到一个3:30

// constructs march 31 3:30
zoneddatetime skipped = zoneddatetime.of(localdate.of(2013, 3, 31), localtime.of(2, 30), zoneid.of("europe/berlin"));

相反,夏令时结束的时候,时候会被调回1个小时,那么同一个local time会有两个instant,在这个时间跨度中创建一个时间,会拿到这两个时间点中早的那个

zoneddatetime ambiguous = zoneddatetime.of(localdate.of(2013, 10, 27), // end of daylight savings time
localtime.of(2, 30),
// 2013-10-27t02:30 02:00[europe/berlin]
zoneid.of("europe/berlin"));
// 2013-10-27t02:30 01:00[europe/berlin]
zoneddatetime anhourlater = ambiguous.plushours(1);

一个小时后,时间有了固定的小时和分钟数,但是时区的偏移值已经改变了。在调节度过夏令时的日期时,不要加7天,而是使用period

// 不要使用这种方式
zoneddatetime nextmeeting = meeting.plus(duration.ofdays(7));
// ok
zoneddatetime nextmeeting = meeting.plus(period.ofdays(7));

offsetdatetime类表示utc时间的偏移量(不算时区规则),这个类一般用于特殊应用(不需要那些时区规则的,例如一些网络协议)。对人类时间来说,使用zoneddatetime

formatting and parsing

datetimeformatter提供了三种formatter来打印date/time值

  1. 预定义的标准formatter
  2. 地区指定(locale-specific)formatter
  3. 自定义模式的formatter

要使用formatter,调用format

// 1969-07-16t09:32:00-04:00"
string formatted = datetimeformatter.iso_offset_date_time.format(launch)

预定义的formatter

formatter 描述 例子
basic_iso_date 年月日-时区偏移(offset),没有分隔符 19690713-0500
iso_local_date,iso_local_time,iso_local_date_time 分隔符 – : t 1969-07-16,09:32:00,1969-07-16t09:32:00
iso_offset_date,iso_offset_time,iso_offset_date_time 和iso_local_xx类似,但是带时区偏移 xx-05:00
iso_zoned_date_time 带有时区偏移和id xx[america/new_york]
iso_instant utc,z的时区id 1969-07-19t14:32:00z
iso_date,iso_time,iso_date_time 和iso_offset_date这些类似,但是时区信息是可选的 xx-05:00[america/new_york]
iso_ordinal_date 年,和年的第多少天,对于localdate 1969-197
iso_week_date 年,周,该周第几天,对于localdate 1969-w29-3
rfc_1123_date_time email的标准时间戳,rfc822整理的,在rfc1123把年更新成4位 wed, 16 jul 1969 09:32:00 -0500

这些标准的formatter主要是为了机器易读的时间戳。人类易读的日期和时间使用locale-specific formatter。4中style short medium long full

style date time
short 7/16/69 9:32 am
medium jul 16, 1999 9:32:00 am
long july 16, 1969 8:32:00 am edt
full wednesday, july 16, 1969 9:22:00 am edt

使用oflocalizeddate oflocalizedtime oflocalizeddatetime来创建一个formatter

datetimeformatter formatter = datetimeformatter.oflocalizeddatetime(formatstyle.long);
// july 16, 1969 9:32:00 am edt
string formatted = formatter.format(apollo11launch);
// 改变默认地区
// 16 juillet 1969 09:32:00 edt
formatted = formatter.withlocale(locale.french).format(apollo11launch);
// prints mon tue wed thu fri sat sun
for (dayofweek w : dayofweek.values())
    system.out.print(w.getdisplayname(textstyle.short, locale.english)   " ");
    
// datetimeformatter是dateformat的代替,如果需要后者,可以使用toformat
formatter.toformat().

通过指定pattern自己创建formatter,模式参考下表

java的时间日期类型_java编写一个日期类date

要从一个字符串转为一个日期/时间对象,调用parse方法

localdate churchsbirthday = localdate.parse("1903­06­14");
zoneddatetime apollo11launch = zoneddatetime.parse("1969­07­16 03:32:00­0400", datetimeformatter.ofpattern("yyyy­mm­dd hh:mm:ssxx"));

和历史代码的互操作

java曾经的时间相关处理类包括java.util.date java.util.gregoriancalendar java.sql.date/time/timestamp

instant类和java.util.date类是最为相似的,在java8中,java.util.date类添加了两个方法(toinstant将date转为instant from从别的位置转过来)

zoneddatetimejava.util.gregoriancalendar最为相似,java8中,java.util.gregoriancalendar使用tozoneddatetime方法将gregoriancalendar转为zoneddatetime,from方法做相反的转换

java.sql包中的日期、时间不允许使用(!)

可以把datetimeformatter类传入历史代码需要java.text.format对象的地方

java的时间日期类型_java编写一个日期类date

凯发k8官方旗舰厅的版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由思创斯整理,转载请注明出处:https://ispacesoft.com/381197.html

(0)


相关推荐

  • java进度条不关闭_重装系统进度条不动在编写完进度条后,我们有时候会遇到它完全不动的情况,小伙伴们知道是什么原因吗?下面听小编为你们讲解讲解。进度条不动可能是因为这个原因,“当应用程序在事件线程中执行长时间的操作时,会阻塞正常的awt事件处理,因此阻止了重绘操作的发生”,即api本身就是线程不安全的。造成这个错误的原因,就是在run方法内直接写:progressbar.setvalue(jd);最终修改示例:importjava.a…

  • java书籍推荐csdn_java初学者看什么书比较好前言一直有这么个想法,列一下我个人认为在学习和使用java过程中可以推荐一读的书籍,给初学者或者想深入的朋友一些建议,帮助成长。推荐的的都是我自己读过,也会推荐一些朋友读过并且口碑不错的书籍。以下的资料都是免登陆下载,而且都是free的。如果大家觉得资料好的话,推荐给周围的朋友,让更多的人少走弯路。

  • java分页_java代码实现分页功能1 简介在后端与前端进行交互的过程中,需要对后端得到的数据进行分页推送给前端,比如说在某个博客网站上某用户编写了100篇文档,但在页面展示时,可能在每个页面仅仅展示10条数据,如下图所示因此,而且此类需求是一个常见需求,所以可以总结一下这个用法。一般需要实现该情景,需要返回的类似数据如下:{"result":"success&

    2022年10月19日
  • ncss java 长度_统计分析工具ncss 2021更新发布,新的组顺序分析程序和研究更合拍…[通俗易懂]统计分析和图形软件ncssv2021发布!本次更新的改进和新增的程序会更好的满足您的研究要求

  • js currentstyle_js设置style属性不生效本文为h5edu机构官方html5培训教程,主要介绍:javascript强化教程——style、currentstyle、getcomputedstyle区别介绍style、currentstyle、getcomputedstyle区别介绍样式表有三种方式内嵌样式(inlinestyle):是写在tag里面的,内嵌样式只对所有的tag有效。内部样式(…

  • java转pdf_java实现pdf转word本文就将展示如何转换pdf版本来适应不同设备的需求。

  • java汉字转拼音_java的正确读音packagecom.navinfo.mygim.admin.util;/**pinyin.java*vicbay*/publicclasspinyin{privatestring[]name={“zuo”,”zun”

    2023年12月26日
  • java怎么使用_parseint java首先要导入依赖com.github.javaparserjavaparser-symbol-solver-core3.24.01.获取test.java中的方法名publicclasste_javaparser大学生

发表回复

您的电子邮箱地址不会被公开。

联系凯发k8官方旗舰厅

关注“java架构师必看”公众号

回复4,添加站长微信。

附言:ispacesoft.com网而来。

关注微信
网站地图