/*
* Copyright (C) 2013 Simon Vig Therkildsen
*
* 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 net.simonvt.cathode.util;
import android.content.Context;
import android.content.res.Resources;
import android.text.format.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.Locale;
import net.simonvt.cathode.R;
public final class DateUtils {
public static final long MINUTE_IN_SECONDS = 60;
public static final long HOUR_IN_SECONDS = 60 * MINUTE_IN_SECONDS;
public static final long DAY_IN_SECONDS = 24 * HOUR_IN_SECONDS;
public static final long YEAR_IN_SECONDS = 365 * DAY_IN_SECONDS;
public static final long MINUTE_IN_MILLIS = android.text.format.DateUtils.MINUTE_IN_MILLIS;
public static final long HOUR_IN_MILLIS = android.text.format.DateUtils.HOUR_IN_MILLIS;
public static final long DAY_IN_MILLIS = android.text.format.DateUtils.DAY_IN_MILLIS;
public static final long YEAR_IN_MILLIS = android.text.format.DateUtils.YEAR_IN_MILLIS;
public static final long HOUR_IN_MINUTES = 60;
public static final long DAY_IN_MINUTES = 24 * HOUR_IN_MINUTES;
public static final long YEAR_IN_MINUTES = 365 * DAY_IN_MINUTES;
private DateUtils() {
}
public static long getMillis(String iso) {
try {
SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ", Locale.US);
Date date = formatter.parse(iso);
return date.getTime();
} catch (ParseException e) {
e.printStackTrace();
}
return 0L;
}
/**
* Calculate time until the timestamp string returned by
* {@link #millisToString(android.content.Context, long, boolean)} should be updated.
*/
public static long timeUntilUpdate(long millis) {
Calendar rightNow = Calendar.getInstance();
final long rightNowMillis = rightNow.getTimeInMillis();
Calendar nextYear = Calendar.getInstance();
final int year = rightNow.get(Calendar.YEAR);
nextYear.set(year + 1, Calendar.JANUARY, 1, 0, 0, 0);
final long nextYearMillis = nextYear.getTimeInMillis();
// If show aired more than 24 hours ago, update next year
if (millis < rightNowMillis - 24 * HOUR_IN_MILLIS) {
return nextYearMillis - rightNowMillis;
}
// If millis is next year
if (millis > nextYearMillis) {
if (millis - 24 * HOUR_IN_MILLIS < nextYearMillis) {
return millis - 24 * HOUR_IN_MILLIS - rightNowMillis;
} else {
return nextYearMillis - rightNowMillis;
}
}
// If millis is in more than 24 hours
if (millis > rightNowMillis + 24 * HOUR_IN_MILLIS) {
return millis - 24 * HOUR_IN_MILLIS - rightNowMillis;
}
// If millis is within next hour
if (millis <= rightNowMillis + HOUR_IN_MILLIS && millis >= rightNowMillis) {
final long nextMin = millis % MINUTE_IN_MILLIS;
return nextMin > 0 ? nextMin : MINUTE_IN_MILLIS;
}
// If millis was within last hour
if (millis < rightNowMillis && millis >= rightNowMillis - HOUR_IN_MILLIS) {
final long lastMin = millis % MINUTE_IN_MILLIS;
return lastMin > 0 ? MINUTE_IN_MILLIS - lastMin : MINUTE_IN_MILLIS;
}
// If millis is within next 24 hours
if (millis > rightNowMillis && millis <= rightNowMillis + 24 * HOUR_IN_MILLIS) {
final long nextHour = millis % HOUR_IN_MILLIS;
return nextHour > 0 ? nextHour : HOUR_IN_MILLIS;
}
// If millis was within last 24 hours
if (millis < rightNowMillis && millis >= rightNowMillis - 24 * HOUR_IN_MILLIS) {
final long lastHour = millis % HOUR_IN_MILLIS;
return lastHour > 0 ? HOUR_IN_MILLIS - lastHour : HOUR_IN_MILLIS;
}
throw new RuntimeException(
"Unable to get update time for millis " + millis + " at time " + rightNowMillis);
}
public static String getTimeString(Context context, long millis) {
StringBuilder sb = new StringBuilder();
Calendar cal = Calendar.getInstance();
cal.setTimeInMillis(millis);
final boolean twentyFourHourFormat = DateFormat.is24HourFormat(context);
if (twentyFourHourFormat) {
sb.append(cal.get(Calendar.HOUR_OF_DAY));
} else {
sb.append(cal.get(Calendar.HOUR));
}
sb.append(":").append(String.format(Locale.US, "%02d", cal.get(Calendar.MINUTE)));
if (!twentyFourHourFormat) {
sb.append(" ");
final int ampm = cal.get(Calendar.AM_PM);
if (ampm == Calendar.AM) {
sb.append("am");
} else {
sb.append("pm");
}
}
return sb.toString();
}
public static String getDateString(long millis) {
Calendar cal = Calendar.getInstance();
cal.setTimeInMillis(millis);
SimpleDateFormat formatter = new SimpleDateFormat("EEEE, MMMM d", Locale.US);
return formatter.format(cal.getTime());
}
/** Formats milliseconds (UTC) as a String. */
public static String millisToString(Context context, long millis, boolean extended) {
if (millis == 0L) {
return context.getResources().getString(R.string.airdate_unknown);
}
Calendar cal = Calendar.getInstance();
final long rightNow = cal.getTimeInMillis();
if (rightNow >= millis - 2 * MINUTE_IN_MILLIS && rightNow <= millis + 2 * MINUTE_IN_MILLIS) {
return context.getString(R.string.now);
}
if (rightNow > millis && rightNow < millis + 1 * HOUR_IN_MILLIS) {
final int minutes = (int) ((rightNow - millis) / MINUTE_IN_MILLIS);
return context.getResources().getQuantityString(R.plurals.minutes_ago, minutes, minutes);
}
if (rightNow < millis && rightNow > millis - 1 * HOUR_IN_MILLIS) {
final int minutes = (int) ((millis - rightNow) / MINUTE_IN_MILLIS);
return context.getResources().getQuantityString(R.plurals.in_minutes, minutes, minutes);
}
if (rightNow > millis && rightNow <= millis + 24 * HOUR_IN_MILLIS) {
final int hours = (int) ((rightNow - millis) / HOUR_IN_MILLIS);
return context.getResources().getQuantityString(R.plurals.hours_ago, hours, hours);
}
if (rightNow < millis && rightNow >= millis - 24 * HOUR_IN_MILLIS) {
final int hours = (int) ((millis - rightNow) / HOUR_IN_MILLIS);
return context.getResources().getQuantityString(R.plurals.in_hours, hours, hours);
}
final int currentYear = cal.get(Calendar.YEAR);
cal.setTimeInMillis(millis);
final int millisYear = cal.get(Calendar.YEAR);
final String month = cal.getDisplayName(Calendar.MONTH, Calendar.SHORT, Locale.getDefault());
final int day = cal.get(Calendar.DAY_OF_MONTH);
StringBuilder sb = new StringBuilder();
if (millisYear >= currentYear || extended) {
sb.append(month).append(" ").append(day);
}
if (millisYear < currentYear && !extended) {
sb.append(millisYear);
} else if (millisYear != currentYear && extended) {
sb.append(", ").append(millisYear);
}
if (extended) {
final boolean twentyFourHourFormat = DateFormat.is24HourFormat(context);
sb.append(" ");
if (twentyFourHourFormat) {
sb.append(cal.get(Calendar.HOUR_OF_DAY));
} else {
sb.append(cal.get(Calendar.HOUR));
}
sb.append(":").append(String.format(Locale.US, "%02d", cal.get(Calendar.MINUTE)));
if (!twentyFourHourFormat) {
sb.append(" ");
final int ampm = cal.get(Calendar.AM_PM);
if (ampm == Calendar.AM) {
sb.append("am");
} else {
sb.append("pm");
}
}
}
return sb.toString();
}
public static String getStatsString(Context context, long timeInMinutes) {
Resources res = context.getResources();
final int years = (int) (timeInMinutes / YEAR_IN_MINUTES);
long timeLeft = timeInMinutes - years * YEAR_IN_MINUTES;
final int days = (int) (timeLeft / DAY_IN_MINUTES);
timeLeft = timeLeft - days * DAY_IN_MINUTES;
final int hours = (int) (timeLeft / HOUR_IN_MINUTES);
timeLeft = timeLeft - hours * HOUR_IN_MINUTES;
final int minutes = (int) timeLeft;
StringBuilder builder = new StringBuilder();
if (years > 0) {
String yearString = res.getString(R.string.stats_years, years);
builder.append(yearString);
}
if (days > 0) {
if (years > 0) {
builder.append(" ");
}
String daysString = res.getString(R.string.stats_days, days);
builder.append(daysString);
}
if (hours > 0) {
if (days > 0 || years > 0) {
builder.append(" ");
}
String hourString = res.getString(R.string.stats_hours, hours);
builder.append(hourString);
}
if (minutes > 0 && years == 0) {
if (hours > 0 || days > 0) {
builder.append(" ");
}
String minuteString = res.getString(R.string.stats_minutes, minutes);
builder.append(minuteString);
}
return builder.toString();
}
}