From f0f760315fd468e51d97804b1ddc370777d86c31 Mon Sep 17 00:00:00 2001 From: Mark Anderson Date: Wed, 5 Feb 2014 21:30:08 +0000 Subject: [PATCH 1/4] Format story date for ReadingItemFragement on client --- .../fragment/ReadingItemFragment.java | 4 +- .../src/com/newsblur/util/StoryUtils.java | 81 +++++++++++++++++++ 2 files changed, 84 insertions(+), 1 deletion(-) create mode 100644 clients/android/NewsBlur/src/com/newsblur/util/StoryUtils.java diff --git a/clients/android/NewsBlur/src/com/newsblur/fragment/ReadingItemFragment.java b/clients/android/NewsBlur/src/com/newsblur/fragment/ReadingItemFragment.java index ebc816642..e84ad3e1d 100644 --- a/clients/android/NewsBlur/src/com/newsblur/fragment/ReadingItemFragment.java +++ b/clients/android/NewsBlur/src/com/newsblur/fragment/ReadingItemFragment.java @@ -39,6 +39,7 @@ import com.newsblur.util.DefaultFeedView; import com.newsblur.util.FeedUtils; import com.newsblur.util.ImageLoader; import com.newsblur.util.PrefsUtils; +import com.newsblur.util.StoryUtils; import com.newsblur.util.UIUtils; import com.newsblur.util.ViewUtils; import com.newsblur.view.FlowLayout; @@ -309,7 +310,8 @@ public class ReadingItemFragment extends Fragment implements ClassifierDialogFra } itemTitle.setText(Html.fromHtml(story.title)); - itemDate.setText(story.longDate); + itemDate.setText(StoryUtils.formatLongDate(story.date)); + Log.d("mark", story.longDate); if (!TextUtils.isEmpty(story.authors)) { itemAuthors.setText("• " + story.authors); diff --git a/clients/android/NewsBlur/src/com/newsblur/util/StoryUtils.java b/clients/android/NewsBlur/src/com/newsblur/util/StoryUtils.java new file mode 100644 index 000000000..f2dfbda48 --- /dev/null +++ b/clients/android/NewsBlur/src/com/newsblur/util/StoryUtils.java @@ -0,0 +1,81 @@ +package com.newsblur.util; + +import java.text.SimpleDateFormat; +import java.util.Calendar; +import java.util.Date; + +/** + * Created by mark on 04/02/2014. + */ +public class StoryUtils { + + private static final SimpleDateFormat todayLongFormat = new SimpleDateFormat("MMMM d"); + private static final SimpleDateFormat monthLongFormat = new SimpleDateFormat("EEEE, MMMM d"); + private static final SimpleDateFormat yearLongFormat = new SimpleDateFormat("yyyy"); + private static final SimpleDateFormat twelveHourFormat = new SimpleDateFormat("h:mma"); + + public static String formatLongDate(Date storyDate) { + + Date midnightToday = midnightToday(); + Date midnightYesterday = midnightYesterday(); + Date beginningOfMonth = beginningOfMonth(); + + Calendar storyCalendar = Calendar.getInstance(); + storyCalendar.setTime(storyDate); + int month = storyCalendar.get(Calendar.DAY_OF_MONTH); + + // F = Long Month + // l = Long Day + // j = day number + // S = st/th etc. + if (storyDate.getTime() > midnightToday.getTime()) { + // Today, January 1st 00:00 + return "Today, " + todayLongFormat.format(storyDate) + getDayOfMonthSuffix(month) + " " + twelveHourFormat.format(storyDate); + } else if (storyDate.getTime() > midnightYesterday.getTime()) { + // Yesterday, January 1st 00:00 + return "Yesterday, " + todayLongFormat.format(storyDate) + getDayOfMonthSuffix(month) + " " + twelveHourFormat.format(storyDate); + } else if (storyDate.getTime() > beginningOfMonth.getTime()) { + // Monday, January 1st 00:00 + return monthLongFormat.format(storyDate) + getDayOfMonthSuffix(month) + " " + twelveHourFormat.format(storyDate); + } else { + // Monday, January 1st 2014 00:00 + return monthLongFormat.format(storyDate) + getDayOfMonthSuffix(month) + " " + yearLongFormat.format(storyDate) + " " + twelveHourFormat.format(storyDate); + } + } + + private static Date midnightToday() { + Calendar midnight = Calendar.getInstance(); + midnight.set(Calendar.HOUR_OF_DAY, 0); + midnight.set(Calendar.MINUTE, 0); + midnight.set(Calendar.SECOND, 0); + return midnight.getTime(); + } + + private static Date midnightYesterday() { + return new Date(midnightToday().getTime() - (24 * 60 * 60* 1000)); + } + + private static Date beginningOfMonth() { + Calendar month = Calendar.getInstance(); + month.set(Calendar.HOUR_OF_DAY, 0); + month.set(Calendar.MINUTE, 0); + month.set(Calendar.SECOND, 0); + month.set(Calendar.DAY_OF_MONTH, 1); + return month.getTime(); + } + + /** + * From http://stackoverflow.com/questions/4011075/how-do-you-format-the-day-of-the-month-to-say-11th-21st-or-23rd-in-java + */ + private static String getDayOfMonthSuffix(final int n) { + if (n >= 11 && n <= 13) { + return "th"; + } + switch (n % 10) { + case 1: return "st"; + case 2: return "nd"; + case 3: return "rd"; + default: return "th"; + } + } +} From 44435944806b4f8d563fafacfeba9e0a6368aa83 Mon Sep 17 00:00:00 2001 From: Mark Anderson Date: Thu, 6 Feb 2014 22:37:25 +0000 Subject: [PATCH 2/4] Format short dates for list item fragments --- .../AllSharedStoriesItemListFragment.java | 2 +- .../fragment/AllStoriesItemListFragment.java | 2 +- .../fragment/FeedItemListFragment.java | 2 +- .../fragment/FolderItemListFragment.java | 2 +- .../SavedStoriesItemListFragment.java | 2 +- .../fragment/SocialFeedItemListFragment.java | 2 +- .../src/com/newsblur/util/StoryUtils.java | 22 +++++++++++++++---- .../com/newsblur/view/FeedItemViewBinder.java | 8 ++++++- .../newsblur/view/SocialItemViewBinder.java | 8 ++++++- 9 files changed, 38 insertions(+), 12 deletions(-) diff --git a/clients/android/NewsBlur/src/com/newsblur/fragment/AllSharedStoriesItemListFragment.java b/clients/android/NewsBlur/src/com/newsblur/fragment/AllSharedStoriesItemListFragment.java index b1fe86734..b1a5e2b49 100644 --- a/clients/android/NewsBlur/src/com/newsblur/fragment/AllSharedStoriesItemListFragment.java +++ b/clients/android/NewsBlur/src/com/newsblur/fragment/AllSharedStoriesItemListFragment.java @@ -61,7 +61,7 @@ public class AllSharedStoriesItemListFragment extends ItemListFragment implement contentResolver = getActivity().getContentResolver(); - String[] groupFrom = new String[] { DatabaseConstants.STORY_TITLE, DatabaseConstants.STORY_AUTHORS, DatabaseConstants.STORY_TITLE, DatabaseConstants.STORY_SHORTDATE, DatabaseConstants.STORY_INTELLIGENCE_AUTHORS, DatabaseConstants.FEED_TITLE }; + String[] groupFrom = new String[] { DatabaseConstants.STORY_TITLE, DatabaseConstants.STORY_AUTHORS, DatabaseConstants.STORY_TITLE, DatabaseConstants.STORY_DATE, DatabaseConstants.STORY_INTELLIGENCE_AUTHORS, DatabaseConstants.FEED_TITLE }; int[] groupTo = new int[] { R.id.row_item_title, R.id.row_item_author, R.id.row_item_title, R.id.row_item_date, R.id.row_item_sidebar, R.id.row_item_feedtitle }; // TODO: defer creation of the adapter until the loader's first callback so we don't leak this first ListView cursor Cursor cursor = contentResolver.query(FeedProvider.ALL_SHARED_STORIES_URI, null, DatabaseConstants.getStorySelectionFromState(currentState), null, DatabaseConstants.getStorySortOrder(storyOrder)); diff --git a/clients/android/NewsBlur/src/com/newsblur/fragment/AllStoriesItemListFragment.java b/clients/android/NewsBlur/src/com/newsblur/fragment/AllStoriesItemListFragment.java index 51ecb8de5..ebf7b39e6 100644 --- a/clients/android/NewsBlur/src/com/newsblur/fragment/AllStoriesItemListFragment.java +++ b/clients/android/NewsBlur/src/com/newsblur/fragment/AllStoriesItemListFragment.java @@ -59,7 +59,7 @@ public class AllStoriesItemListFragment extends StoryItemListFragment implements Cursor cursor = getActivity().getContentResolver().query(FeedProvider.ALL_STORIES_URI, null, DatabaseConstants.getStorySelectionFromState(currentState), null, DatabaseConstants.getStorySortOrder(storyOrder)); getActivity().startManagingCursor(cursor); - String[] groupFrom = new String[] { DatabaseConstants.STORY_TITLE, DatabaseConstants.STORY_AUTHORS, DatabaseConstants.STORY_TITLE, DatabaseConstants.STORY_SHORTDATE, DatabaseConstants.STORY_INTELLIGENCE_AUTHORS, DatabaseConstants.FEED_TITLE }; + String[] groupFrom = new String[] { DatabaseConstants.STORY_TITLE, DatabaseConstants.STORY_AUTHORS, DatabaseConstants.STORY_TITLE, DatabaseConstants.STORY_DATE, DatabaseConstants.STORY_INTELLIGENCE_AUTHORS, DatabaseConstants.FEED_TITLE }; int[] groupTo = new int[] { R.id.row_item_title, R.id.row_item_author, R.id.row_item_title, R.id.row_item_date, R.id.row_item_sidebar, R.id.row_item_feedtitle }; adapter = new MultipleFeedItemsAdapter(getActivity(), R.layout.row_socialitem, cursor, groupFrom, groupTo, CursorAdapter.FLAG_REGISTER_CONTENT_OBSERVER); diff --git a/clients/android/NewsBlur/src/com/newsblur/fragment/FeedItemListFragment.java b/clients/android/NewsBlur/src/com/newsblur/fragment/FeedItemListFragment.java index 594416aca..ad8f08a26 100644 --- a/clients/android/NewsBlur/src/com/newsblur/fragment/FeedItemListFragment.java +++ b/clients/android/NewsBlur/src/com/newsblur/fragment/FeedItemListFragment.java @@ -88,7 +88,7 @@ public class FeedItemListFragment extends StoryItemListFragment implements Loade Feed feed = Feed.fromCursor(feedCursor); feedCursor.close(); - String[] groupFrom = new String[] { DatabaseConstants.STORY_TITLE, DatabaseConstants.STORY_AUTHORS, DatabaseConstants.STORY_READ, DatabaseConstants.STORY_SHORTDATE, DatabaseConstants.STORY_INTELLIGENCE_AUTHORS }; + String[] groupFrom = new String[] { DatabaseConstants.STORY_TITLE, DatabaseConstants.STORY_AUTHORS, DatabaseConstants.STORY_READ, DatabaseConstants.STORY_DATE, DatabaseConstants.STORY_INTELLIGENCE_AUTHORS }; int[] groupTo = new int[] { R.id.row_item_title, R.id.row_item_author, R.id.row_item_title, R.id.row_item_date, R.id.row_item_sidebar }; // create the adapter before starting the loader, since the callback updates the adapter diff --git a/clients/android/NewsBlur/src/com/newsblur/fragment/FolderItemListFragment.java b/clients/android/NewsBlur/src/com/newsblur/fragment/FolderItemListFragment.java index 59442f3e9..e7ce91456 100644 --- a/clients/android/NewsBlur/src/com/newsblur/fragment/FolderItemListFragment.java +++ b/clients/android/NewsBlur/src/com/newsblur/fragment/FolderItemListFragment.java @@ -83,7 +83,7 @@ public class FolderItemListFragment extends StoryItemListFragment implements Loa Cursor cursor = contentResolver.query(FeedProvider.MULTIFEED_STORIES_URI, null, DatabaseConstants.getStorySelectionFromState(currentState), feedIds, DatabaseConstants.getStorySortOrder(storyOrder)); getActivity().startManagingCursor(cursor); - String[] groupFrom = new String[] { DatabaseConstants.STORY_TITLE, DatabaseConstants.FEED_TITLE, DatabaseConstants.STORY_READ, DatabaseConstants.STORY_SHORTDATE, DatabaseConstants.STORY_INTELLIGENCE_AUTHORS, DatabaseConstants.STORY_AUTHORS }; + String[] groupFrom = new String[] { DatabaseConstants.STORY_TITLE, DatabaseConstants.FEED_TITLE, DatabaseConstants.STORY_READ, DatabaseConstants.STORY_DATE, DatabaseConstants.STORY_INTELLIGENCE_AUTHORS, DatabaseConstants.STORY_AUTHORS }; int[] groupTo = new int[] { R.id.row_item_title, R.id.row_item_feedtitle, R.id.row_item_title, R.id.row_item_date, R.id.row_item_sidebar, R.id.row_item_author }; getLoaderManager().initLoader(ITEMLIST_LOADER , null, this); diff --git a/clients/android/NewsBlur/src/com/newsblur/fragment/SavedStoriesItemListFragment.java b/clients/android/NewsBlur/src/com/newsblur/fragment/SavedStoriesItemListFragment.java index b23a6c53a..724fec595 100644 --- a/clients/android/NewsBlur/src/com/newsblur/fragment/SavedStoriesItemListFragment.java +++ b/clients/android/NewsBlur/src/com/newsblur/fragment/SavedStoriesItemListFragment.java @@ -52,7 +52,7 @@ public class SavedStoriesItemListFragment extends ItemListFragment implements Lo contentResolver = getActivity().getContentResolver(); Cursor cursor = contentResolver.query(FeedProvider.STARRED_STORIES_URI, null, null, null, DatabaseConstants.STARRED_STORY_ORDER); - String[] groupFrom = new String[] { DatabaseConstants.STORY_TITLE, DatabaseConstants.STORY_AUTHORS, DatabaseConstants.STORY_TITLE, DatabaseConstants.STORY_SHORTDATE, DatabaseConstants.STORY_INTELLIGENCE_AUTHORS, DatabaseConstants.FEED_TITLE }; + String[] groupFrom = new String[] { DatabaseConstants.STORY_TITLE, DatabaseConstants.STORY_AUTHORS, DatabaseConstants.STORY_TITLE, DatabaseConstants.STORY_DATE, DatabaseConstants.STORY_INTELLIGENCE_AUTHORS, DatabaseConstants.FEED_TITLE }; int[] groupTo = new int[] { R.id.row_item_title, R.id.row_item_author, R.id.row_item_title, R.id.row_item_date, R.id.row_item_sidebar, R.id.row_item_feedtitle }; getLoaderManager().initLoader(ITEMLIST_LOADER , null, this); diff --git a/clients/android/NewsBlur/src/com/newsblur/fragment/SocialFeedItemListFragment.java b/clients/android/NewsBlur/src/com/newsblur/fragment/SocialFeedItemListFragment.java index db5d1b9a9..b04fbe917 100644 --- a/clients/android/NewsBlur/src/com/newsblur/fragment/SocialFeedItemListFragment.java +++ b/clients/android/NewsBlur/src/com/newsblur/fragment/SocialFeedItemListFragment.java @@ -60,7 +60,7 @@ public class SocialFeedItemListFragment extends ItemListFragment implements Load Uri uri = FeedProvider.SOCIALFEED_STORIES_URI.buildUpon().appendPath(userId).build(); Cursor cursor = getActivity().getContentResolver().query(uri, null, DatabaseConstants.getStorySelectionFromState(currentState), null, DatabaseConstants.getStorySharedSortOrder(storyOrder)); - groupFroms = new String[] { DatabaseConstants.FEED_FAVICON_URL, DatabaseConstants.FEED_TITLE, DatabaseConstants.STORY_TITLE, DatabaseConstants.STORY_SHORTDATE, DatabaseConstants.STORY_AUTHORS, DatabaseConstants.STORY_INTELLIGENCE_AUTHORS}; + groupFroms = new String[] { DatabaseConstants.FEED_FAVICON_URL, DatabaseConstants.FEED_TITLE, DatabaseConstants.STORY_TITLE, DatabaseConstants.STORY_DATE, DatabaseConstants.STORY_AUTHORS, DatabaseConstants.STORY_INTELLIGENCE_AUTHORS}; groupTos = new int[] { R.id.row_item_feedicon, R.id.row_item_feedtitle, R.id.row_item_title, R.id.row_item_date, R.id.row_item_author, R.id.row_item_sidebar}; adapter = new MultipleFeedItemsAdapter(getActivity(), R.layout.row_socialitem, cursor, groupFroms, groupTos, CursorAdapter.FLAG_REGISTER_CONTENT_OBSERVER); diff --git a/clients/android/NewsBlur/src/com/newsblur/util/StoryUtils.java b/clients/android/NewsBlur/src/com/newsblur/util/StoryUtils.java index f2dfbda48..e9c0749f1 100644 --- a/clients/android/NewsBlur/src/com/newsblur/util/StoryUtils.java +++ b/clients/android/NewsBlur/src/com/newsblur/util/StoryUtils.java @@ -13,6 +13,7 @@ public class StoryUtils { private static final SimpleDateFormat monthLongFormat = new SimpleDateFormat("EEEE, MMMM d"); private static final SimpleDateFormat yearLongFormat = new SimpleDateFormat("yyyy"); private static final SimpleDateFormat twelveHourFormat = new SimpleDateFormat("h:mma"); + private static final SimpleDateFormat shortDateFormat = new SimpleDateFormat("d MMM yyyy"); public static String formatLongDate(Date storyDate) { @@ -24,10 +25,6 @@ public class StoryUtils { storyCalendar.setTime(storyDate); int month = storyCalendar.get(Calendar.DAY_OF_MONTH); - // F = Long Month - // l = Long Day - // j = day number - // S = st/th etc. if (storyDate.getTime() > midnightToday.getTime()) { // Today, January 1st 00:00 return "Today, " + todayLongFormat.format(storyDate) + getDayOfMonthSuffix(month) + " " + twelveHourFormat.format(storyDate); @@ -78,4 +75,21 @@ public class StoryUtils { default: return "th"; } } + + public static String formatShortDate(Date storyDate) { + + Date midnightToday = midnightToday(); + Date midnightYesterday = midnightYesterday(); + + if (storyDate.getTime() > midnightToday.getTime()) { + // 00:00 + return twelveHourFormat.format(storyDate); + } else if (storyDate.getTime() > midnightYesterday.getTime()) { + // Yesterday, 00:00 + return "Yesterday, " + twelveHourFormat.format(storyDate); + } else { + // 1 Jan 2014, 00:00 + return shortDateFormat.format(storyDate) +", " + twelveHourFormat.format(storyDate); + } + } } diff --git a/clients/android/NewsBlur/src/com/newsblur/view/FeedItemViewBinder.java b/clients/android/NewsBlur/src/com/newsblur/view/FeedItemViewBinder.java index 1f546474e..73ac7e9b3 100644 --- a/clients/android/NewsBlur/src/com/newsblur/view/FeedItemViewBinder.java +++ b/clients/android/NewsBlur/src/com/newsblur/view/FeedItemViewBinder.java @@ -12,6 +12,9 @@ import android.widget.TextView; import com.newsblur.R; import com.newsblur.database.DatabaseConstants; import com.newsblur.domain.Story; +import com.newsblur.util.StoryUtils; + +import java.util.Date; public class FeedItemViewBinder implements ViewBinder { @@ -68,7 +71,10 @@ public class FeedItemViewBinder implements ViewBinder { } else if (TextUtils.equals(columnName, DatabaseConstants.STORY_TITLE)) { ((TextView) view).setText(Html.fromHtml(cursor.getString(columnIndex))); return true; - } + } else if (TextUtils.equals(columnName, DatabaseConstants.STORY_DATE)) { + ((TextView) view).setText(StoryUtils.formatShortDate(new Date(cursor.getLong(columnIndex)))); + return true; + } return false; } diff --git a/clients/android/NewsBlur/src/com/newsblur/view/SocialItemViewBinder.java b/clients/android/NewsBlur/src/com/newsblur/view/SocialItemViewBinder.java index 78bcaab94..608193821 100644 --- a/clients/android/NewsBlur/src/com/newsblur/view/SocialItemViewBinder.java +++ b/clients/android/NewsBlur/src/com/newsblur/view/SocialItemViewBinder.java @@ -15,6 +15,9 @@ import com.newsblur.activity.NewsBlurApplication; import com.newsblur.database.DatabaseConstants; import com.newsblur.domain.Story; import com.newsblur.util.ImageLoader; +import com.newsblur.util.StoryUtils; + +import java.util.Date; public class SocialItemViewBinder implements ViewBinder { @@ -72,7 +75,10 @@ public class SocialItemViewBinder implements ViewBinder { } else if (TextUtils.equals(columnName, DatabaseConstants.STORY_TITLE)) { ((TextView) view).setText(Html.fromHtml(cursor.getString(columnIndex))); return true; - } + } else if (TextUtils.equals(columnName, DatabaseConstants.STORY_DATE)) { + ((TextView) view).setText(StoryUtils.formatShortDate(new Date(cursor.getLong(columnIndex)))); + return true; + } return false; } From 797babaf582c486e44d1265c99604366947929b0 Mon Sep 17 00:00:00 2001 From: Mark Anderson Date: Thu, 6 Feb 2014 22:40:40 +0000 Subject: [PATCH 3/4] Delete debug logging --- .../src/com/newsblur/fragment/ReadingItemFragment.java | 3 --- 1 file changed, 3 deletions(-) diff --git a/clients/android/NewsBlur/src/com/newsblur/fragment/ReadingItemFragment.java b/clients/android/NewsBlur/src/com/newsblur/fragment/ReadingItemFragment.java index e84ad3e1d..3c347388b 100644 --- a/clients/android/NewsBlur/src/com/newsblur/fragment/ReadingItemFragment.java +++ b/clients/android/NewsBlur/src/com/newsblur/fragment/ReadingItemFragment.java @@ -15,7 +15,6 @@ import android.support.v4.app.DialogFragment; import android.support.v4.app.Fragment; import android.text.Html; import android.text.TextUtils; -import android.util.Log; import android.view.LayoutInflater; import android.view.View; import android.view.View.OnClickListener; @@ -34,7 +33,6 @@ import com.newsblur.domain.UserDetails; import com.newsblur.network.APIManager; import com.newsblur.network.SetupCommentSectionTask; import com.newsblur.network.domain.StoryTextResponse; -import com.newsblur.util.AppConstants; import com.newsblur.util.DefaultFeedView; import com.newsblur.util.FeedUtils; import com.newsblur.util.ImageLoader; @@ -311,7 +309,6 @@ public class ReadingItemFragment extends Fragment implements ClassifierDialogFra itemTitle.setText(Html.fromHtml(story.title)); itemDate.setText(StoryUtils.formatLongDate(story.date)); - Log.d("mark", story.longDate); if (!TextUtils.isEmpty(story.authors)) { itemAuthors.setText("• " + story.authors); From 3f5b94c967069aca7891288363e37d2176891aa4 Mon Sep 17 00:00:00 2001 From: Mark Anderson Date: Mon, 10 Feb 2014 21:05:52 +0000 Subject: [PATCH 4/4] Use ThreadLocals for data formats in StoryUtils --- .../src/com/newsblur/util/StoryUtils.java | 53 ++++++++++++++----- 1 file changed, 41 insertions(+), 12 deletions(-) diff --git a/clients/android/NewsBlur/src/com/newsblur/util/StoryUtils.java b/clients/android/NewsBlur/src/com/newsblur/util/StoryUtils.java index e9c0749f1..dfce30cdf 100644 --- a/clients/android/NewsBlur/src/com/newsblur/util/StoryUtils.java +++ b/clients/android/NewsBlur/src/com/newsblur/util/StoryUtils.java @@ -9,11 +9,40 @@ import java.util.Date; */ public class StoryUtils { - private static final SimpleDateFormat todayLongFormat = new SimpleDateFormat("MMMM d"); - private static final SimpleDateFormat monthLongFormat = new SimpleDateFormat("EEEE, MMMM d"); - private static final SimpleDateFormat yearLongFormat = new SimpleDateFormat("yyyy"); - private static final SimpleDateFormat twelveHourFormat = new SimpleDateFormat("h:mma"); - private static final SimpleDateFormat shortDateFormat = new SimpleDateFormat("d MMM yyyy"); + private static final ThreadLocal todayLongFormat = new ThreadLocal() { + @Override + protected SimpleDateFormat initialValue() { + return new SimpleDateFormat("MMMM d"); + } + }; + + private static final ThreadLocal monthLongFormat = new ThreadLocal() { + @Override + protected SimpleDateFormat initialValue() { + return new SimpleDateFormat("EEEE, MMMM d"); + } + }; + + private static final ThreadLocal yearLongFormat = new ThreadLocal() { + @Override + protected SimpleDateFormat initialValue() { + return new SimpleDateFormat("yyyy"); + } + }; + + private static final ThreadLocal twelveHourFormat = new ThreadLocal() { + @Override + protected SimpleDateFormat initialValue() { + return new SimpleDateFormat("h:mma"); + } + }; + + private static final ThreadLocal shortDateFormat = new ThreadLocal() { + @Override + protected SimpleDateFormat initialValue() { + return new SimpleDateFormat("d MMM yyyy"); + } + }; public static String formatLongDate(Date storyDate) { @@ -27,16 +56,16 @@ public class StoryUtils { if (storyDate.getTime() > midnightToday.getTime()) { // Today, January 1st 00:00 - return "Today, " + todayLongFormat.format(storyDate) + getDayOfMonthSuffix(month) + " " + twelveHourFormat.format(storyDate); + return "Today, " + todayLongFormat.get().format(storyDate) + getDayOfMonthSuffix(month) + " " + twelveHourFormat.get().format(storyDate); } else if (storyDate.getTime() > midnightYesterday.getTime()) { // Yesterday, January 1st 00:00 - return "Yesterday, " + todayLongFormat.format(storyDate) + getDayOfMonthSuffix(month) + " " + twelveHourFormat.format(storyDate); + return "Yesterday, " + todayLongFormat.get().format(storyDate) + getDayOfMonthSuffix(month) + " " + twelveHourFormat.get().format(storyDate); } else if (storyDate.getTime() > beginningOfMonth.getTime()) { // Monday, January 1st 00:00 - return monthLongFormat.format(storyDate) + getDayOfMonthSuffix(month) + " " + twelveHourFormat.format(storyDate); + return monthLongFormat.get().format(storyDate) + getDayOfMonthSuffix(month) + " " + twelveHourFormat.get().format(storyDate); } else { // Monday, January 1st 2014 00:00 - return monthLongFormat.format(storyDate) + getDayOfMonthSuffix(month) + " " + yearLongFormat.format(storyDate) + " " + twelveHourFormat.format(storyDate); + return monthLongFormat.get().format(storyDate) + getDayOfMonthSuffix(month) + " " + yearLongFormat.get().format(storyDate) + " " + twelveHourFormat.get().format(storyDate); } } @@ -83,13 +112,13 @@ public class StoryUtils { if (storyDate.getTime() > midnightToday.getTime()) { // 00:00 - return twelveHourFormat.format(storyDate); + return twelveHourFormat.get().format(storyDate); } else if (storyDate.getTime() > midnightYesterday.getTime()) { // Yesterday, 00:00 - return "Yesterday, " + twelveHourFormat.format(storyDate); + return "Yesterday, " + twelveHourFormat.get().format(storyDate); } else { // 1 Jan 2014, 00:00 - return shortDateFormat.format(storyDate) +", " + twelveHourFormat.format(storyDate); + return shortDateFormat.get().format(storyDate) +", " + twelveHourFormat.get().format(storyDate); } } }