Banana
Banana

Reputation: 2443

Displaying Date and Time separately from a String in localized format in Android

I know there are a lot of similar questions, and so far some of the solutions that I tried, but did not fully answer my question are: this, this, this, this, this, this, this, this, this, this, and a lot more.

I am making an app where I get user's post from server and sort it by date, and also displaying date and time it was created in the post. Right now I have a working solution, and I am doing it by converting string from a server in this format yyyy-MM-dd HH:mm:ss to my custom date and time format.

The problem is: I do not want to hard code a format, but instead I want to display it in the format that user phone has, and do it separately for both date and time. By the local format of the phone I mean - am-pm/24 hour format, and same for the date format - dd-MM-YY, or MM-dd-YYYY, or dd-MM, etc.

So far I have looked through a lot of solutions, most of which have that hardcoded format. I try to avoid, but I think that additional problem is that I want to separate date and time from datetime string. The other problem is that the transformation is not separate for date and time.

In short I want to format 2017-07-04 12:00:00 to 04 Jul 2017 and 12:00 PM, or 07/04/17 and 12:00. ie. Separating date and time into two strings, and displaying them in localized phone format.

My Adapter:

 public class UserPostsAdapter extends RecyclerView.Adapter<UserPostsAdapter.PostsViewHolder> {

     private List<UserPosts> postItems;
     private Context context;
     private static final String TAG = UserPosts.class.getSimpleName();

     class PostsViewHolder extends RecyclerView.ViewHolder {
    TextView userPostsTitle, userPostsDate, userPostsTime, userPost, textViewStars, textViewComments;
         ImageView imageViewDisplayComments, imageViewReply, imageViewCommentStar;
         String pCcontactId, postId;

         PostsViewHolder(View itemView) {
             super(itemView);

             userPostsTitle = (TextView) itemView.findViewById(R.id.userPostsTitle);
             userPostsDate = (TextView) itemView.findViewById(R.id.userPostsDate);
             userPostsTime = (TextView) itemView.findViewById(R.id.userPostsTime);
             userPost = (TextView) itemView.findViewById(R.id.userPost);

             textViewStars = (TextView) itemView.findViewById(R.id.textViewStars);
             textViewComments = (TextView) itemView.findViewById(R.id.textViewComments);

             imageViewCommentStar = (ImageView) itemView.findViewById(R.id.imageViewCommentStar);
             imageViewDisplayComments = (ImageView) itemView.findViewById(R.id.imageViewDisplayComments);
             imageViewReply = (ImageView) itemView.findViewById(R.id.imageViewReply);
         }
     }

     public UserPostsAdapter(List<UserPosts> postsList, Context context) {
         this.postItems = postsList;
         this.context = context;
     }

     @Override
     public UserPostsAdapter.PostsViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
         View itemView = LayoutInflater.from(parent.getContext()).inflate(R.layout.card_user_post, parent, false);

         return new UserPostsAdapter.PostsViewHolder(itemView);
     }

     @Override
     public void onBindViewHolder(final UserPostsAdapter.PostsViewHolder holder, int position) {
         final UserPosts post = postItems.get(position);

         SQLiteHandler db = new SQLiteHandler(context.getApplicationContext());
         HashMap<String, String> user = db.getUserDetails();
         final String currentUserId = user.get("uid");

         if (post.getTitle() != null && !post.getTitle().isEmpty()) {
             holder.userPostsTitle.setText(post.getTitle());
         } else {
             holder.userPostsTitle.setVisibility(View.GONE);
         }
         holder.userPostsDate.setText(convertDate(postItems.get(position).getCreatedDate()));
         holder.userPostsTime.setText(convertTime(postItems.get(position).getCreatedTime()));
         holder.userPost.setText(post.getPostedText());
         if (Integer.parseInt(post.getLikesNumber()) > 0) {
             holder.textViewStars.setText(post.getLikesNumber());
         }
         holder.textViewComments.setText(post.getCommentsNumber());

         holder.pCcontactId = post.getUserId();
         final String postId = holder.postId = post.getId();

         holder.imageViewDisplayComments.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {

            }
     });

     ***TRANSFORMING DATE AND TIME SEPARATELY TO CUSTOM FORMAT***
-----------------------------------------------------------------------------
private String convertDate(String time) {

    SimpleDateFormat dateFormatReceived = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.getDefault());
    SimpleDateFormat dateFormatConverted = new SimpleDateFormat("dd MMM yyyy", Locale.getDefault());
    java.util.Locale.getDefault());

    SimpleDateFormat(datePattern);

      DateFormat.getTimeInstance(DateFormat.SHORT).parse(mTimeDisplay.getText().toString());

    java.util.Date date = null;

    try {
        date = dateFormatReceived.parse(time);
    } catch (ParseException e) {
        e.printStackTrace();
    }

    return dateFormatConverted.format(date);
}

private String convertTime(String time) {

    SimpleDateFormat timeFormatReceived = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.getDefault());
    SimpleDateFormat timeFormatConverted = new SimpleDateFormat("HH:mm", Locale.getDefault());

    java.util.Date date = null;

    try {
        date = timeFormatReceived.parse(time);
    } catch (ParseException e) {
        e.printStackTrace();
    }

    return timeFormatConverted.format(date);
}
-----------------------------------------------------------------------------
     @Override
     public int getItemCount() {
         return postItems.size();
     }
 }

Upvotes: 1

Views: 1153

Answers (3)

from56
from56

Reputation: 4127

First I strongly recommend that you save dates as long(1) and not as String It would simplify your code a lot. You can handle dates and display them in the current Locale without having a single formatting string like "yyyy_MM_dd" in your code.

Then to get the Date or Time in current Locale just :

String dateLocalizedStr = DateFormat.getDateInstance().format(myDate);
String timeLocalizedStr = DateFormat.getTimeInstance().format(myDate);

You can change to long or short format passing an argument to getDateInstance() or getTimenstance()

(1) as long or Date because Date internally is a long.

Upvotes: 3

Usman Rana
Usman Rana

Reputation: 2142

Let me explain in steps:

  1. You can get to know default date format of device.
  2. You must know the format of date that the server is sending to you.
  3. Make a instance of calendar and set the dateTime as it is coming from server.
  4. Then you can format date and time as following (input to SimpleDateFormat is the format that you determined in step 1):

Code:

String formattedDate = new SimpleDateFormat("yyyy-MM dd", Locale.getDefault())
        .format(Calendar.getInstance()‌​.getTime()); 

String formattedTime = new SimpleDateFormat("HH:mm:ss", Locale.getDefault())
        .format(Calendar.getInstance().g‌​etTime()); 

Upvotes: 2

Anonymous
Anonymous

Reputation: 86173

Usman Rana’s answer is correct and well explained. What I want to contribite is the modern answer since the replacements for SimpleDateFormat and Date have been out for years now.

    String dateTimeString = "2017-07-04 12:00:00";
    LocalDateTime dateTime = LocalDateTime.parse(dateTimeString,
            DateTimeFormatter.ofPattern("uuuu-MM-dd HH:mm:ss"));
    String formattedDate 
            = dateTime.format(DateTimeFormatter.ofLocalizedDate(FormatStyle.MEDIUM));
    System.out.println(formattedDate);
    String formattedTime 
            = dateTime.format(DateTimeFormatter.ofLocalizedTime(FormatStyle.MEDIUM));
    System.out.println(formattedTime);

On my computer this prints

04-07-2017
12:00:00

And the idea is exactly what you asked for, these are the date format and the time format set up on my computer, so each device will print the date and the time in its own preferred way.

Beware that there’s a potential time zone issue here. If you want to display the server’s time on the user’s phone no matter where in the world the user is taking her/his phone, you should be fine. If you wanted to use the phone’s time zone, you need to convert the date-time first, and for that you need to know the server time zone. Or probably better, the server would need to send the date and time in UTC.

The modern Java date and time API that I am using will come natively to Android Java. Until that happens, you will need the ThreeTenABP, the backport to Android Java 7. See How to use ThreeTenABP in Android Project.

Upvotes: 4

Related Questions