Android 时间 日期 相关

参考
Java日期时间使用总结
Java Calendar,Date,DateFormat,TimeZone,Locale(1) Calendar
Java Calendar,Date,DateFormat,TimeZone,Locale(2) 自己封装的Calendar接口
Java Calendar,Date,DateFormat,TimeZone,Locale(3) Date
Java Calendar,Date,DateFormat,TimeZone,Locale(4) DateFormat
Java Calendar,Date,DateFormat,TimeZone,Locale(5) SimpleDateFormat
Java Calendar,Date,DateFormat,TimeZone,Locale(6) Locale
Java Calendar,Date,DateFormat,TimeZone,Locale(7) TimeZone

一、概念

参考时间标准总结 IAT、UT、UTC、GMT、夏令时
1.格林尼治标准时间:Greenwich Mean Time(简称 GMT)
GMT 以格林尼治天文台经线为 0 度经线,将世界分为 24 个时区,向东时间快,向西时间慢。
UTC是基于标准的GMT提供的准确时间。(在计算机中 GMT 时间和 UTC 时间是一样的)

2.夏令时与冬令时 Daylight Saving Time(简称 DST)
又称“日光节约时制”和“夏令时间”,是一种为节约能源而人为规定地方时间的制度,在这一制度实行期间所采用的统一时间称为“夏令时间”。
一般在天亮早的夏季人为将时间提前一小时,可以使人早起早睡,减少照明量,以充分利用光照资源,从而节约照明用电。各个采纳夏时制的国家具体规定不同。目前全世界有近110个国家每年要实行夏令时。
自2011年3月27日开始俄罗斯永久使用夏令时,把时间拨快一小时,不再调回。
简单来说,使用夏令时和冬令时即在夏季将时间拨快一个小时,等到冬季再将时间拨慢一个小时。

举个例子总结一下:
假设当前 GMT 时间为 13:00,已知北京时间为 GMT+8(北京位于东 8 区),所以北京时间为 13:00 + 8 = 21:00。
但当存在夏令时时,会出现不同。比如已知莫斯科时间为 GMT+3,理论上莫斯科时间为 16:00,但是由于俄罗斯永久使用夏令时,所以实际上莫斯科时间为 17:00。

3.开发规范
在实际开发中,当时间用于显示时,非特殊要求下一般使用系统默认的时区时间作为显示时间。将时间做为数据存储或传递给其他系统时(特别是跨平台调用),则最好使用标准的UTC/GMT时间(后面统称GMT),除非事先约定或标识了时间的类型。

因为用户很有可能会有更改时区的操作出现,如果使用对应时区的时间戳,并且时间戳作为某种标记量存入了数据库,那么一旦时区发生改变,已存数据将会与当前时区设置产生问题;而使用标准时间戳则可以避免这一问题,因为通过程序可以很容易地将时间戳转化为标准时间戳,并且标准时间戳是固定的,这样就能保证即使在修改了时区的情况下,也能正确处理日期时间。

二、Calendar日历 与 Gregorian Calendar公历

参考Java Calendar类详解
在历史上有着许多种纪元的方法。它们的差异实在太大了,比如说一个人的生日是"八月八日" 那么一种可能是阳(公)历的八月八日,但也可以是阴(农)历的日期。所以为了计时的统一,必需指定一个日历的选择。那现在最为普及和通用的日历就是 "Gregorian Calendar"。也就是我们在讲述年份时常用 "公元几几年"。Calendar 抽象类定义了足够的方法,让我们能够表述日历的规则。Java 本身提供了对 "Gregorian Calendar" 规则的实现。我们从 Calendar.getInstance() 中所获得的实例就是一个 "GreogrianCalendar" 对象(与您通过 new GregorianCalendar() 获得的结果一致)。

Calendar 在 Java 中是一个抽象类(Abstract Class),GregorianCalendar 是它的一个具体实现。

我们也可以自己的 Calendar 实现类,然后将它作为 Calendar 对象返回(面向对象的特性)。在 IBM alphaWorks 上,IBM 的开发人员实现了多种日历。同样在 Internet 上,也有对中国农历的实现。本文对如何扩展 Calendar 不作讨论,大家可以通过察看上述 Calendar 的源码来学习。

三、Date DateFormat SimpleDateFormat

java.util.Date
类 Date 表示特定的瞬间,精确到毫秒。从 JDK 1.1 开始,应该使用 Calendar 类实现日期和时间字段之间转换,使用 DateFormat 类来格式化和分析日期字符串。Date 中的把日期解释为年、月、日、小时、分钟和秒值的方法已废弃。

java.text.DateFormat(抽象类)
DateFormat 是日期/时间格式化子类的抽象类,它以与语言无关的方式格式化并分析日期或时间。日期/时间格式化子类(如 SimpleDateFormat)允许进行格式化(也就是日期 -> 文本)、分析(文本-> 日期)和标准化。将日期表示为 Date 对象,或者表示为从 GMT(格林尼治标准时间)1970 年,1 月 1 日 00:00:00 这一刻开始的毫秒数。

java.text.SimpleDateFormat(DateFormat的直接子类)
参考深入理解Java:SimpleDateFormat安全的时间格式化
SimpleDateFormat 是一个以与语言环境相关的方式来格式化和分析日期的具体类。它允许进行格式化(日期 -> 文本)、分析(文本 -> 日期)和规范化。
SimpleDateFormat 使得可以选择任何用户定义的日期-时间格式的模式。但是,仍然建议通过 DateFormat 中的 getTimeInstance、getDateInstance 或 getDateTimeInstance 来新的创建日期-时间格式化程序。

import java.text.SimpleDateFormat;
import java.util.Date;

public class Data {
   public static void main(String[] args) {
      SimpleDateFormat dateFormat =
      new SimpleDateFormat("yyyy-MM-dd E");//可以查API,根据自己的需要显示格式
      Date date = new Date();
      System.out.println("今天的日期是: "+dateFormat.format(date));
   }
}

DateFormat 和SimpleDateFormat 的区别
参考日期操作类(DateFormat与SimpleDateFormat)的区别和实例
1.DateFormat 可以直接使用,但其本身是一个抽象类,可以根据Locate指定的区域得到对应的日期时间格式
2.SimpleDateFormat 类是DateFormat 类的子类,一般情况下来讲 DateFormat 类很少会直接使用。而都使用SimpleDateFormat 类完成。

Locale
参考Locale简介

import java.util.Locale;

public class LocaleOne {
    public static void main(String[] args) {
       Locale myLocale = Locale.getDefault();
       System.out.println(myLocale.getCountry());//CN
       System.out.println(myLocale.getLanguage());//zh
       System.out.println(myLocale.getDisplayCountry());//中国
       System.out.println(myLocale.getDisplayLanguage());//中文
    }
}

与SimpleDateFormat一起使用:

public static final SimpleDateFormat sdfMd = new 
SimpleDateFormat("M/d", Locale.getDefault());
四、在Android中需要特别注意的事项

参考Android中关于日期时间与时区的使用总结

Android中表示日期时间的类型,有Date、Calendar,他们在没有显示设置其时区时,取到的当前时间均为系统默认时区的时间,即使给定一个时间,同样是按系统默认时区来换算时间,所以说他们都是与时区相关的。SimpleDateFormat对象本身也是跟时区相关。当使用parse将一个字符串格式的日期转换为Date对象,或者将一个Date对象转换为字符串日期时,这个字符串日期的时区以SimpleDateFormat关联的时区为准,如果通过setTimeZone修改了时区,则这个字符串日期以修改后的时区为准。

// 2013-1-31 22:17:14
Date date = new Date(1359641834000L);
System.out.println(date);
String dateStr = "2013-1-31 22:17:14";
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
dateFormat.setTimeZone(TimeZone.getTimeZone("GMT"));
try
{
    //对于已经设定为GMT时间标准的dateFormat来说,
    //一切需要他转换的字符串日期都是GMT标准时间,
    //转换后返回的Date由于默认遵守系统默认时区,
    //所以转换给Date的日期需要+8(例如北京标准时区),
    //也就是时区与标准不同导致的时差。
    Date dateTmp = dateFormat.parse(dateStr);
    System.out.println(dateTmp);
} 
catch (ParseException e) 
{
    e.printStackTrace();  
}  
// Date还是按系统默认时区,而format格式化处来的字符串是GMT,所以要-8。
String dateStrTmp = dateFormat.format(date);  
System.out.println(dateStrTmp);
Paste_Image.png

Calendar在不手动设置时区时,是与系统默认时区相关的。在手动修改时区后,不能使用calendar.getTime方法来直接获取Date日期,因为此时的日期与setTime时的值相同,想要正确获取修改时区后的时间,应该通过calendar的get方法。

Date date = new Date(1359641834000L);
System.out.println(date);
Calendar calendar = Calendar.getInstance();
calendar.setTimeZone(TimeZone.getTimeZone("GMT"));  
//或者可以 Calendar calendar = 
//Calendar.getInstance(TimeZone.getTimeZone("GMT"));  
calendar.setTime(date);
System.out.println(calendar.get(Calendar.HOUR_OF_DAY) + ":" 
+ calendar.get(Calendar.MINUTE));

Calendar calendar2 = Calendar.getInstance();  
calendar2.set(calendar.get(Calendar.YEAR), calendar.get(Calendar.MONTH),
calendar.get(Calendar.DAY_OF_MONTH), calendar.get(Calendar.HOUR_OF_DAY),
calendar.get(Calendar.MINUTE), calendar.get(Calendar.SECOND));

System.out.println(calendar.getTime());  
System.out.println(calendar2.getTime());
Paste_Image.png
五、DatePickerDialog TimePickerDialog

参考Android中DatePickerDialog对话框和TimePickerDialog对话框的使用

点击按钮
弹出选择框
设置完成
package com.lovo;

import java.util.Calendar;

import android.app.Activity;
import android.app.DatePickerDialog;
import android.app.TimePickerDialog;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.DatePicker;
import android.widget.TextView;
import android.widget.TimePicker;

public class MainActivity extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        // 获得设置日期按钮
        Button dateBtn = (Button) findViewById(R.id.btn1);
        // 获得设置时间按钮
        Button timeBtn = (Button) findViewById(R.id.btn2);
        // 为设置日期按钮绑定监听器
        dateBtn.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View arg0) {
                Calendar c = Calendar.getInstance();
                // 直接创建一个DatePickerDialog对话框实例,并将它显示出来
                new DatePickerDialog(MainActivity.this,
                // 绑定监听器
                        new DatePickerDialog.OnDateSetListener() {

                            @Override
                            public void onDateSet(DatePicker view, int year,
                                    int monthOfYear, int dayOfMonth) {
                                TextView show = (TextView) findViewById(R.id.txt1);
                                show.setText("您选择了:" + year + "年" + monthOfYear
                                        + "月" + dayOfMonth + "日");
                            }
                        }
                        // 设置初始日期
                        , c.get(Calendar.YEAR), c.get(Calendar.MONTH), c
                                .get(Calendar.DAY_OF_MONTH)).show();
            }
        });
        // 为设置时间按钮绑定监听器
        timeBtn.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                Calendar c = Calendar.getInstance();
                // 创建一个TimePickerDialog实例,并把它显示出来
                new TimePickerDialog(MainActivity.this,
                // 绑定监听器
                        new TimePickerDialog.OnTimeSetListener() {

                            @Override
                            public void onTimeSet(TimePicker view,
                                    int hourOfDay, int minute) {
                                TextView show = (TextView) findViewById(R.id.txt2);
                                show.setText("您选择了:" + hourOfDay + "时" + minute
                                        + "分");
                            }
                        }
                        // 设置初始时间
                        , c.get(Calendar.HOUR_OF_DAY), c.get(Calendar.MINUTE),
                        // true表示采用24小时制
                        true).show();
            }
        });
    }
}


<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:gravity="center"
    android:orientation="vertical" >

    <Button
        android:id="@+id/btn1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="设置日期" />

    <Button
        android:id="@+id/btn2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="设置时间" />

    <TextView
        android:id="@+id/txt1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />

    <TextView
        android:id="@+id/txt2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />

</LinearLayout>
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容