SimpleDateFormat df = new SimpleDateFormat(ALTERNATIVE_ISO8601_DATE_FORMAT, Locale.US);
df.setTimeZone(new SimpleTimeZone(0, “GMT”));
return df;
}
RFC 822
=======
STANDARD FOR THE FORMAT OF ARPA INTERNET TEXT MESSAGES
其中ARPA网络其实就是互联网的前身。
有些地方会用RFC 822里的时间格式,格式如下
date-time = [ day “,” ] date time ; dd mm yy
; hh:mm:ss zzz
第二个相当于现在格式
==========
“EEE, dd MMM yyyy HH:mm:ss z”
有些头设置采用该格式。
joda中实现如下
// RFC 822 Date Format
private static final String RFC822_DATE_FORMAT = “EEE, dd MMM yyyy HH:mm:ss z”;
private static DateFormat getRfc822DateFormat() {
SimpleDateFormat rfc822DateFormat =
new SimpleDateFormat(RFC822_DATE_FORMAT, Locale.US);
rfc822DateFormat.setTimeZone(new SimpleTimeZone(0, “GMT”));
return rfc822DateFormat;
}
创建SimpleDateFormat的Locale.US可以决定格式字符串某些字符的代替用哪个语言,比如EEE等。
SimpleDateFormat df1=new SimpleDateFormat(“GGGG yyyy/MMMM/dd HH:mm:ss EEE aaa zzzz”,Locale.CHINA);
SimpleDateFormat df2=new SimpleDateFormat(“GGGG yyyy/MMMM/dd HH:mm:ss EEE aaa zzzz”,Locale.US);
//公元 2016/三月/27 23:32:10 星期日 下午 中国标准时间
//AD 2016/March/27 23:32:10 Sun PM China Standard Time
gregorian Calendar, julian Calendar:这是两种历法,我们一般用的通用的gregorian Calendar。
jdk1.8之前
========
主要的类有记录时间戳的Date,时间和日期进行转换的Calendar,用来格式化和解析时间字符串的DateFormat
java.util.Date
==============
使用前要注意时间表示的规则。
还有这个类有很多过期方法不推荐使用,很多已经被Calendar代替。
构造方法
====
这个类代表某个时刻的毫秒值,既然是毫秒值也就说需要有一个参考值。
在接受或返回年、月、日期、小时、分钟和秒值的所有类日期方法中,使用以下表示形式:
年份y由整数y-1900表示。一个月由0到11的整数表示;0是一月,1是二月,依此类推;因此,11月是12月。日期(月的某一天)通常由1到31之间的整数表示。小时由0到23之间的整数表示。因此,从午夜到凌晨1点的时间是0小时,从中午到下午1点的时间是12小时。一分钟通常由0到59之间的整数表示。第二个由0到61之间的整数表示;值60和61仅在闰秒内出现,甚至仅在实际正确跟踪闰秒的Java实现中出现。由于目前引入闰秒的方式,在同一分钟内出现两个闰秒的可能性极低,但本规范遵循ISO C的日期和时间约定。
当我们创建一个Date的时候获取的是哪一个毫秒值?
public Date() {
this(System.currentTimeMillis());
}
public Date(long date) {
fastTime = date;
}
System.currentTimeMillis()是本地方法,the difference, measured in milliseconds, between the current time and midnight, January 1, 1970 UTC。
这个可能会因为操作系统的时间而不准。有些操作系统不一定是用毫秒表示的。这个时间都是用的UTC时间,不和时区有关的,这个无关的意思是同一时刻每个时区下获得的值应该是一致的,可以简单用程序验证一下获取的时间表达内容。
long time = System.currentTimeMillis();
System.out.println(time=(time/1000));
System.out.println(“秒:”+ time%60);
System.out.println(time=(time/60));
System.out.println(“分钟:”+time%60);
System.out.println(time=(time/60));
System.out.println(“小时:”+time%24);
可以理解成和UTC的1970年1月1日零点的差值。而fastTime就是Date类保存这个时刻的变量。
成员变量
====
Date对象打印出来是本地时间,而构造方法是没有时区体现的。那么哪里体现了时区呢?
下面是Date的成员变量
gcal
====
获取的是以下的对象。其中并没有自定义字段。可以说只是一个gregorian(公历)时间工厂获取CalendarDate的子类。
jcal
====
在以下方法中用到
private static final BaseCalendar getCalendarSystem(BaseCalendar.Date cdate) {
if (jcal == null) {
return gcal;
}
if (cdate.getEra() != null) {
return jcal;
}
return gcal;
}
synchronized private static final BaseCalendar getJulianCalendar() {
if (jcal == null) {
jcal = (BaseCalendar) CalendarSystem.forName(“julian”);
}
return jcal;
}
当时间戳在以下情况下用儒略历,并且,在用到的时候会自动设置儒略历,所以在clone的时候也没有这个参数。所以这个可以忽略。
private static final BaseCalendar getCalendarSystem(int year) {
if (year >= 1582) {
return gcal;
}
return getJulianCalendar();
}
private static final BaseCalendar getCalendarSystem(long utc) {
// Quickly check if the time stamp given by `utc’ is the Epoch
// or later. If it’s before 1970, we convert the cutover to
// local time to compare.
if (utc >= 0
|| utc >= GregorianCalendar.DEFAULT_GREGORIAN_CUTOVER
- TimeZone.getDefaultRef().getOffset(utc)) {
return gcal;
}
return getJulianCalendar();
}
fastTime
========
保存了一个时间戳表示时刻。最重要的参数。创建Date就是对这个值的赋值。
cdate
=====
保存了时间相关内容,包括时区,语言等
public static final int FIELD_UNDEFINED = -2147483648;
public static final long TIME_UNDEFINED = -9223372036854775808L;
private Era era;
private int year;
private int month;
private int dayOfMonth;
private int dayOfWeek;
private boolean leapYear;
private int hours;
private int minutes;
private int seconds;
private int millis;
private long fraction;
private boolean normalized;
private TimeZone zoneinfo;
private int zoneOffset;
private int daylightSaving;
private boolean forceStandardTime;
private Locale locale;
defalutCenturyStart
===================
这个值可以忽略,在过期方法中用到。
@Deprecated
public static long parse(String s) {
… …
// Parse 2-digit years within the correct default century.
if (year < 100) {
synchronized (Date.class) {
if (defaultCenturyStart == 0) {
defaultCenturyStart = gcal.getCalendarDate().getYear() - 80;
}
}
year += (defaultCenturyStart / 100) * 100;
if (year < defaultCenturyStart) year += 100;
}
… …
}
serialVersionUID
================
验证版本一致性的UID
wtb
===
保存toString格式化用到的值
ttb
===
保存toString 格式化用到的值
主要方法
====
java.util.Calendar
==================
主要也是其中保存的毫秒值time字段,下面是我们常用的方法,用了默认的时区和区域语言:
public static Calendar getInstance() {
return createCalendar(TimeZone.getDefault(), Locale.getDefault(Locale.Category.FORMAT));
}
国内环境默认GregorianCalendar,但是TH-th用的BuddhistCalendar等
一些坑:
set(int,int,int,int,int,int)方法
==============================
方法不能设置毫秒值,所以当用getInstance后即使用设置相同的值,最后毫秒值也是不一致的。所以如果有需要,将MILLISECOND清零。
set,add,get,roll
================
set方法不会马上计算时间,指是修改了对应的成员变量,只有get()、getTime()、getTimeInMillis()、add() 或 roll()的时候才会做调整
//2000-8-31
Calendar cal1 = Calendar.getInstance();
cal1.set(2000, 7, 31, 0, 0 , 0);
//应该是 2000-9-31,也就是 2000-10-1
cal1.set(Calendar.MONTH, Calendar.SEPTEMBER);
//如果 Calendar 转化到 2000-10-1,那么现在的结果就该是 2000-10-30
cal1.set(Calendar.DAY_OF_MONTH, 30);
//输出的是2000-9-30,说明 Calendar 不是马上就刷新其内部的记录
System.out.println(cal1.getTime());
也就是说多次设置的时候如果中间有需要调整的时间,但是实际是不会做调整的。所以尽量将无法确定的设置之后不要再进行其他调整,防止最后实际值与正常值不准。
add方法会马上做时间修改
=============
roll与add类似,但是roll不会修改更大的字段的值。
java.text.SimpleDateFormat
==========================
创建设置pattern字符串,可以表示的格式如下:
日期格式是不同步的。建议为每个线程创建独立的格式实例。如果多个线程同时访问一个格式,则它必须是外部同步的。
SimpleDateFormat 是线程不安全的类,其父类维护了一个Calendar,调用相关方法有可能会修改Calendar。一般不要定义为static变量,如果定义为 static,必须加锁,或者使用 DateUtils 工具类。 正例:注意线程安全,使用 DateUtils。
org.apache.commons.lang.time.DateUtils,也推荐如下处理:
private static final ThreadLocal df = new ThreadLocal() {
@Override
protected DateFormat initialValue() {
return new SimpleDateFormat(“yyyy-MM-dd”);
}
};
java.sql.Date/Time/Timestamp
============================
这几个类都继承了java.util.Date。
相当于将java.util.Date分开表示了。Date表示年月日等信息。Time表示时分秒等信息。Timestamp多维护了纳秒,可以表示纳秒。
如果是 JDK8 的应用,可以使用 Instant 代替 Date,LocalDateTime 代替 Calendar, DateTimeFormatter 代替SimpleDateFormat,官方给出的解释:simple beautiful strong immutable thread-safe。
jdk1.8的时间类
==========
1.8增加了新的date-time包,遵循JSR310。核心代码主要放在java.time包下。默认的日历系统用的ISO-8601(基于格里高利历)。
java.time下主要内容包括:
java.time -主要包括,日期,时间,日期时间,时刻,期间,和时钟相关的类。
- java.time.chrono -其他非ISO标准的日历系统可以用java.time.chrono,里面已经定义了一部分年表,你也可以自定义。
自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。
深知大多数Java工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!
因此收集整理了一份《2024年Java开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Java开发知识点,真正体系化!
由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!
如果你觉得这些内容对你有帮助,可以扫码获取!!(备注Java获取)
![img](https://img-blog.csdnimg.cn/img_convert/0d5ae6e05656c11ff4012da3da58a249.jpeg)
总结
如果你选择了IT行业并坚定的走下去,这个方向肯定是没有一丝问题的,这是个高薪行业,但是高薪是凭自己的努力学习获取来的,这次我把P8大佬用过的一些学习笔记(pdf)都整理在本文中了
《Java中高级核心知识全面解析》
小米商场项目实战,别再担心面试没有实战项目:
《互联网大厂面试真题解析、进阶开发核心学习笔记、全套讲解视频、实战项目源码讲义》点击传送门即可获取!
学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Java开发知识点,真正体系化!**
由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!
如果你觉得这些内容对你有帮助,可以扫码获取!!(备注Java获取)
![img](https://img-blog.csdnimg.cn/img_convert/0d5ae6e05656c11ff4012da3da58a249.jpeg)
总结
如果你选择了IT行业并坚定的走下去,这个方向肯定是没有一丝问题的,这是个高薪行业,但是高薪是凭自己的努力学习获取来的,这次我把P8大佬用过的一些学习笔记(pdf)都整理在本文中了
《Java中高级核心知识全面解析》
[外链图片转存中…(img-ddDXqDv0-1713518200775)]
小米商场项目实战,别再担心面试没有实战项目:
[外链图片转存中…(img-8P7b8hCB-1713518200777)]
《互联网大厂面试真题解析、进阶开发核心学习笔记、全套讲解视频、实战项目源码讲义》点击传送门即可获取!