Android關於獲取時間的記錄

初涉江湖,還望海涵!
寫點東西,純粹是由於我的的記憶能力較弱,寫些筆記罷了,如有錯誤還望雅正!java

對Android中的時間獲取作個記錄,如下爲結果!

clipboard.png

代碼粘貼api

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 timestamp
2 date
3 SimpleDateFormat
4 Calendar
5 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:ide

  • 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類的註釋特別描述了ui

  • 日曆記時中,一年定爲365天,閏年多一天,這代表,時間並不老是一天246060*60毫秒,須要用閏年加一天來調整。在coordinated universal time (UTC)的時間定義中,是經過閏秒(leap second)來調整時間的,而且老是在6月30日或12月31日,具體表現爲該類對秒的限制在0 to 61,60和61發生在leap second時。

構造函數this

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(棄用)了spa

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;這樣的寫法,其實才是最舒服的(我的感受),固然,最重要的仍是安全問題

相關文章
相關標籤/搜索