1

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();
     }
 }
Banana
  • 2,435
  • 7
  • 34
  • 60
  • 1
    Did you check this: https://stackoverflow.com/questions/6981505/how-to-get-user-selected-date-format-in-android – Usman Rana Jul 04 '17 at 10:42
  • @UsmanRana Thank you for your answer Usman. I did try it, but it did not answer my question. What I want to do is get this string from server: `yyyy-MM-dd HH:mm:ss`, cut it into two strings: `yyyy-MM-dd` and `HH:mm:ss`, and format them bith separately into local format. – Banana Jul 04 '17 at 10:47
  • 1
    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): String formattedDate = new SimpleDateFormat("yyyy-MM-dd").format(Calendar.getInstance().getTime()); String formattedTime = new SimpleDateFormat("HH:mm:ss").format(Calendar.getInstance().getTime()); – Usman Rana Jul 04 '17 at 11:01
  • @UsmanRana Thanks for the solution, and reading my question before downvoting :) Can you answer this, so I can accept your answer :) Once again thanks for the help – Banana Jul 04 '17 at 11:05
  • 2
    Thanks for searching high and low beofre asking. I think one of the reasons you didn’t find a duplicate is that you are really asking at least two questions in one: (1) How to parse the date-time string from the server (2) how to format date and time using the device’s format settings. If you can, better to post two separate questions then. – Ole V.V. Jul 04 '17 at 11:48

3 Answers3

4

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.

Ole V.V.
  • 81,772
  • 15
  • 137
  • 161
  • Thank you for reading my question and for your reply :) I did look for a similar answers as Usman's and yours before, but couldn't find any. Hope this will help someone else as well. Thanks again :) – Banana Jul 04 '17 at 11:41
3

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.

from56
  • 3,976
  • 2
  • 13
  • 23
  • Thank you for your answer, since i was receiving all my data from server I thought it would be easier to save it as a string. – Banana Jul 04 '17 at 11:39
2

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()); 
Usman Rana
  • 2,067
  • 1
  • 21
  • 32