(转)android开发中常见日期管理工具类

原地址:http://blog.csdn.net/lenmoyouzi/article/details/17524779


在日常的开发中,我们常常需要根据各种需要,对日期进行不同形式的格式化。这里我将日常用到的日期格式化加以总结。写出个工具方法,欢迎大家总结:

     1、对时间的加减操作,主要需求为闹钟等题型功能,用到的API为:Calendar  

             

[java]  view plain  copy
  1. /** 
  2.      * 获取增加多少月的时间 
  3.      *  
  4.      * @return addMonth - 增加多少月 
  5.      */  
  6.     public static Date getAddMonthDate(int addMonth) {  
  7.         Calendar calendar = Calendar.getInstance();  
  8.         calendar.add(Calendar.MONTH, addMonth);  
  9.         return calendar.getTime();  
  10.     }  
  11.   
  12.     /** 
  13.      * 获取增加多少天的时间 
  14.      *  
  15.      * @return addDay - 增加多少天 
  16.      */  
  17.     public static Date getAddDayDate(int addDay) {  
  18.         Calendar calendar = Calendar.getInstance();  
  19.         calendar.add(Calendar.DAY_OF_YEAR, addDay);  
  20.         return calendar.getTime();  
  21.     }  
  22.     /** 
  23.      * 获取增加多少小时的时间 
  24.      *  
  25.      * @return addDay - 增加多少消失 
  26.      */  
  27.     public static Date getAddHourDate(int addHour) {  
  28.         Calendar calendar = Calendar.getInstance();  
  29.         calendar.add(Calendar.HOUR, addHour);  
  30.         return calendar.getTime();  
  31.     }  

2、按照  yyyy/MM/dd hh:mm等格式显示日期,主要用到的API为:SimpleDateFormat,Time

             

[java]  view plain  copy
  1. /** 
  2.      * 显示时间格式为 hh:mm 
  3.      *  
  4.      * @param context 
  5.      * @param when 
  6.      * @return String 
  7.      */  
  8.     @SuppressLint("SimpleDateFormat")  
  9.     public static String formatTimeShort(Context context, long when) {  
  10.         String formatStr = "HH:mm";  
  11.         SimpleDateFormat sdf = new SimpleDateFormat(formatStr);  
  12.         String temp = sdf.format(when);  
  13.         if (temp != null && temp.length() == 5 && temp.substring(01).equals("0")) {  
  14.             temp = temp.substring(1);  
  15.         }  
  16.         return temp;  
  17.     }  
3、格式时间,让其输出,今天,昨天,两天前以及日期等。

         

[java]  view plain  copy
  1. /** 
  2.      * 显示时间格式为今天、昨天、yyyy/MM/dd hh:mm 
  3.      *  
  4.      * @param context 
  5.      * @param when 
  6.      * @return String 
  7.      */  
  8.     public static String formatTimeString(Context context, long when) {  
  9.         Time then = new Time();  
  10.         then.set(when);  
  11.         Time now = new Time();  
  12.         now.setToNow();  
  13.   
  14.         String formatStr;  
  15.         if (then.year != now.year) {  
  16.             formatStr = "yyyy/MM/dd";  
  17.         } else if (then.yearDay != now.yearDay) {  
  18.             // If it is from a different day than today, show only the date.  
  19.             formatStr = "MM/dd";  
  20.         } else {  
  21.             // Otherwise, if the message is from today, show the time.  
  22.             formatStr = "HH:MM";  
  23.         }  
  24.   
  25.         if (then.year == now.year && then.yearDay == now.yearDay) {  
  26.             return context.getString(R.string.date_today);  
  27.         } else if ((then.year == now.year) && ((now.yearDay - then.yearDay) == 1)) {  
  28.             return context.getString(R.string.date_yesterday);  
  29.         } else {  
  30.             SimpleDateFormat sdf = new SimpleDateFormat(formatStr);  
  31.             String temp = sdf.format(when);  
  32.             if (temp != null && temp.length() == 5 && temp.substring(01).equals("0")) {  
  33.                 temp = temp.substring(1);  
  34.             }  
  35.             return temp;  
  36.         }  
  37.     }  
4、按照上下午显示时间:主要用到的API,DateUtils

             DateUtils.formatDateTime(this, System.getTimeMillis(), DateUtils.FORMAT_SHOW_TIME);

5、判断两个日期是否是同一个日期:

            

[java]  view plain  copy
  1. /** 
  2.      * 是否同一天 
  3.      *  
  4.      * @param date1 
  5.      * @param date2 
  6.      * @return 
  7.      */  
  8.     public static boolean isSameDate(long date1, long date2) {  
  9.         long days1 = date1 / (1000 * 60 * 60 * 24);  
  10.         long days2 = date2 / (1000 * 60 * 60 * 24);  
  11.         return days1 == days2;  
  12.     }  
6、附上android系统的DateUtils类的代码。

       

[java]  view plain  copy
  1. public class DateUtils  
  2. {  
  3.     private static final Object sLock = new Object();  
  4.     private static Configuration sLastConfig;  
  5.     private static java.text.DateFormat sStatusTimeFormat;  
  6.     private static String sElapsedFormatMMSS;  
  7.     private static String sElapsedFormatHMMSS;  
  8.   
  9.     private static final String FAST_FORMAT_HMMSS = "%1$d:%2$02d:%3$02d";  
  10.     private static final String FAST_FORMAT_MMSS = "%1$02d:%2$02d";  
  11.     private static final char TIME_SEPARATOR = ':';  
  12.   
  13.   
  14.     public static final long SECOND_IN_MILLIS = 1000;  
  15.     public static final long MINUTE_IN_MILLIS = SECOND_IN_MILLIS * 60;  
  16.     public static final long HOUR_IN_MILLIS = MINUTE_IN_MILLIS * 60;  
  17.     public static final long DAY_IN_MILLIS = HOUR_IN_MILLIS * 24;  
  18.     public static final long WEEK_IN_MILLIS = DAY_IN_MILLIS * 7;  
  19.     /** 
  20.      * This constant is actually the length of 364 days, not of a year! 
  21.      */  
  22.     public static final long YEAR_IN_MILLIS = WEEK_IN_MILLIS * 52;  
  23.   
  24.     // The following FORMAT_* symbols are used for specifying the format of  
  25.     // dates and times in the formatDateRange method.  
  26.     public static final int FORMAT_SHOW_TIME = 0x00001;  
  27.     public static final int FORMAT_SHOW_WEEKDAY = 0x00002;  
  28.     public static final int FORMAT_SHOW_YEAR = 0x00004;  
  29.     public static final int FORMAT_NO_YEAR = 0x00008;  
  30.     public static final int FORMAT_SHOW_DATE = 0x00010;  
  31.     public static final int FORMAT_NO_MONTH_DAY = 0x00020;  
  32.     @Deprecated  
  33.     public static final int FORMAT_12HOUR = 0x00040;  
  34.     @Deprecated  
  35.     public static final int FORMAT_24HOUR = 0x00080;  
  36.     @Deprecated  
  37.     public static final int FORMAT_CAP_AMPM = 0x00100;  
  38.     public static final int FORMAT_NO_NOON = 0x00200;  
  39.     @Deprecated  
  40.     public static final int FORMAT_CAP_NOON = 0x00400;  
  41.     public static final int FORMAT_NO_MIDNIGHT = 0x00800;  
  42.     @Deprecated  
  43.     public static final int FORMAT_CAP_MIDNIGHT = 0x01000;  
  44.     /** 
  45.      * @deprecated Use 
  46.      * {@link #formatDateRange(Context, Formatter, long, long, int, String) formatDateRange} 
  47.      * and pass in {@link Time#TIMEZONE_UTC Time.TIMEZONE_UTC} for the timeZone instead. 
  48.      */  
  49.     @Deprecated  
  50.     public static final int FORMAT_UTC = 0x02000;  
  51.     public static final int FORMAT_ABBREV_TIME = 0x04000;  
  52.     public static final int FORMAT_ABBREV_WEEKDAY = 0x08000;  
  53.     public static final int FORMAT_ABBREV_MONTH = 0x10000;  
  54.     public static final int FORMAT_NUMERIC_DATE = 0x20000;  
  55.     public static final int FORMAT_ABBREV_RELATIVE = 0x40000;  
  56.     public static final int FORMAT_ABBREV_ALL = 0x80000;  
  57.     @Deprecated  
  58.     public static final int FORMAT_CAP_NOON_MIDNIGHT = (FORMAT_CAP_NOON | FORMAT_CAP_MIDNIGHT);  
  59.     @Deprecated  
  60.     public static final int FORMAT_NO_NOON_MIDNIGHT = (FORMAT_NO_NOON | FORMAT_NO_MIDNIGHT);  
  61.   
  62.     // Date and time format strings that are constant and don't need to be  
  63.     // translated.  
  64.     /** 
  65.      * This is not actually the preferred 24-hour date format in all locales. 
  66.      * @deprecated use {@link java.text.SimpleDateFormat} instead. 
  67.      */  
  68.     @Deprecated  
  69.     public static final String HOUR_MINUTE_24 = "%H:%M";  
  70.     public static final String MONTH_FORMAT = "%B";  
  71.     /** 
  72.      * This is not actually a useful month name in all locales. 
  73.      * @deprecated use {@link java.text.SimpleDateFormat} instead. 
  74.      */  
  75.     @Deprecated  
  76.     public static final String ABBREV_MONTH_FORMAT = "%b";  
  77.     public static final String NUMERIC_MONTH_FORMAT = "%m";  
  78.     public static final String MONTH_DAY_FORMAT = "%-d";  
  79.     public static final String YEAR_FORMAT = "%Y";  
  80.     public static final String YEAR_FORMAT_TWO_DIGITS = "%g";  
  81.     public static final String WEEKDAY_FORMAT = "%A";  
  82.     public static final String ABBREV_WEEKDAY_FORMAT = "%a";  
  83.   
  84.     // This table is used to lookup the resource string id of a format string  
  85.     // used for formatting a start and end date that fall in the same year.  
  86.     // The index is constructed from a bit-wise OR of the boolean values:  
  87.     // {showTime, showYear, showWeekDay}.  For example, if showYear and  
  88.     // showWeekDay are both true, then the index would be 3.  
  89.     /** @deprecated do not use. */  
  90.     public static final int sameYearTable[] = {  
  91.         com.android.internal.R.string.same_year_md1_md2,  
  92.         com.android.internal.R.string.same_year_wday1_md1_wday2_md2,  
  93.         com.android.internal.R.string.same_year_mdy1_mdy2,  
  94.         com.android.internal.R.string.same_year_wday1_mdy1_wday2_mdy2,  
  95.         com.android.internal.R.string.same_year_md1_time1_md2_time2,  
  96.         com.android.internal.R.string.same_year_wday1_md1_time1_wday2_md2_time2,  
  97.         com.android.internal.R.string.same_year_mdy1_time1_mdy2_time2,  
  98.         com.android.internal.R.string.same_year_wday1_mdy1_time1_wday2_mdy2_time2,  
  99.   
  100.         // Numeric date strings  
  101.         com.android.internal.R.string.numeric_md1_md2,  
  102.         com.android.internal.R.string.numeric_wday1_md1_wday2_md2,  
  103.         com.android.internal.R.string.numeric_mdy1_mdy2,  
  104.         com.android.internal.R.string.numeric_wday1_mdy1_wday2_mdy2,  
  105.         com.android.internal.R.string.numeric_md1_time1_md2_time2,  
  106.         com.android.internal.R.string.numeric_wday1_md1_time1_wday2_md2_time2,  
  107.         com.android.internal.R.string.numeric_mdy1_time1_mdy2_time2,  
  108.         com.android.internal.R.string.numeric_wday1_mdy1_time1_wday2_mdy2_time2,  
  109.     };  
  110.   
  111.     // This table is used to lookup the resource string id of a format string  
  112.     // used for formatting a start and end date that fall in the same month.  
  113.     // The index is constructed from a bit-wise OR of the boolean values:  
  114.     // {showTime, showYear, showWeekDay}.  For example, if showYear and  
  115.     // showWeekDay are both true, then the index would be 3.  
  116.     /** @deprecated do not use. */  
  117.     public static final int sameMonthTable[] = {  
  118.         com.android.internal.R.string.same_month_md1_md2,  
  119.         com.android.internal.R.string.same_month_wday1_md1_wday2_md2,  
  120.         com.android.internal.R.string.same_month_mdy1_mdy2,  
  121.         com.android.internal.R.string.same_month_wday1_mdy1_wday2_mdy2,  
  122.         com.android.internal.R.string.same_month_md1_time1_md2_time2,  
  123.         com.android.internal.R.string.same_month_wday1_md1_time1_wday2_md2_time2,  
  124.         com.android.internal.R.string.same_month_mdy1_time1_mdy2_time2,  
  125.         com.android.internal.R.string.same_month_wday1_mdy1_time1_wday2_mdy2_time2,  
  126.   
  127.         com.android.internal.R.string.numeric_md1_md2,  
  128.         com.android.internal.R.string.numeric_wday1_md1_wday2_md2,  
  129.         com.android.internal.R.string.numeric_mdy1_mdy2,  
  130.         com.android.internal.R.string.numeric_wday1_mdy1_wday2_mdy2,  
  131.         com.android.internal.R.string.numeric_md1_time1_md2_time2,  
  132.         com.android.internal.R.string.numeric_wday1_md1_time1_wday2_md2_time2,  
  133.         com.android.internal.R.string.numeric_mdy1_time1_mdy2_time2,  
  134.         com.android.internal.R.string.numeric_wday1_mdy1_time1_wday2_mdy2_time2,  
  135.     };  
  136.   
  137.     /** 
  138.      * Request the full spelled-out name. For use with the 'abbrev' parameter of 
  139.      * {@link #getDayOfWeekString} and {@link #getMonthString}. 
  140.      * 
  141.      * @more 

     

  142.      *       e.g. "Sunday" or "January" 
  143.      * @deprecated use {@link java.text.SimpleDateFormat} instead. 
  144.      */  
  145.     @Deprecated  
  146.     public static final int LENGTH_LONG = 10;  
  147.   
  148.     /** 
  149.      * Request an abbreviated version of the name. For use with the 'abbrev' 
  150.      * parameter of {@link #getDayOfWeekString} and {@link #getMonthString}. 
  151.      * 
  152.      * @more 

     

  153.      *       e.g. "Sun" or "Jan" 
  154.      * @deprecated use {@link java.text.SimpleDateFormat} instead. 
  155.      */  
  156.     @Deprecated  
  157.     public static final int LENGTH_MEDIUM = 20;  
  158.   
  159.     /** 
  160.      * Request a shorter abbreviated version of the name. 
  161.      * For use with the 'abbrev' parameter of {@link #getDayOfWeekString} and {@link #getMonthString}. 
  162.      * @more 
  163.      * 

    e.g. "Su" or "Jan" 

  164.      * 

    In most languages, the results returned for LENGTH_SHORT will be the same as 

  165.      * the results returned for {@link #LENGTH_MEDIUM}. 
  166.      * @deprecated use {@link java.text.SimpleDateFormat} instead. 
  167.      */  
  168.     @Deprecated  
  169.     public static final int LENGTH_SHORT = 30;  
  170.   
  171.     /** 
  172.      * Request an even shorter abbreviated version of the name. 
  173.      * Do not use this.  Currently this will always return the same result 
  174.      * as {@link #LENGTH_SHORT}. 
  175.      * @deprecated use {@link java.text.SimpleDateFormat} instead. 
  176.      */  
  177.     @Deprecated  
  178.     public static final int LENGTH_SHORTER = 40;  
  179.   
  180.     /** 
  181.      * Request an even shorter abbreviated version of the name. 
  182.      * For use with the 'abbrev' parameter of {@link #getDayOfWeekString} and {@link #getMonthString}. 
  183.      * @more 
  184.      * 

    e.g. "S", "T", "T" or "J" 

  185.      * 

    In some languages, the results returned for LENGTH_SHORTEST will be the same as 

  186.      * the results returned for {@link #LENGTH_SHORT}. 
  187.      * @deprecated use {@link java.text.SimpleDateFormat} instead. 
  188.      */  
  189.     @Deprecated  
  190.     public static final int LENGTH_SHORTEST = 50;  
  191.   
  192.     /** 
  193.      * Return a string for the day of the week. 
  194.      * @param dayOfWeek One of {@link Calendar#SUNDAY Calendar.SUNDAY}, 
  195.      *               {@link Calendar#MONDAY Calendar.MONDAY}, etc. 
  196.      * @param abbrev One of {@link #LENGTH_LONG}, {@link #LENGTH_SHORT}, 
  197.      *               {@link #LENGTH_MEDIUM}, or {@link #LENGTH_SHORTEST}. 
  198.      *               Note that in most languages, {@link #LENGTH_SHORT} 
  199.      *               will return the same as {@link #LENGTH_MEDIUM}. 
  200.      *               Undefined lengths will return {@link #LENGTH_MEDIUM} 
  201.      *               but may return something different in the future. 
  202.      * @throws IndexOutOfBoundsException if the dayOfWeek is out of bounds. 
  203.      * @deprecated use {@link java.text.SimpleDateFormat} instead. 
  204.      */  
  205.     @Deprecated  
  206.     public static String getDayOfWeekString(int dayOfWeek, int abbrev) {  
  207.         LocaleData d = LocaleData.get(Locale.getDefault());  
  208.         String[] names;  
  209.         switch (abbrev) {  
  210.             case LENGTH_LONG:       names = d.longWeekdayNames;  break;  
  211.             case LENGTH_MEDIUM:     names = d.shortWeekdayNames; break;  
  212.             case LENGTH_SHORT:      names = d.shortWeekdayNames; break// TODO  
  213.             case LENGTH_SHORTER:    names = d.shortWeekdayNames; break// TODO  
  214.             case LENGTH_SHORTEST:   names = d.tinyWeekdayNames;  break;  
  215.             default:                names = d.shortWeekdayNames; break;  
  216.         }  
  217.         return names[dayOfWeek];  
  218.     }  
  219.   
  220.     /** 
  221.      * Return a localized string for AM or PM. 
  222.      * @param ampm Either {@link Calendar#AM Calendar.AM} or {@link Calendar#PM Calendar.PM}. 
  223.      * @throws IndexOutOfBoundsException if the ampm is out of bounds. 
  224.      * @return Localized version of "AM" or "PM". 
  225.      * @deprecated use {@link java.text.SimpleDateFormat} instead. 
  226.      */  
  227.     @Deprecated  
  228.     public static String getAMPMString(int ampm) {  
  229.         return LocaleData.get(Locale.getDefault()).amPm[ampm - Calendar.AM];  
  230.     }  
  231.   
  232.     /** 
  233.      * Return a localized string for the month of the year. 
  234.      * @param month One of {@link Calendar#JANUARY Calendar.JANUARY}, 
  235.      *               {@link Calendar#FEBRUARY Calendar.FEBRUARY}, etc. 
  236.      * @param abbrev One of {@link #LENGTH_LONG}, {@link #LENGTH_MEDIUM}, 
  237.      *               or {@link #LENGTH_SHORTEST}. 
  238.      *               Undefined lengths will return {@link #LENGTH_MEDIUM} 
  239.      *               but may return something different in the future. 
  240.      * @return Localized month of the year. 
  241.      * @deprecated use {@link java.text.SimpleDateFormat} instead. 
  242.      */  
  243.     @Deprecated  
  244.     public static String getMonthString(int month, int abbrev) {  
  245.         // Note that here we use d.shortMonthNames for MEDIUM, SHORT and SHORTER.  
  246.         // This is a shortcut to not spam the translators with too many variations  
  247.         // of the same string.  If we find that in a language the distinction  
  248.         // is necessary, we can can add more without changing this API.  
  249.         LocaleData d = LocaleData.get(Locale.getDefault());  
  250.         String[] names;  
  251.         switch (abbrev) {  
  252.             case LENGTH_LONG:       names = d.longMonthNames;  break;  
  253.             case LENGTH_MEDIUM:     names = d.shortMonthNames; break;  
  254.             case LENGTH_SHORT:      names = d.shortMonthNames; break;  
  255.             case LENGTH_SHORTER:    names = d.shortMonthNames; break;  
  256.             case LENGTH_SHORTEST:   names = d.tinyMonthNames;  break;  
  257.             default:                names = d.shortMonthNames; break;  
  258.         }  
  259.         return names[month];  
  260.     }  
  261.   
  262.     /** 
  263.      * Return a localized string for the month of the year, for 
  264.      * contexts where the month is not formatted together with 
  265.      * a day of the month. 
  266.      * 
  267.      * @param month One of {@link Calendar#JANUARY Calendar.JANUARY}, 
  268.      *               {@link Calendar#FEBRUARY Calendar.FEBRUARY}, etc. 
  269.      * @param abbrev One of {@link #LENGTH_LONG}, {@link #LENGTH_MEDIUM}, 
  270.      *               or {@link #LENGTH_SHORTEST}. 
  271.      *               Undefined lengths will return {@link #LENGTH_MEDIUM} 
  272.      *               but may return something different in the future. 
  273.      * @return Localized month of the year. 
  274.      * @hide Pending API council approval 
  275.      * @deprecated use {@link java.text.SimpleDateFormat} instead. 
  276.      */  
  277.     @Deprecated  
  278.     public static String getStandaloneMonthString(int month, int abbrev) {  
  279.         // Note that here we use d.shortMonthNames for MEDIUM, SHORT and SHORTER.  
  280.         // This is a shortcut to not spam the translators with too many variations  
  281.         // of the same string.  If we find that in a language the distinction  
  282.         // is necessary, we can can add more without changing this API.  
  283.         LocaleData d = LocaleData.get(Locale.getDefault());  
  284.         String[] names;  
  285.         switch (abbrev) {  
  286.             case LENGTH_LONG:       names = d.longStandAloneMonthNames;  
  287.                                                             break;  
  288.             case LENGTH_MEDIUM:     names = d.shortMonthNames; break;  
  289.             case LENGTH_SHORT:      names = d.shortMonthNames; break;  
  290.             case LENGTH_SHORTER:    names = d.shortMonthNames; break;  
  291.             case LENGTH_SHORTEST:   names = d.tinyMonthNames;  break;  
  292.             default:                names = d.shortMonthNames; break;  
  293.         }  
  294.         return names[month];  
  295.     }  
  296.   
  297.     /** 
  298.      * Returns a string describing the elapsed time since startTime. 
  299.      * @param startTime some time in the past. 
  300.      * @return a String object containing the elapsed time. 
  301.      * @see #getRelativeTimeSpanString(long, long, long) 
  302.      */  
  303.     public static CharSequence getRelativeTimeSpanString(long startTime) {  
  304.         return getRelativeTimeSpanString(startTime, System.currentTimeMillis(), MINUTE_IN_MILLIS);  
  305.     }  
  306.   
  307.     /** 
  308.      * Returns a string describing 'time' as a time relative to 'now'. 
  309.      * 

     

  310.      * Time spans in the past are formatted like "42 minutes ago". 
  311.      * Time spans in the future are formatted like "in 42 minutes". 
  312.      * 
  313.      * @param time the time to describe, in milliseconds 
  314.      * @param now the current time in milliseconds 
  315.      * @param minResolution the minimum timespan to report. For example, a time 3 seconds in the 
  316.      *     past will be reported as "0 minutes ago" if this is set to MINUTE_IN_MILLIS. Pass one of 
  317.      *     0, MINUTE_IN_MILLIS, HOUR_IN_MILLIS, DAY_IN_MILLIS, WEEK_IN_MILLIS 
  318.      */  
  319.     public static CharSequence getRelativeTimeSpanString(long time, long now, long minResolution) {  
  320.         int flags = FORMAT_SHOW_DATE | FORMAT_SHOW_YEAR | FORMAT_ABBREV_MONTH;  
  321.         return getRelativeTimeSpanString(time, now, minResolution, flags);  
  322.     }  
  323.   
  324.     /** 
  325.      * Returns a string describing 'time' as a time relative to 'now'. 
  326.      * 

     

  327.      * Time spans in the past are formatted like "42 minutes ago". Time spans in 
  328.      * the future are formatted like "in 42 minutes". 
  329.      * 

     

  330.      * Can use {@link #FORMAT_ABBREV_RELATIVE} flag to use abbreviated relative 
  331.      * times, like "42 mins ago". 
  332.      * 
  333.      * @param time the time to describe, in milliseconds 
  334.      * @param now the current time in milliseconds 
  335.      * @param minResolution the minimum timespan to report. For example, a time 
  336.      *            3 seconds in the past will be reported as "0 minutes ago" if 
  337.      *            this is set to MINUTE_IN_MILLIS. Pass one of 0, 
  338.      *            MINUTE_IN_MILLIS, HOUR_IN_MILLIS, DAY_IN_MILLIS, 
  339.      *            WEEK_IN_MILLIS 
  340.      * @param flags a bit mask of formatting options, such as 
  341.      *            {@link #FORMAT_NUMERIC_DATE} or 
  342.      *            {@link #FORMAT_ABBREV_RELATIVE} 
  343.      */  
  344.     public static CharSequence getRelativeTimeSpanString(long time, long now, long minResolution,  
  345.             int flags) {  
  346.         Resources r = Resources.getSystem();  
  347.         boolean abbrevRelative = (flags & (FORMAT_ABBREV_RELATIVE | FORMAT_ABBREV_ALL)) != 0;  
  348.   
  349.         boolean past = (now >= time);  
  350.         long duration = Math.abs(now - time);  
  351.   
  352.         int resId;  
  353.         long count;  
  354.         if (duration < MINUTE_IN_MILLIS && minResolution < MINUTE_IN_MILLIS) {  
  355.             count = duration / SECOND_IN_MILLIS;  
  356.             if (past) {  
  357.                 if (abbrevRelative) {  
  358.                     resId = com.android.internal.R.plurals.abbrev_num_seconds_ago;  
  359.                 } else {  
  360.                     resId = com.android.internal.R.plurals.num_seconds_ago;  
  361.                 }  
  362.             } else {  
  363.                 if (abbrevRelative) {  
  364.                     resId = com.android.internal.R.plurals.abbrev_in_num_seconds;  
  365.                 } else {  
  366.                     resId = com.android.internal.R.plurals.in_num_seconds;  
  367.                 }  
  368.             }  
  369.         } else if (duration < HOUR_IN_MILLIS && minResolution < HOUR_IN_MILLIS) {  
  370.             count = duration / MINUTE_IN_MILLIS;  
  371.             if (past) {  
  372.                 if (abbrevRelative) {  
  373.                     resId = com.android.internal.R.plurals.abbrev_num_minutes_ago;  
  374.                 } else {  
  375.                     resId = com.android.internal.R.plurals.num_minutes_ago;  
  376.                 }  
  377.             } else {  
  378.                 if (abbrevRelative) {  
  379.                     resId = com.android.internal.R.plurals.abbrev_in_num_minutes;  
  380.                 } else {  
  381.                     resId = com.android.internal.R.plurals.in_num_minutes;  
  382.                 }  
  383.             }  
  384.         } else if (duration < DAY_IN_MILLIS && minResolution < DAY_IN_MILLIS) {  
  385.             count = duration / HOUR_IN_MILLIS;  
  386.             if (past) {  
  387.                 if (abbrevRelative) {  
  388.                     resId = com.android.internal.R.plurals.abbrev_num_hours_ago;  
  389.                 } else {  
  390.                     resId = com.android.internal.R.plurals.num_hours_ago;  
  391.                 }  
  392.             } else {  
  393.                 if (abbrevRelative) {  
  394.                     resId = com.android.internal.R.plurals.abbrev_in_num_hours;  
  395.                 } else {  
  396.                     resId = com.android.internal.R.plurals.in_num_hours;  
  397.                 }  
  398.             }  
  399.         } else if (duration < WEEK_IN_MILLIS && minResolution < WEEK_IN_MILLIS) {  
  400.             count = getNumberOfDaysPassed(time, now);  
  401.             if (past) {  
  402.                 if (abbrevRelative) {  
  403.                     resId = com.android.internal.R.plurals.abbrev_num_days_ago;  
  404.                 } else {  
  405.                     resId = com.android.internal.R.plurals.num_days_ago;  
  406.                 }  
  407.             } else {  
  408.                 if (abbrevRelative) {  
  409.                     resId = com.android.internal.R.plurals.abbrev_in_num_days;  
  410.                 } else {  
  411.                     resId = com.android.internal.R.plurals.in_num_days;  
  412.                 }  
  413.             }  
  414.         } else {  
  415.             // We know that we won't be showing the time, so it is safe to pass  
  416.             // in a null context.  
  417.             return formatDateRange(null, time, time, flags);  
  418.         }  
  419.   
  420.         String format = r.getQuantityString(resId, (int) count);  
  421.         return String.format(format, count);  
  422.     }  
  423.   
  424.     /** 
  425.      * Returns the number of days passed between two dates. 
  426.      * 
  427.      * @param date1 first date 
  428.      * @param date2 second date 
  429.      * @return number of days passed between to dates. 
  430.      */  
  431.     private synchronized static long getNumberOfDaysPassed(long date1, long date2) {  
  432.         if (sThenTime == null) {  
  433.             sThenTime = new Time();  
  434.         }  
  435.         sThenTime.set(date1);  
  436.         int day1 = Time.getJulianDay(date1, sThenTime.gmtoff);  
  437.         sThenTime.set(date2);  
  438.         int day2 = Time.getJulianDay(date2, sThenTime.gmtoff);  
  439.         return Math.abs(day2 - day1);  
  440.     }  
  441.   
  442.     /** 
  443.      * Return string describing the elapsed time since startTime formatted like 
  444.      * "[relative time/date], [time]". 
  445.      * 

     

  446.      * Example output strings for the US date format. 
  447.      * 
       
    •      * 
    • 3 mins ago, 10:15 AM
    •  
    •      * 
    • yesterday, 12:20 PM
    •  
    •      * 
    • Dec 12, 4:12 AM
    •  
    •      * 
    • 11/14/2007, 8:20 AM
    •  
    •      * 
     
  448.      * 
  449.      * @param time some time in the past. 
  450.      * @param minResolution the minimum elapsed time (in milliseconds) to report 
  451.      *            when showing relative times. For example, a time 3 seconds in 
  452.      *            the past will be reported as "0 minutes ago" if this is set to 
  453.      *            {@link #MINUTE_IN_MILLIS}. 
  454.      * @param transitionResolution the elapsed time (in milliseconds) at which 
  455.      *            to stop reporting relative measurements. Elapsed times greater 
  456.      *            than this resolution will default to normal date formatting. 
  457.      *            For example, will transition from "6 days ago" to "Dec 12" 
  458.      *            when using {@link #WEEK_IN_MILLIS}. 
  459.      */  
  460.     public static CharSequence getRelativeDateTimeString(Context c, long time, long minResolution,  
  461.             long transitionResolution, int flags) {  
  462.         Resources r = Resources.getSystem();  
  463.   
  464.         long now = System.currentTimeMillis();  
  465.         long duration = Math.abs(now - time);  
  466.   
  467.         // getRelativeTimeSpanString() doesn't correctly format relative dates  
  468.         // above a week or exact dates below a day, so clamp  
  469.         // transitionResolution as needed.  
  470.         if (transitionResolution > WEEK_IN_MILLIS) {  
  471.             transitionResolution = WEEK_IN_MILLIS;  
  472.         } else if (transitionResolution < DAY_IN_MILLIS) {  
  473.             transitionResolution = DAY_IN_MILLIS;  
  474.         }  
  475.   
  476.         CharSequence timeClause = formatDateRange(c, time, time, FORMAT_SHOW_TIME);  
  477.   
  478.         String result;  
  479.         if (duration < transitionResolution) {  
  480.             CharSequence relativeClause = getRelativeTimeSpanString(time, now, minResolution, flags);  
  481.             result = r.getString(com.android.internal.R.string.relative_time, relativeClause, timeClause);  
  482.         } else {  
  483.             CharSequence dateClause = getRelativeTimeSpanString(c, time, false);  
  484.             result = r.getString(com.android.internal.R.string.date_time, dateClause, timeClause);  
  485.         }  
  486.   
  487.         return result;  
  488.     }  
  489.   
  490.     /** 
  491.      * Returns a string describing a day relative to the current day. For example if the day is 
  492.      * today this function returns "Today", if the day was a week ago it returns "7 days ago", and 
  493.      * if the day is in 2 weeks it returns "in 14 days". 
  494.      * 
  495.      * @param r the resources to get the strings from 
  496.      * @param day the relative day to describe in UTC milliseconds 
  497.      * @param today the current time in UTC milliseconds 
  498.      * @return a formatting string 
  499.      */  
  500.     private static final String getRelativeDayString(Resources r, long day, long today) {  
  501.         Time startTime = new Time();  
  502.         startTime.set(day);  
  503.         Time currentTime = new Time();  
  504.         currentTime.set(today);  
  505.   
  506.         int startDay = Time.getJulianDay(day, startTime.gmtoff);  
  507.         int currentDay = Time.getJulianDay(today, currentTime.gmtoff);  
  508.   
  509.         int days = Math.abs(currentDay - startDay);  
  510.         boolean past = (today > day);  
  511.   
  512.         // TODO: some locales name other days too, such as de_DE's "Vorgestern" (today - 2).  
  513.         Locale locale = r.getConfiguration().locale;  
  514.         if (locale == null) {  
  515.             locale = Locale.getDefault();  
  516.         }  
  517.         if (days == 1) {  
  518.             if (past) {  
  519.                 return LocaleData.get(locale).yesterday;  
  520.             } else {  
  521.                 return LocaleData.get(locale).tomorrow;  
  522.             }  
  523.         } else if (days == 0) {  
  524.             return LocaleData.get(locale).today;  
  525.         }  
  526.   
  527.         int resId;  
  528.         if (past) {  
  529.             resId = com.android.internal.R.plurals.num_days_ago;  
  530.         } else {  
  531.             resId = com.android.internal.R.plurals.in_num_days;  
  532.         }  
  533.   
  534.         String format = r.getQuantityString(resId, days);  
  535.         return String.format(format, days);  
  536.     }  
  537.   
  538.     private static void initFormatStrings() {  
  539.         synchronized (sLock) {  
  540.             initFormatStringsLocked();  
  541.         }  
  542.     }  
  543.   
  544.     private static void initFormatStringsLocked() {  
  545.         Resources r = Resources.getSystem();  
  546.         Configuration cfg = r.getConfiguration();  
  547.         if (sLastConfig == null || !sLastConfig.equals(cfg)) {  
  548.             sLastConfig = cfg;  
  549.             sStatusTimeFormat = java.text.DateFormat.getTimeInstance(java.text.DateFormat.SHORT);  
  550.             sElapsedFormatMMSS = r.getString(com.android.internal.R.string.elapsed_time_short_format_mm_ss);  
  551.             sElapsedFormatHMMSS = r.getString(com.android.internal.R.string.elapsed_time_short_format_h_mm_ss);  
  552.         }  
  553.     }  
  554.   
  555.     /** 
  556.      * Format a time so it appears like it would in the status bar clock. 
  557.      * @deprecated use {@link #DateFormat.getTimeFormat(Context)} instead. 
  558.      * @hide 
  559.      */  
  560.     public static final CharSequence timeString(long millis) {  
  561.         synchronized (sLock) {  
  562.             initFormatStringsLocked();  
  563.             return sStatusTimeFormat.format(millis);  
  564.         }  
  565.     }  
  566.   
  567.     /** 
  568.      * Formats an elapsed time in the form "MM:SS" or "H:MM:SS" 
  569.      * for display on the call-in-progress screen. 
  570.      * @param elapsedSeconds the elapsed time in seconds. 
  571.      */  
  572.     public static String formatElapsedTime(long elapsedSeconds) {  
  573.         return formatElapsedTime(null, elapsedSeconds);  
  574.     }  
  575.   
  576.     /** 
  577.      * Formats an elapsed time in the form "MM:SS" or "H:MM:SS" 
  578.      * for display on the call-in-progress screen. 
  579.      * 
  580.      * @param recycle {@link StringBuilder} to recycle, if possible 
  581.      * @param elapsedSeconds the elapsed time in seconds. 
  582.      */  
  583.     public static String formatElapsedTime(StringBuilder recycle, long elapsedSeconds) {  
  584.         initFormatStrings();  
  585.   
  586.         long hours = 0;  
  587.         long minutes = 0;  
  588.         long seconds = 0;  
  589.   
  590.         if (elapsedSeconds >= 3600) {  
  591.             hours = elapsedSeconds / 3600;  
  592.             elapsedSeconds -= hours * 3600;  
  593.         }  
  594.         if (elapsedSeconds >= 60) {  
  595.             minutes = elapsedSeconds / 60;  
  596.             elapsedSeconds -= minutes * 60;  
  597.         }  
  598.         seconds = elapsedSeconds;  
  599.   
  600.         String result;  
  601.         if (hours > 0) {  
  602.             return formatElapsedTime(recycle, sElapsedFormatHMMSS, hours, minutes, seconds);  
  603.         } else {  
  604.             return formatElapsedTime(recycle, sElapsedFormatMMSS, minutes, seconds);  
  605.         }  
  606.     }  
  607.   
  608.     private static void append(StringBuilder sb, long value, boolean pad, char zeroDigit) {  
  609.         if (value < 10) {  
  610.             if (pad) {  
  611.                 sb.append(zeroDigit);  
  612.             }  
  613.         } else {  
  614.             sb.append((char) (zeroDigit + (value / 10)));  
  615.         }  
  616.         sb.append((char) (zeroDigit + (value % 10)));  
  617.     }  
  618.   
  619.     /** 
  620.      * Fast formatting of h:mm:ss. 
  621.      */  
  622.     private static String formatElapsedTime(StringBuilder recycle, String format, long hours,  
  623.             long minutes, long seconds) {  
  624.         if (FAST_FORMAT_HMMSS.equals(format)) {  
  625.             char zeroDigit = LocaleData.get(Locale.getDefault()).zeroDigit;  
  626.   
  627.             StringBuilder sb = recycle;  
  628.             if (sb == null) {  
  629.                 sb = new StringBuilder(8);  
  630.             } else {  
  631.                 sb.setLength(0);  
  632.             }  
  633.             append(sb, hours, false, zeroDigit);  
  634.             sb.append(TIME_SEPARATOR);  
  635.             append(sb, minutes, true, zeroDigit);  
  636.             sb.append(TIME_SEPARATOR);  
  637.             append(sb, seconds, true, zeroDigit);  
  638.             return sb.toString();  
  639.         } else {  
  640.             return String.format(format, hours, minutes, seconds);  
  641.         }  
  642.     }  
  643.   
  644.     /** 
  645.      * Fast formatting of mm:ss. 
  646.      */  
  647.     private static String formatElapsedTime(StringBuilder recycle, String format, long minutes,  
  648.             long seconds) {  
  649.         if (FAST_FORMAT_MMSS.equals(format)) {  
  650.             char zeroDigit = LocaleData.get(Locale.getDefault()).zeroDigit;  
  651.   
  652.             StringBuilder sb = recycle;  
  653.             if (sb == null) {  
  654.                 sb = new StringBuilder(8);  
  655.             } else {  
  656.                 sb.setLength(0);  
  657.             }  
  658.             append(sb, minutes, false, zeroDigit);  
  659.             sb.append(TIME_SEPARATOR);  
  660.             append(sb, seconds, true, zeroDigit);  
  661.             return sb.toString();  
  662.         } else {  
  663.             return String.format(format, minutes, seconds);  
  664.         }  
  665.     }  
  666.   
  667.     /** 
  668.      * Format a date / time such that if the then is on the same day as now, it shows 
  669.      * just the time and if it's a different day, it shows just the date. 
  670.      * 
  671.      * 

    The parameters dateFormat and timeFormat should each be one of 

  672.      * {@link java.text.DateFormat#DEFAULT}, 
  673.      * {@link java.text.DateFormat#FULL}, 
  674.      * {@link java.text.DateFormat#LONG}, 
  675.      * {@link java.text.DateFormat#MEDIUM} 
  676.      * or 
  677.      * {@link java.text.DateFormat#SHORT} 
  678.      * 
  679.      * @param then the date to format 
  680.      * @param now the base time 
  681.      * @param dateStyle how to format the date portion. 
  682.      * @param timeStyle how to format the time portion. 
  683.      */  
  684.     public static final CharSequence formatSameDayTime(long then, long now,  
  685.             int dateStyle, int timeStyle) {  
  686.         Calendar thenCal = new GregorianCalendar();  
  687.         thenCal.setTimeInMillis(then);  
  688.         Date thenDate = thenCal.getTime();  
  689.         Calendar nowCal = new GregorianCalendar();  
  690.         nowCal.setTimeInMillis(now);  
  691.   
  692.         java.text.DateFormat f;  
  693.   
  694.         if (thenCal.get(Calendar.YEAR) == nowCal.get(Calendar.YEAR)  
  695.                 && thenCal.get(Calendar.MONTH) == nowCal.get(Calendar.MONTH)  
  696.                 && thenCal.get(Calendar.DAY_OF_MONTH) == nowCal.get(Calendar.DAY_OF_MONTH)) {  
  697.             f = java.text.DateFormat.getTimeInstance(timeStyle);  
  698.         } else {  
  699.             f = java.text.DateFormat.getDateInstance(dateStyle);  
  700.         }  
  701.         return f.format(thenDate);  
  702.     }  
  703.   
  704.     /** 
  705.      * @hide 
  706.      * @deprecated use {@link android.text.format.Time} 
  707.      */  
  708.     public static Calendar newCalendar(boolean zulu)  
  709.     {  
  710.         if (zulu)  
  711.             return Calendar.getInstance(TimeZone.getTimeZone("GMT"));  
  712.   
  713.         return Calendar.getInstance();  
  714.     }  
  715.   
  716.     /** 
  717.      * @return true if the supplied when is today else false 
  718.      */  
  719.     public static boolean isToday(long when) {  
  720.         Time time = new Time();  
  721.         time.set(when);  
  722.   
  723.         int thenYear = time.year;  
  724.         int thenMonth = time.month;  
  725.         int thenMonthDay = time.monthDay;  
  726.   
  727.         time.set(System.currentTimeMillis());  
  728.         return (thenYear == time.year)  
  729.                 && (thenMonth == time.month)  
  730.                 && (thenMonthDay == time.monthDay);  
  731.     }  
  732.   
  733.     /** 
  734.      * @hide 
  735.      * @deprecated use {@link android.text.format.Time} 
  736.      * Return true if this date string is local time 
  737.      */  
  738.     public static boolean isUTC(String s)  
  739.     {  
  740.         if (s.length() == 16 && s.charAt(15) == 'Z') {  
  741.             return true;  
  742.         }  
  743.         if (s.length() == 9 && s.charAt(8) == 'Z') {  
  744.             // XXX not sure if this case possible/valid  
  745.             return true;  
  746.         }  
  747.         return false;  
  748.     }  
  749.   
  750.     /** 
  751.      * Return a string containing the date and time in RFC2445 format. 
  752.      * Ensures that the time is written in UTC.  The Calendar class doesn't 
  753.      * really help out with this, so this is slower than it ought to be. 
  754.      * 
  755.      * @param cal the date and time to write 
  756.      * @hide 
  757.      * @deprecated use {@link android.text.format.Time} 
  758.      */  
  759.     public static String writeDateTime(Calendar cal)  
  760.     {  
  761.         TimeZone tz = TimeZone.getTimeZone("GMT");  
  762.         GregorianCalendar c = new GregorianCalendar(tz);  
  763.         c.setTimeInMillis(cal.getTimeInMillis());  
  764.         return writeDateTime(c, true);  
  765.     }  
  766.   
  767.     /** 
  768.      * Return a string containing the date and time in RFC2445 format. 
  769.      * 
  770.      * @param cal the date and time to write 
  771.      * @param zulu If the calendar is in UTC, pass true, and a Z will 
  772.      * be written at the end as per RFC2445.  Otherwise, the time is 
  773.      * considered in localtime. 
  774.      * @hide 
  775.      * @deprecated use {@link android.text.format.Time} 
  776.      */  
  777.     public static String writeDateTime(Calendar cal, boolean zulu)  
  778.     {  
  779.         StringBuilder sb = new StringBuilder();  
  780.         sb.ensureCapacity(16);  
  781.         if (zulu) {  
  782.             sb.setLength(16);  
  783.             sb.setCharAt(15'Z');  
  784.         } else {  
  785.             sb.setLength(15);  
  786.         }  
  787.         return writeDateTime(cal, sb);  
  788.     }  
  789.   
  790.     /** 
  791.      * Return a string containing the date and time in RFC2445 format. 
  792.      * 
  793.      * @param cal the date and time to write 
  794.      * @param sb a StringBuilder to use.  It is assumed that setLength 
  795.      *           has already been called on sb to the appropriate length 
  796.      *           which is sb.setLength(zulu ? 16 : 15) 
  797.      * @hide 
  798.      * @deprecated use {@link android.text.format.Time} 
  799.      */  
  800.     public static String writeDateTime(Calendar cal, StringBuilder sb)  
  801.     {  
  802.         int n;  
  803.   
  804.         n = cal.get(Calendar.YEAR);  
  805.         sb.setCharAt(3, (char)('0'+n%10));  
  806.         n /= 10;  
  807.         sb.setCharAt(2, (char)('0'+n%10));  
  808.         n /= 10;  
  809.         sb.setCharAt(1, (char)('0'+n%10));  
  810.         n /= 10;  
  811.         sb.setCharAt(0, (char)('0'+n%10));  
  812.   
  813.         n = cal.get(Calendar.MONTH) + 1;  
  814.         sb.setCharAt(5, (char)('0'+n%10));  
  815.         n /= 10;  
  816.         sb.setCharAt(4, (char)('0'+n%10));  
  817.   
  818.         n = cal.get(Calendar.DAY_OF_MONTH);  
  819.         sb.setCharAt(7, (char)('0'+n%10));  
  820.         n /= 10;  
  821.         sb.setCharAt(6, (char)('0'+n%10));  
  822.   
  823.         sb.setCharAt(8'T');  
  824.   
  825.         n = cal.get(Calendar.HOUR_OF_DAY);  
  826.         sb.setCharAt(10, (char)('0'+n%10));  
  827.         n /= 10;  
  828.         sb.setCharAt(9, (char)('0'+n%10));  
  829.   
  830.         n = cal.get(Calendar.MINUTE);  
  831.         sb.setCharAt(12, (char)('0'+n%10));  
  832.         n /= 10;  
  833.         sb.setCharAt(11, (char)('0'+n%10));  
  834.   
  835.         n = cal.get(Calendar.SECOND);  
  836.         sb.setCharAt(14, (char)('0'+n%10));  
  837.         n /= 10;  
  838.         sb.setCharAt(13, (char)('0'+n%10));  
  839.   
  840.         return sb.toString();  
  841.     }  
  842.   
  843.     /** 
  844.      * @hide 
  845.      * @deprecated use {@link android.text.format.Time} 
  846.      */  
  847.     public static void assign(Calendar lval, Calendar rval)  
  848.     {  
  849.         // there should be a faster way.  
  850.         lval.clear();  
  851.         lval.setTimeInMillis(rval.getTimeInMillis());  
  852.     }  
  853.   
  854.     /** 
  855.      * Formats a date or a time range according to the local conventions. 
  856.      * 

     

  857.      * Note that this is a convenience method. Using it involves creating an 
  858.      * internal {@link java.util.Formatter} instance on-the-fly, which is 
  859.      * somewhat costly in terms of memory and time. This is probably acceptable 
  860.      * if you use the method only rarely, but if you rely on it for formatting a 
  861.      * large number of dates, consider creating and reusing your own 
  862.      * {@link java.util.Formatter} instance and use the version of 
  863.      * {@link #formatDateRange(Context, long, long, int) formatDateRange} 
  864.      * that takes a {@link java.util.Formatter}. 
  865.      * 
  866.      * @param context the context is required only if the time is shown 
  867.      * @param startMillis the start time in UTC milliseconds 
  868.      * @param endMillis the end time in UTC milliseconds 
  869.      * @param flags a bit mask of options See 
  870.      * {@link #formatDateRange(Context, Formatter, long, long, int, String) formatDateRange} 
  871.      * @return a string containing the formatted date/time range. 
  872.      */  
  873.     public static String formatDateRange(Context context, long startMillis,  
  874.             long endMillis, int flags) {  
  875.         Formatter f = new Formatter(new StringBuilder(50), Locale.getDefault());  
  876.         return formatDateRange(context, f, startMillis, endMillis, flags).toString();  
  877.     }  
  878.   
  879.     /** 
  880.      * Formats a date or a time range according to the local conventions. 
  881.      * 

     

  882.      * Note that this is a convenience method for formatting the date or 
  883.      * time range in the local time zone. If you want to specify the time 
  884.      * zone please use 
  885.      * {@link #formatDateRange(Context, Formatter, long, long, int, String) formatDateRange}. 
  886.      * 
  887.      * @param context the context is required only if the time is shown 
  888.      * @param formatter the Formatter used for formatting the date range. 
  889.      * Note: be sure to call setLength(0) on StringBuilder passed to 
  890.      * the Formatter constructor unless you want the results to accumulate. 
  891.      * @param startMillis the start time in UTC milliseconds 
  892.      * @param endMillis the end time in UTC milliseconds 
  893.      * @param flags a bit mask of options See 
  894.      * {@link #formatDateRange(Context, Formatter, long, long, int, String) formatDateRange} 
  895.      * @return a string containing the formatted date/time range. 
  896.      */  
  897.     public static Formatter formatDateRange(Context context, Formatter formatter, long startMillis,  
  898.             long endMillis, int flags) {  
  899.         return formatDateRange(context, formatter, startMillis, endMillis, flags, null);  
  900.     }  
  901.   
  902.     /** 
  903.      * Formats a date or a time range according to the local conventions. 
  904.      * 
  905.      * 

     

  906.      * Example output strings (date formats in these examples are shown using 
  907.      * the US date format convention but that may change depending on the 
  908.      * local settings): 
  909.      * 
       
    •      *   
    • 10:15am
    •  
    •      *   
    • 3:00pm - 4:00pm
    •  
    •      *   
    • 3pm - 4pm
    •  
    •      *   
    • 3PM - 4PM
    •  
    •      *   
    • 08:00 - 17:00
    •  
    •      *   
    • Oct 9
    •  
    •      *   
    • Tue, Oct 9
    •  
    •      *   
    • October 9, 2007
    •  
    •      *   
    • Oct 9 - 10
    •  
    •      *   
    • Oct 9 - 10, 2007
    •  
    •      *   
    • Oct 28 - Nov 3, 2007
    •  
    •      *   
    • Dec 31, 2007 - Jan 1, 2008
    •  
    •      *   
    • Oct 9, 8:00am - Oct 10, 5:00pm
    •  
    •      *   
    • 12/31/2007 - 01/01/2008
    •  
    •      * 
     
  910.      * 
  911.      * 

     

  912.      * The flags argument is a bitmask of options from the following list: 
  913.      * 
  914.      * 
       
    •      *   
    • FORMAT_SHOW_TIME
    •  
    •      *   
    • FORMAT_SHOW_WEEKDAY
    •  
    •      *   
    • FORMAT_SHOW_YEAR
    •  
    •      *   
    • FORMAT_NO_YEAR
    •  
    •      *   
    • FORMAT_SHOW_DATE
    •  
    •      *   
    • FORMAT_NO_MONTH_DAY
    •  
    •      *   
    • FORMAT_12HOUR
    •  
    •      *   
    • FORMAT_24HOUR
    •  
    •      *   
    • FORMAT_CAP_AMPM
    •  
    •      *   
    • FORMAT_NO_NOON
    •  
    •      *   
    • FORMAT_CAP_NOON
    •  
    •      *   
    • FORMAT_NO_MIDNIGHT
    •  
    •      *   
    • FORMAT_CAP_MIDNIGHT
    •  
    •      *   
    • FORMAT_UTC
    •  
    •      *   
    • FORMAT_ABBREV_TIME
    •  
    •      *   
    • FORMAT_ABBREV_WEEKDAY
    •  
    •      *   
    • FORMAT_ABBREV_MONTH
    •  
    •      *   
    • FORMAT_ABBREV_ALL
    •  
    •      *   
    • FORMAT_NUMERIC_DATE
    •  
    •      * 
     
  915.      * 
  916.      * 

     

  917.      * If FORMAT_SHOW_TIME is set, the time is shown as part of the date range. 
  918.      * If the start and end time are the same, then just the start time is 
  919.      * shown. 
  920.      * 
  921.      * 

     

  922.      * If FORMAT_SHOW_WEEKDAY is set, then the weekday is shown. 
  923.      * 
  924.      * 

     

  925.      * If FORMAT_SHOW_YEAR is set, then the year is always shown. 
  926.      * If FORMAT_NO_YEAR is set, then the year is not shown. 
  927.      * If neither FORMAT_SHOW_YEAR nor FORMAT_NO_YEAR are set, then the year 
  928.      * is shown only if it is different from the current year, or if the start 
  929.      * and end dates fall on different years.  If both are set, 
  930.      * FORMAT_SHOW_YEAR takes precedence. 
  931.      * 
  932.      * 

     

  933.      * Normally the date is shown unless the start and end day are the same. 
  934.      * If FORMAT_SHOW_DATE is set, then the date is always shown, even for 
  935.      * same day ranges. 
  936.      * 
  937.      * 

     

  938.      * If FORMAT_NO_MONTH_DAY is set, then if the date is shown, just the 
  939.      * month name will be shown, not the day of the month.  For example, 
  940.      * "January, 2008" instead of "January 6 - 12, 2008". 
  941.      * 
  942.      * 

     

  943.      * If FORMAT_CAP_AMPM is set and 12-hour time is used, then the "AM" 
  944.      * and "PM" are capitalized.  You should not use this flag 
  945.      * because in some locales these terms cannot be capitalized, and in 
  946.      * many others it doesn't make sense to do so even though it is possible. 
  947.      * 
  948.      * 

     

  949.      * If FORMAT_NO_NOON is set and 12-hour time is used, then "12pm" is 
  950.      * shown instead of "noon". 
  951.      * 
  952.      * 

     

  953.      * If FORMAT_CAP_NOON is set and 12-hour time is used, then "Noon" is 
  954.      * shown instead of "noon".  You should probably not use this flag 
  955.      * because in many locales it will not make sense to capitalize 
  956.      * the term. 
  957.      * 
  958.      * 

     

  959.      * If FORMAT_NO_MIDNIGHT is set and 12-hour time is used, then "12am" is 
  960.      * shown instead of "midnight". 
  961.      * 
  962.      * 

     

  963.      * If FORMAT_CAP_MIDNIGHT is set and 12-hour time is used, then "Midnight" 
  964.      * is shown instead of "midnight".  You should probably not use this 
  965.      * flag because in many locales it will not make sense to capitalize 
  966.      * the term. 
  967.      * 
  968.      * 

     

  969.      * If FORMAT_12HOUR is set and the time is shown, then the time is 
  970.      * shown in the 12-hour time format. You should not normally set this. 
  971.      * Instead, let the time format be chosen automatically according to the 
  972.      * system settings. If both FORMAT_12HOUR and FORMAT_24HOUR are set, then 
  973.      * FORMAT_24HOUR takes precedence. 
  974.      * 
  975.      * 

     

  976.      * If FORMAT_24HOUR is set and the time is shown, then the time is 
  977.      * shown in the 24-hour time format. You should not normally set this. 
  978.      * Instead, let the time format be chosen automatically according to the 
  979.      * system settings. If both FORMAT_12HOUR and FORMAT_24HOUR are set, then 
  980.      * FORMAT_24HOUR takes precedence. 
  981.      * 
  982.      * 

     

  983.      * If FORMAT_UTC is set, then the UTC time zone is used for the start 
  984.      * and end milliseconds unless a time zone is specified. If a time zone 
  985.      * is specified it will be used regardless of the FORMAT_UTC flag. 
  986.      * 
  987.      * 

     

  988.      * If FORMAT_ABBREV_TIME is set and 12-hour time format is used, then the 
  989.      * start and end times (if shown) are abbreviated by not showing the minutes 
  990.      * if they are zero.  For example, instead of "3:00pm" the time would be 
  991.      * abbreviated to "3pm". 
  992.      * 
  993.      * 

     

  994.      * If FORMAT_ABBREV_WEEKDAY is set, then the weekday (if shown) is 
  995.      * abbreviated to a 3-letter string. 
  996.      * 
  997.      * 

     

  998.      * If FORMAT_ABBREV_MONTH is set, then the month (if shown) is abbreviated 
  999.      * to a 3-letter string. 
  1000.      * 
  1001.      * 

     

  1002.      * If FORMAT_ABBREV_ALL is set, then the weekday and the month (if shown) 
  1003.      * are abbreviated to 3-letter strings. 
  1004.      * 
  1005.      * 

     

  1006.      * If FORMAT_NUMERIC_DATE is set, then the date is shown in numeric format 
  1007.      * instead of using the name of the month.  For example, "12/31/2008" 
  1008.      * instead of "December 31, 2008". 
  1009.      * 
  1010.      * 

     

  1011.      * If the end date ends at 12:00am at the beginning of a day, it is 
  1012.      * formatted as the end of the previous day in two scenarios: 
  1013.      * 
       
    •      *   
    • For single day events. This results in "8pm - midnight" instead of 
    •      *       "Nov 10, 8pm - Nov 11, 12am".
    •  
    •      *   
    • When the time is not displayed. This results in "Nov 10 - 11" for 
    •      *       an event with a start date of Nov 10 and an end date of Nov 12 at 
    •      *       00:00.
    •  
    •      * 
     
  1014.      * 
  1015.      * @param context the context is required only if the time is shown 
  1016.      * @param formatter the Formatter used for formatting the date range. 
  1017.      * Note: be sure to call setLength(0) on StringBuilder passed to 
  1018.      * the Formatter constructor unless you want the results to accumulate. 
  1019.      * @param startMillis the start time in UTC milliseconds 
  1020.      * @param endMillis the end time in UTC milliseconds 
  1021.      * @param flags a bit mask of options 
  1022.      * @param timeZone the time zone to compute the string in. Use null for local 
  1023.      * or if the FORMAT_UTC flag is being used. 
  1024.      * 
  1025.      * @return the formatter with the formatted date/time range appended to the string buffer. 
  1026.      */  
  1027.     public static Formatter formatDateRange(Context context, Formatter formatter, long startMillis,  
  1028.             long endMillis, int flags, String timeZone) {  
  1029.         Resources res = Resources.getSystem();  
  1030.         boolean showTime = (flags & FORMAT_SHOW_TIME) != 0;  
  1031.         boolean showWeekDay = (flags & FORMAT_SHOW_WEEKDAY) != 0;  
  1032.         boolean showYear = (flags & FORMAT_SHOW_YEAR) != 0;  
  1033.         boolean noYear = (flags & FORMAT_NO_YEAR) != 0;  
  1034.         boolean useUTC = (flags & FORMAT_UTC) != 0;  
  1035.         boolean abbrevWeekDay = (flags & (FORMAT_ABBREV_WEEKDAY | FORMAT_ABBREV_ALL)) != 0;  
  1036.         boolean abbrevMonth = (flags & (FORMAT_ABBREV_MONTH | FORMAT_ABBREV_ALL)) != 0;  
  1037.         boolean noMonthDay = (flags & FORMAT_NO_MONTH_DAY) != 0;  
  1038.         boolean numericDate = (flags & FORMAT_NUMERIC_DATE) != 0;  
  1039.   
  1040.         // If we're getting called with a single instant in time (from  
  1041.         // e.g. formatDateTime(), below), then we can skip a lot of  
  1042.         // computation below that'd otherwise be thrown out.  
  1043.         boolean isInstant = (startMillis == endMillis);  
  1044.   
  1045.         Time startDate;  
  1046.         if (timeZone != null) {  
  1047.             startDate = new Time(timeZone);  
  1048.         } else if (useUTC) {  
  1049.             startDate = new Time(Time.TIMEZONE_UTC);  
  1050.         } else {  
  1051.             startDate = new Time();  
  1052.         }  
  1053.         startDate.set(startMillis);  
  1054.   
  1055.         Time endDate;  
  1056.         int dayDistance;  
  1057.         if (isInstant) {  
  1058.             endDate = startDate;  
  1059.             dayDistance = 0;  
  1060.         } else {  
  1061.             if (timeZone != null) {  
  1062.                 endDate = new Time(timeZone);  
  1063.             } else if (useUTC) {  
  1064.                 endDate = new Time(Time.TIMEZONE_UTC);  
  1065.             } else {  
  1066.                 endDate = new Time();  
  1067.             }  
  1068.             endDate.set(endMillis);  
  1069.             int startJulianDay = Time.getJulianDay(startMillis, startDate.gmtoff);  
  1070.             int endJulianDay = Time.getJulianDay(endMillis, endDate.gmtoff);  
  1071.             dayDistance = endJulianDay - startJulianDay;  
  1072.         }  
  1073.   
  1074.         if (!isInstant  
  1075.             && (endDate.hour | endDate.minute | endDate.second) == 0  
  1076.             && (!showTime || dayDistance <= 1)) {  
  1077.             endDate.monthDay -= 1;  
  1078.             endDate.normalize(true /* ignore isDst */);  
  1079.         }  
  1080.   
  1081.         int startDay = startDate.monthDay;  
  1082.         int startMonthNum = startDate.month;  
  1083.         int startYear = startDate.year;  
  1084.   
  1085.         int endDay = endDate.monthDay;  
  1086.         int endMonthNum = endDate.month;  
  1087.         int endYear = endDate.year;  
  1088.   
  1089.         String startWeekDayString = "";  
  1090.         String endWeekDayString = "";  
  1091.         if (showWeekDay) {  
  1092.             String weekDayFormat = "";  
  1093.             if (abbrevWeekDay) {  
  1094.                 weekDayFormat = ABBREV_WEEKDAY_FORMAT;  
  1095.             } else {  
  1096.                 weekDayFormat = WEEKDAY_FORMAT;  
  1097.             }  
  1098.             startWeekDayString = startDate.format(weekDayFormat);  
  1099.             endWeekDayString = isInstant ? startWeekDayString : endDate.format(weekDayFormat);  
  1100.         }  
  1101.   
  1102.         String startTimeString = "";  
  1103.         String endTimeString = "";  
  1104.         if (showTime) {  
  1105.             String startTimeFormat = "";  
  1106.             String endTimeFormat = "";  
  1107.             boolean force24Hour = (flags & FORMAT_24HOUR) != 0;  
  1108.             boolean force12Hour = (flags & FORMAT_12HOUR) != 0;  
  1109.             boolean use24Hour;  
  1110.             if (force24Hour) {  
  1111.                 use24Hour = true;  
  1112.             } else if (force12Hour) {  
  1113.                 use24Hour = false;  
  1114.             } else {  
  1115.                 use24Hour = DateFormat.is24HourFormat(context);  
  1116.             }  
  1117.             if (use24Hour) {  
  1118.                 startTimeFormat = endTimeFormat =  
  1119.                     res.getString(com.android.internal.R.string.hour_minute_24);  
  1120.             } else {  
  1121.                 boolean abbrevTime = (flags & (FORMAT_ABBREV_TIME | FORMAT_ABBREV_ALL)) != 0;  
  1122.                 boolean capAMPM = (flags & FORMAT_CAP_AMPM) != 0;  
  1123.                 boolean noNoon = (flags & FORMAT_NO_NOON) != 0;  
  1124.                 boolean capNoon = (flags & FORMAT_CAP_NOON) != 0;  
  1125.                 boolean noMidnight = (flags & FORMAT_NO_MIDNIGHT) != 0;  
  1126.                 boolean capMidnight = (flags & FORMAT_CAP_MIDNIGHT) != 0;  
  1127.   
  1128.                 boolean startOnTheHour = startDate.minute == 0 && startDate.second == 0;  
  1129.                 boolean endOnTheHour = endDate.minute == 0 && endDate.second == 0;  
  1130.                 if (abbrevTime && startOnTheHour) {  
  1131.                     if (capAMPM) {  
  1132.                         startTimeFormat = res.getString(com.android.internal.R.string.hour_cap_ampm);  
  1133.                     } else {  
  1134.                         startTimeFormat = res.getString(com.android.internal.R.string.hour_ampm);  
  1135.                     }  
  1136.                 } else {  
  1137.                     if (capAMPM) {  
  1138.                         startTimeFormat = res.getString(com.android.internal.R.string.hour_minute_cap_ampm);  
  1139.                     } else {  
  1140.                         startTimeFormat = res.getString(com.android.internal.R.string.hour_minute_ampm);  
  1141.                     }  
  1142.                 }  
  1143.   
  1144.                 // Don't waste time on setting endTimeFormat when  
  1145.                 // we're dealing with an instant, where we'll never  
  1146.                 // need the end point.  (It's the same as the start  
  1147.                 // point)  
  1148.                 if (!isInstant) {  
  1149.                     if (abbrevTime && endOnTheHour) {  
  1150.                         if (capAMPM) {  
  1151.                             endTimeFormat = res.getString(com.android.internal.R.string.hour_cap_ampm);  
  1152.                         } else {  
  1153.                             endTimeFormat = res.getString(com.android.internal.R.string.hour_ampm);  
  1154.                         }  
  1155.                     } else {  
  1156.                         if (capAMPM) {  
  1157.                             endTimeFormat = res.getString(com.android.internal.R.string.hour_minute_cap_ampm);  
  1158.                         } else {  
  1159.                             endTimeFormat = res.getString(com.android.internal.R.string.hour_minute_ampm);  
  1160.                         }  
  1161.                     }  
  1162.   
  1163.                     if (endDate.hour == 12 && endOnTheHour && !noNoon) {  
  1164.                         if (capNoon) {  
  1165.                             endTimeFormat = res.getString(com.android.internal.R.string.Noon);  
  1166.                         } else {  
  1167.                             endTimeFormat = res.getString(com.android.internal.R.string.noon);  
  1168.                         }  
  1169.                     } else if (endDate.hour == 0 && endOnTheHour && !noMidnight) {  
  1170.                         if (capMidnight) {  
  1171.                             endTimeFormat = res.getString(com.android.internal.R.string.Midnight);  
  1172.                         } else {  
  1173.                             endTimeFormat = res.getString(com.android.internal.R.string.midnight);  
  1174.                         }  
  1175.                     }  
  1176.                 }  
  1177.   
  1178.                 if (startDate.hour == 12 && startOnTheHour && !noNoon) {  
  1179.                     if (capNoon) {  
  1180.                         startTimeFormat = res.getString(com.android.internal.R.string.Noon);  
  1181.                     } else {  
  1182.                         startTimeFormat = res.getString(com.android.internal.R.string.noon);  

你可能感兴趣的:(Android基础)