/* * Copyright (C) 2014 SCVNGR, Inc. d/b/a LevelUp * * 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 com.scvngr.levelup.core.util; import android.support.annotation.NonNull; import com.scvngr.levelup.core.annotation.LevelUpApi; import com.scvngr.levelup.core.annotation.LevelUpApi.Contract; import net.jcip.annotations.ThreadSafe; import java.text.DateFormat; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.Calendar; import java.util.Date; import java.util.Locale; import java.util.TimeZone; /** * Helper utility class to handle date operations. */ @ThreadSafe @LevelUpApi(contract = Contract.INTERNAL) public final class IsoDateUtils { private static final String ISO_DATETIME_TIME_ZONE_FORMAT_STRING = "yyyy-MM-dd'T'HH:mm:ssZZ"; /** * Gets a new instance of {@link TimeZone} representing UTC. * * @return A new instance of {@link TimeZone} representing UTC. */ @NonNull public static TimeZone getTimeZoneUtc() { return NullUtils.nonNullContract(TimeZone.getTimeZone("UTC")); } /** * Parses an ISO 8601 timezone-formatted string into a {@link Date} relative to a * {@link TimeZone}. * * @param datetime An ISO 8601 formatted datetime with timezone. * @param timeZone The relative {@link TimeZone}. * @return a parsed {@link Date} relative to the given {@link TimeZone}. * @throws ParseException if there was a problem parsing the date. */ @NonNull public static Date parseIsoDatetime(@NonNull final String datetime, @NonNull final TimeZone timeZone) throws ParseException { final DateFormat formatter = new SimpleDateFormat(ISO_DATETIME_TIME_ZONE_FORMAT_STRING, Locale.US); setTimeZone(formatter, timeZone); return NullUtils.nonNullContract(formatter.parse(datetime)); } /** * Converts a {@link Date} to a ISO 8601 timezone-formatted string relative to a * {@link TimeZone}. * * @param date The date to convert. * @param timeZone The relative {@link TimeZone}. * @return An ISO 8601 formatted datetime relative to the given {@link TimeZone}. */ @NonNull public static String toIsoDatetime(@NonNull final Date date, @NonNull final TimeZone timeZone) { final DateFormat formatter = new SimpleDateFormat(ISO_DATETIME_TIME_ZONE_FORMAT_STRING, Locale.US); setTimeZone(formatter, timeZone); return NullUtils.nonNullContract(formatter.format(date)); } /** * Sets the time zone of a {@link DateFormat}. This method implements a workaround for * https://code.google.com/p/android/issues/detail?id=8258 which only affects Android 2.2 * devices. * * @param timeZone The relative {@link TimeZone}. */ private static void setTimeZone(@NonNull final DateFormat formatter, @NonNull final TimeZone timeZone) { if (EnvironmentUtil.isSdk9OrGreater()) { formatter.setTimeZone(timeZone); } else { formatter.setCalendar(Calendar.getInstance(timeZone, Locale.US)); } } /** * Private constructor prevents instantiation. * * @throws UnsupportedOperationException because this class cannot be instantiated. */ private IsoDateUtils() { throw new UnsupportedOperationException("This class is non-instantiable"); } }