/* * Copyright (C) 2009 Android Shuffle Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dodgybits.shuffle.android.core.util; import static android.text.format.DateUtils.FORMAT_ABBREV_MONTH; import static android.text.format.DateUtils.FORMAT_ABBREV_TIME; import static android.text.format.DateUtils.FORMAT_SHOW_DATE; import static android.text.format.DateUtils.FORMAT_SHOW_TIME; import java.lang.ref.SoftReference; import java.text.DateFormat; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.Date; import android.content.Context; import android.text.format.Time; public class DateUtils { /** * Lazily create date format objects, one per thread. Use soft references so format * may be collected when low on memory. */ private static final ThreadLocal<SoftReference<DateFormat>> cDateFormat = new ThreadLocal<SoftReference<DateFormat>>() { private SoftReference<DateFormat> createValue() { return new SoftReference<DateFormat>(new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ")); } @Override public SoftReference<DateFormat> get() { SoftReference<DateFormat> value = super.get(); if (value == null || value.get() == null) { value = createValue(); set(value); } return value; } }; /** * Accepts strings in ISO 8601 format. This includes the following cases: * <ul> * <li>2009-08-15T12:50:03+01:00</li> * <li>2009-08-15T12:50:03+0200</li> * <li>2010-04-07T04:00:00Z</li> * </ul> */ public static long parseIso8601Date(String dateStr) throws ParseException { // normalize timezone first String timezone = dateStr.substring(19); timezone = timezone.replaceAll(":", ""); if ("Z".equals(timezone)) { // Z indicates UTC, so convert to standard representation timezone = "+0000"; } String cleanedDateStr = dateStr.substring(0, 19) + timezone; DateFormat f = cDateFormat.get().get(); Date d = f.parse(cleanedDateStr); return d.getTime(); } public static String formatIso8601Date(long ms) { DateFormat f = cDateFormat.get().get(); String dateStr = f.format(new Date(ms)); if (dateStr.length() == 24) { dateStr = dateStr.substring(0, 22) + ":" + dateStr.substring(22); } return dateStr; } public static boolean isSameDay(long millisX, long millisY) { return Time.getJulianDay(millisX, 0) == Time.getJulianDay(millisY, 0); } public static CharSequence displayDateRange(Context context, long startMs, long endMs, boolean includeTime) { CharSequence result = ""; final boolean includeStart = startMs > 0L; final boolean includeEnd = endMs > 0L; if (includeStart) { if (includeEnd) { int flags = FORMAT_SHOW_DATE | FORMAT_ABBREV_MONTH; if (includeTime) { flags |= FORMAT_SHOW_TIME | FORMAT_ABBREV_TIME; } result = android.text.format.DateUtils.formatDateRange( context, startMs, endMs, flags); } else { result = displayShortDateTime(context, startMs); } } else if (includeEnd) { result = displayShortDateTime(context, endMs); } return result; } /** * Display date time in short format using the user's date format settings * as a guideline. * * For epoch, display nothing. * For today, only show the time. * Otherwise, only show the day and month. * * @param context * @param timeInMs datetime to display * @return locale specific representation */ public static CharSequence displayShortDateTime(Context context, long timeInMs) { long now = System.currentTimeMillis(); CharSequence result; if (timeInMs == 0L) { result = ""; } else { int flags; if (isSameDay(timeInMs, now)) { flags = FORMAT_SHOW_TIME | FORMAT_ABBREV_TIME; } else { flags = FORMAT_SHOW_DATE | FORMAT_ABBREV_MONTH; } result = android.text.format.DateUtils.formatDateRange( context, timeInMs, timeInMs, flags); } return result; } }