Android关于获取时间的记录

28次阅读

共计 8081 个字符,预计需要花费 21 分钟才能阅读完成。


初涉江湖,还望海涵!写点东西,纯粹是因为个人的记忆能力较弱,写些笔记罢了,若有错误还望雅正!
对 Android 中的时间获取做个记录,以下为结果!

代码粘贴
public class MainActivity extends AppCompatActivity {
public static final String TAG = “MainActivity”;

@RequiresApi(api = Build.VERSION_CODES.CUPCAKE)
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//timestamp
TextView timestamp = findViewById(R.id.timestamp_show);
timestamp.setText(“timestamp:” + System.currentTimeMillis());
//date
Date date = new Date();
TextView date_show = findViewById(R.id.date_show);
date_show.setText(“Date:” + date.toString());
//Calendar
TextView calendar_show = findViewById(R.id.calendar_show);
Calendar calendar = Calendar.getInstance();
int year = calendar.get(Calendar.YEAR);
int month = calendar.get(Calendar.MONTH);
int day = calendar.get(Calendar.DATE);
int hour = calendar.get(Calendar.HOUR);
int minute = calendar.get(Calendar.MINUTE);
int second = calendar.get(Calendar.SECOND);
String calendar_show_string = “Calendar:” + year + “-” + month + “-” + day
+ ” ” + hour + “:” + minute + “:” + second;
calendar_show.setText(calendar_show_string);
//Time
TextView time_show = findViewById(R.id.time_show);
Time time = new Time();
time.setToNow();
int time_year = time.year;
int time_month = time.month;
int time_day = time.monthDay;
int time_hour = time.hour;
int time_minute = time.minute;
int time_second = time.second;
String time_show_string = “Time:” + time_year + “-” + time_month + “-”
+ time_day + ” ” + time_hour + “:” + time_minute + “:” + time_second;
time_show.setText(time_show_string);
//SimpleDateFormat
TextView simpleDateFormat_show = findViewById(R.id.simpleDateFormat_show);
SimpleDateFormat format = new SimpleDateFormat(“yyyy-MM-dd HH:mm:ss”);
String simpleDateFormat_tring = “SimpleDateFormat:” + format.format(new Date());
simpleDateFormat_show.setText(simpleDateFormat_tring);
Log.d(TAG, “onCreate: Long 的最大值:” + Long.MAX_VALUE);

}
根据自己使用过的以及网上搜索得到的结果,整理记录了以下方法
1 timestamp2 date3 SimpleDateFormat4 Calendar5 Time
1 timestamp
//timestamp
TextView timestamp = findViewById(R.id.timestamp_show);
timestamp.setText(“timestamp:” + System.currentTimeMillis());
timestamp,时间戳。使用时调用 System 类的 currentTimeMillis()方法,该方法的描述是:
/**
* Returns the current time in milliseconds. Note that
* while the unit of time of the return value is a millisecond,
* the granularity of the value depends on the underlying
* operating system and may be larger. For example, many
* operating systems measure time in units of tens of
* milliseconds.
*
* <p> See the description of the class <code>Date</code> for
* a discussion of slight discrepancies that may arise between
* “computer time” and coordinated universal time (UTC).
*
* @return the difference, measured in milliseconds, between
* the current time and midnight, January 1, 1970 UTC.
* @see java.util.Date
*/
public static native long currentTimeMillis();
可以看出,该方法返回的是 long 类型的结果,结果记录的是 midnight, January 1, 1970 UTC 至今经过的毫秒数(milliseconds)。
System.currentTimeMillis()是一个 native 方法,是一个 C /C++ 方法,由系统测量时间戳并返回测量结果,根据注释描述,测量结果可能偏大,因为有些操作系统测量时间是以十毫秒为单位的,类 Date 中讨论了关于系统时间和 UTC 时间产生差异的原因,可自行观看!
Note:

UTC(coordinated universal time)是民用时间的标准,众所周知,地球围绕太阳公转一周的时间定义为一年,地球自转一周定义为一天。有科学报道说,地球漫长的公转中其实是在缓慢的接近太阳,不管是否属实,自转和公转会产生一些变化也是不可避免的,UTC 就是正确测量时间的规则,当测量到需要校正时间时,会以毫秒为单位进行调整,称之为闰秒(leap seconds),后面 Time 会提到!
System.currentTimeMillis()的返回结果是一个记录从 1970 开始的毫秒数的 long 型结果,最容易想到的是 long 是有范围区间的,如果有一天记录的毫秒数超出 long 的范围怎么办!所以我计算了以下,long 的最大值为 0x7fff,ffff,ffff,ffff,取整大约为 922 亿亿,一年算 365 天,不考虑闰年,一天 246060*60 毫秒一年取整大约 18 亿毫秒,922 亿 /18,大约为 50 亿年,考虑到太阳的寿命,貌似也有用尽的一天。。。。但是,那么长的时间,鬼知道会发展成什么样!

2 Date
//date
Date date = new Date();
TextView date_show = findViewById(R.id.date_show);
date_show.setText(“Date:” + date.toString());
通过实例化 Date 类获取 date 实例从而获取时间,简单通过 toString()打印结果
Date 类的注释特别描述了
日历记时中,一年定为 365 天,闰年多一天,这表明,时间并不总是一天 246060*60 毫秒,需要用闰年加一天来调整。在 coordinated universal time (UTC)的时间定义中,是通过闰秒 (leap second) 来调整时间的,并且总是在 6 月 30 日或 12 月 31 日,具体表现为该类对秒的限制在 0 to 61,60 和 61 发生在 leap second 时。
构造函数
public Date() {
this(System.currentTimeMillis());
}

public Date(long date) {
fastTime = date;
}

/**
* @param year the year minus 1900.
* @param month the month between 0-11.
* @param date the day of the month between 1-31.
* @param hrs the hours between 0-23.
* @param min the minutes between 0-59.
* @param sec the seconds between 0-59.
* @see java.util.Calendar
* @deprecated As of JDK version 1.1,
* replaced by <code>Calendar.set(year + 1900, month, date,
* hrs, min, sec)</code> or <code>GregorianCalendar(year + 1900,
* month, date, hrs, min, sec)</code>.
*/
@Deprecated
public Date(int year, int month, int date, int hrs, int min, int sec) {
int y = year + 1900;
// month is 0-based. So we have to normalize month to support Long.MAX_VALUE.
if (month >= 12) {
y += month / 12;
month %= 12;
} else if (month < 0) {
y += CalendarUtils.floorDivide(month, 12);
month = CalendarUtils.mod(month, 12);
}
BaseCalendar cal = getCalendarSystem(y);
cdate = (BaseCalendar.Date) cal.newCalendarDate(TimeZone.getDefaultRef());
cdate.setNormalizedDate(y, month + 1, date).setTimeOfDay(hrs, min, sec, 0);
getTimeImpl();
cdate = null;
}
无参大 Date()直接把 System.currentTimeMillis()的时间戳返回给 fastTime,另一个就是设定好年月日时分秒来创建对象,其中的设定是年是 1900+ 参数 year 并且也对月份超出范围做出了处理,但是该构造方法已是 @Deprecated(弃用)了
Date 类中大部分的方法都已经弃用,要特别是单独获取年或者月等信息的方法,基本上都已经弃用,留下的有打印即 toString()和一些比较等功能性的方法
3 SimpleDateFormat
//SimpleDateFormat
TextView simpleDateFormat_show = findViewById(R.id.simpleDateFormat_show);
SimpleDateFormat format = new SimpleDateFormat(“yyyy-MM-dd HH:mm:ss”);
String simpleDateFormat_tring = “SimpleDateFormat:” + format.format(new Date());
simpleDateFormat_show.setText(simpleDateFormat_tring);
SimpleDateFormat 类的核心是 Text 的 formatting(格式化)和 Time 的 parsing(解析),SimpleDateFormat()通过传入一个字符串来格式化需要的表现形式,样例中通过调用 format()传入 Date 无参对象,实际上是调用 System.currentTimeMillis()获取最基本的时间,SimpleDateFormat 类的作用是把传入的 Date 类时间定制化封装,从而得到需要的结果。
Note:关于 SimpleDateFormat 类,可以很自由的定制表现形式,年月日时分秒,时间格式,AD/BC。。。
定制化所用字母的含义:

G => AD/BC(年份为负数时),1+
y => Year,1+
Y => Week year,24+
M => Month in year,1+
w => Week in year,1+
W => Week in month,1+
D => Day in year,1+
d => Day in month,1+
F => Day of week in month,1+
E => Day name in week,1+
u => Day number of week(1 = Monday, …, 7 = Sunday),24+
a => Am/pm marker,1+
H => Hour in day (0-23),1+
k => Hour in day (1-24),1+
K => Hour in am/pm (0-11),1+
h => Hour in am/pm (1-12),1+
m => Minute in hour,1+
s => Second in minute,1+
S => Millisecond,1+
z => Time zone:General time zone,PST,GMT-08:00,1+
Z => Time zone:RFC 822 time zone,1+
X => Time zone:ISO 8601 time zone,1+

定制化使用 ” 字符串 ”,在该字符串中使用 ’ 字符 ’ 表示在年月日等数据外的部分,如分隔符
SimpleDateFormat 类的时间格式定制包括年月日等数据的表现形式,连接符,日期格式的描述,如 Time zone,AM/PM,AD/BC。。。
SimpleDateFormat 类中存在的问题是线程同步
/**
* Date formats are not synchronized.
* It is recommended to create separate format instances for each thread.
* If multiple threads access a format concurrently, it must be synchronized
* externally.
*/
SimpleDateFormat 是线程不同步的,要在多线程中使用则要在线程外同步.
4 Calendar
//Calendar
TextView calendar_show = findViewById(R.id.calendar_show);
Calendar calendar = Calendar.getInstance();
int year = calendar.get(Calendar.YEAR);
int month = calendar.get(Calendar.MONTH);
int day = calendar.get(Calendar.DATE);
int hour = calendar.get(Calendar.HOUR);
int minute = calendar.get(Calendar.MINUTE);
int second = calendar.get(Calendar.SECOND);
String calendar_show_string = “Calendar:” + year + “-” + month + “-” + day + ” ” + hour + “:” + minute + “:” + second;
calendar_show.setText(calendar_show_string);
Calendar 是一个抽象类通过其内定义的 Calendar.getInstance()静态方法实例化对象而该静态方法最终是通过返回一个 new GregorianCalendar(zone, aLocale)来实现初始化!
Calendar 类内部定义了关于时间需要用到的索引并用一个 int 数组存储相关数据
public final static int ERA = 0;
public final static int YEAR = 1;
public final static int MONTH = 2;
public final static int WEEK_OF_YEAR = 3;

@SuppressWarnings(“ProtectedField”)
protected int fields[];

public int get(int field)
{
complete();
return internalGet(field);
}

protected final int internalGet(int field)
{
return fields[field];
}
Calendar 类的简单实用就是通过调用 get 方法从数组中获取相应的数据
5 Time
//Time
TextView time_show = findViewById(R.id.time_show);
Time time = new Time();
time.setToNow();
int time_year = time.year;
int time_month = time.month;
int time_day = time.monthDay;
int time_hour = time.hour;
int time_minute = time.minute;
int time_second = time.second;
String time_show_string = “Time:” + time_year + “-” + time_month + “-” + time_day + ” ” + time_hour + “:” + time_minute + “:” + time_second;
time_show.setText(time_show_string);
把这段代码打入到剪辑器,你会看到 Time 这个类是弃用了的
官方的注释解释是这样的
/**
* An alternative to the {@link java.util.Calendar} and
* {@link java.util.GregorianCalendar} classes. An instance of the Time class represents
* a moment in time, specified with second precision. It is modelled after
* struct tm. This class is not thread-safe and does not consider leap seconds.
*/
可以看到,描述上说,这是线程不安全的类,同时也没有处理 leap seconds(闰秒)的能力,还举出了几个例子。
虽然是弃用的方法,但是还是可以看看怎么使用 Time 类的,简单地说,就是通过对象. 变量的形式获取,也就是说,Time 不像 Calendar 类那样使用数组存储数据,Time 就是通过创建 public int 数据 的形式来保存数据,也就是这些数据都是 public 的
总的来说,获取数据的时候,通过 Time 的形式,如 int time_hour = time.hour; 这样的写法,其实才是最舒服的(个人感觉),当然,最重要的还是安全问题

正文完
 0