DateUtils.java revision 2b3f95cc12b76523410782d4178562ce241410ef
1/*
2 * Copyright (C) 2010 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.android.contacts.util;
18
19import android.content.Context;
20import android.text.format.DateFormat;
21
22import java.text.ParsePosition;
23import java.text.SimpleDateFormat;
24import java.util.Date;
25
26/**
27 * Utility methods for processing dates.
28 */
29public class DateUtils {
30    public static final SimpleDateFormat NO_YEAR_DATE_FORMAT = new SimpleDateFormat("--MM-dd");
31    public static final SimpleDateFormat FULL_DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd");
32    public static final SimpleDateFormat DATE_AND_TIME_FORMAT =
33            new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'");
34
35    // Variations of ISO 8601 date format.  Do not change the order - it does affect the
36    // result in ambiguous cases.
37    private static final SimpleDateFormat[] DATE_FORMATS = {
38        FULL_DATE_FORMAT,
39        DATE_AND_TIME_FORMAT,
40        new SimpleDateFormat("yyyy-MM-dd'T'HH:mm'Z'"),
41        new SimpleDateFormat("yyyyMMdd"),
42        new SimpleDateFormat("yyyyMMdd'T'HHmmssSSS'Z'"),
43        new SimpleDateFormat("yyyyMMdd'T'HHmmss'Z'"),
44        new SimpleDateFormat("yyyyMMdd'T'HHmm'Z'"),
45    };
46
47    static {
48        for (SimpleDateFormat format : DATE_FORMATS) {
49            format.setLenient(true);
50        }
51    }
52
53    private static final java.text.DateFormat FORMAT_WITHOUT_YEAR_MONTH_FIRST =
54            new SimpleDateFormat("MMMM dd");
55
56    private static final java.text.DateFormat FORMAT_WITHOUT_YEAR_DATE_FIRST =
57            new SimpleDateFormat("dd MMMM");
58
59    /**
60     * Parses the supplied string to see if it looks like a date. If so,
61     * returns the date.  Otherwise, returns null.
62     */
63    public static Date parseDate(String string) {
64        ParsePosition parsePosition = new ParsePosition(0);
65        for (int i = 0; i < DATE_FORMATS.length; i++) {
66            SimpleDateFormat f = DATE_FORMATS[i];
67            synchronized (f) {
68                parsePosition.setIndex(0);
69                Date date = f.parse(string, parsePosition);
70                if (parsePosition.getIndex() == string.length()) {
71                    return date;
72                }
73            }
74        }
75        return null;
76    }
77
78    /**
79     * Parses the supplied string to see if it looks like a date. If so,
80     * returns the same date in a cleaned-up format.  Otherwise, returns
81     * the supplied string unchanged.
82     */
83    public static String formatDate(Context context, String string) {
84        if (string == null) {
85            return null;
86        }
87
88        string = string.trim();
89        if (string.length() == 0) {
90            return string;
91        }
92
93        ParsePosition parsePosition = new ParsePosition(0);
94
95        Date date;
96
97        synchronized (NO_YEAR_DATE_FORMAT) {
98            date = NO_YEAR_DATE_FORMAT.parse(string, parsePosition);
99        }
100
101        if (parsePosition.getIndex() == string.length()) {
102            java.text.DateFormat outFormat = isMonthBeforeDate(context)
103                    ? FORMAT_WITHOUT_YEAR_MONTH_FIRST
104                    : FORMAT_WITHOUT_YEAR_DATE_FIRST;
105            synchronized (outFormat) {
106                return outFormat.format(date);
107            }
108        }
109
110        for (int i = 0; i < DATE_FORMATS.length; i++) {
111            SimpleDateFormat f = DATE_FORMATS[i];
112            synchronized (f) {
113                parsePosition.setIndex(0);
114                date = f.parse(string, parsePosition);
115                if (parsePosition.getIndex() == string.length()) {
116                    java.text.DateFormat outFormat = DateFormat.getDateFormat(context);
117                    synchronized (outFormat) {
118                        return outFormat.format(date);
119                    }
120                }
121            }
122        }
123        return string;
124    }
125
126    private static boolean isMonthBeforeDate(Context context) {
127        char[] dateFormatOrder = DateFormat.getDateFormatOrder(context);
128        for (int i = 0; i < dateFormatOrder.length; i++) {
129            if (dateFormatOrder[i] == DateFormat.DATE) {
130                return false;
131            }
132            if (dateFormatOrder[i] == DateFormat.MONTH) {
133                return true;
134            }
135        }
136        return false;
137    }
138}
139