简体   繁体   English

Android-显示不同日期格式的月份名称

[英]Android - Displaying month name for different date formats

I have an app that displays dates and times in a localized format for different areas , that is - it shows a user dates and times based on his preference. 我有一个应用程序,它以不同区域的本地化格式显示日期和时间 ,即-根据用户的偏好显示用户的日期和时间。 But my issue is that it always displays numbers, ie yyyy.mm.dd , or mm/dd/yyy , or dd,mm,yyyy . 但是我的问题是,它总是显示数字,即yyyy.mm.ddmm / dd / yyydd,mm,yyyy What I would like to have is this: show date so that the day is a number, year is a number, but the month is displayed as a string, ie. 我想要的是:显示日期,以便日期是数字,年份是数字,但是月份显示为字符串,即。 Jan / Xin / Gen / Jān / Yan ... or 01 Jan 2018 / Jan 01 2018 / 2018 Jan 01 , and so on, but still keep the current local formatting. Jan / Xin / Gen /Jān/ Yan ...或2018年 1月1日 / 2018年1月1日/ 2018年1月1日,依此类推,但仍保持当前的本地格式。 I know that I could do that if I hardcode it like MMM, but I want it to change, depending on the localized format. 我知道,如果像MMM一样对其进行硬编码,我可以这样做,但是我希望根据本地化格式对其进行更改。

So basically this is my question: how can I display localized time, from a value I get from the server (yyyy-MM-dd HH: mm: ss), with month displayed as a three letter word, no matter what locale it uses ? 所以基本上这是我的问题: 如何从服务器获取的值(yyyy-MM-dd HH:mm:ss)中显示本地化时间,而无论使用哪种语言环境,月份都显示为三个字母的单词

I know this question sounds familiar, but so far I have tried a lot of answers, both on stack overflow, and other sources, but without any success. 我知道这个问题听起来很熟悉,但是到目前为止,我已经尝试了很多答案,无论是关于堆栈溢出还是其他原因,都没有成功。 Some of the things I have tried include: 1 / 2 / 3 / 4 / 5 / 6 ... but I couldn't make it work in my example. 有些我已经尝试的事情包括: 1 / 2 / 3 / 4 / 5 / 6 ......但我不能让它在我的示例工作。

My Adapter: 我的适配器:

public void onBindViewHolder(RestaurantsAdapter.RestaurantsViewHolder holder, int position) {
    // getting restaurant data for the row
    Restaurant restaurant = restaurant Items.get(position);

    holder.userName.setText(restaurant .getUserName());
    holder.date.setText(convertDate(restaurant .getDateTime())); //string dobiti u formatu, pretvoriti ga u localized i podijeliti na dva dijela
    holder.time.setText(convertTime(restaurant .getDateTime()));

    TextDrawable.IBuilder builder = TextDrawable.builder()
            .beginConfig()
            .withBorder(0)
            .toUpperCase()
            .endConfig()
            .roundRect(10);
    ColorGenerator generator = ColorGenerator.MATERIAL;
    int color = generator.getColor(restaurant.getUserId());
    TextDrawable textDrawable = builder.build(restaurant Items.get(position).getUserName().substring(0, 1), color);
    holder.thumbNail.setImageDrawable(textDrawable);

    Picasso.with(context)
            .load(AppConfig.URL_PROFILE_PHOTO + restaurant.getThumbnailUrl())
            .placeholder(textDrawable)
            .error(textDrawable)
            .transform(new RoundedTransform(12, 0))
            .fit()
            .centerCrop()
            .into(holder.thumbNail);
}

 private String convertDate(String time) {
    final DateFormat shortDateFormat = android.text.format.DateFormat.getDateFormat(context.getApplicationContext());

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

    java.util.Date date = null;

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

    return dateFormatConverted.format(date);
}

private String convertTime(String time) {
    final DateFormat shortTimeFormat = android.text.format.DateFormat.getTimeFormat(context.getApplicationContext());
    SimpleDateFormat timeFormatReceived = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.getDefault());
    SimpleDateFormat timeFormatConverted = new SimpleDateFormat(((SimpleDateFormat) shortTimeFormat).toPattern(), Locale.getDefault());

    java.util.Date date = null;

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

    return timeFormatConverted.format(date);
}

UPDATE: 更新:

I tried adding this to my solution: 我尝试将其添加到我的解决方案中:

 private String convertDate(String time) {
    final DateFormat shortDateFormat = android.text.format.DateFormat.getDateFormat(context.getApplicationContext());
    Calendar Now = Calendar.getInstance();
    Now.getDisplayName(Calendar.HOUR, Calendar.SHORT, Locale.getDefault());
    SimpleDateFormat dateFormatReceived = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.getDefault());
    SimpleDateFormat dateFormatConverted = new SimpleDateFormat(((SimpleDateFormat) shortDateFormat).toPattern(), Locale.getDefault());
    dateFormatConverted.getDisplayName(Calendar.HOUR, Calendar.SHORT, Locale.getDefault());
    java.util.Date date = null;

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

    return dateFormatConverted.format(date);
}

Please try to use getDisplayName(...) method 请尝试使用getDisplayName(...)方法

In order to get more information you had better go through this documentation 为了获得更多信息,您最好阅读文档


Editted 已编辑

More sufficiently you can try this way: 更充分地,您可以尝试这种方式:

int monthOfYear = Calendar.JULY; // 6
String monthName = new 
DateFormatSymbols(Locale.getDefault()).getShortMonths()[monthOfYear];

I think the following method will give you the date-time formatter you want. 我认为以下方法将为您提供所需的日期时间格式化程序。

public static DateTimeFormatter getLocalizedDateFormatter(Locale requestedLocale) {
    String formatPatternString = DateTimeFormatterBuilder.getLocalizedDateTimePattern(
            FormatStyle.SHORT, null, 
            Chronology.ofLocale(requestedLocale), requestedLocale);
    // if not already showing month name, modify so it shows abbreviated month name
    if (! formatPatternString.contains("MMM")) {
        formatPatternString = formatPatternString.replaceAll("M+", "MMM");
    }
    return DateTimeFormatter.ofPattern(formatPatternString, requestedLocale);
}

Test: 测试:

    Locale[] locales = { Locale.US, Locale.FRANCE, Locale.GERMANY,
            Locale.forLanguageTag("da-DK"), Locale.forLanguageTag("sr-BA") };
    LocalDate today = LocalDate.now(ZoneId.of("Europe/Sarajevo"));
    for (Locale currentLocale : locales) {
        DateTimeFormatter ldf = getLocalizedDateFormatter(currentLocale);
        System.out.format(currentLocale, "%-33S%s%n", 
                currentLocale.getDisplayName(), today.format(ldf));
    }

Output: 输出:

ENGLISH (UNITED STATES)          Dec/24/17
FRENCH (FRANCE)                  24/déc./17
GERMAN (GERMANY)                 24.Dez.17
DANSK (DANMARK)                  24-dec.-17
SERBIAN (BOSNIA AND HERZEGOVINA) 17-дец-24

JSR-310 also known as java.time JSR-310也称为java.time

You tried to use the long outdated and notoriously troublesome classes DateFormat and SimpleDateFormat . 您尝试使用过时且臭名昭著的类DateFormatSimpleDateFormat Instead I recommend you make it a habit to use JSR-310, the modern Java date and time API. 相反,我建议您养成使用现代Java日期和时间JSR-310的习惯。 So I do that in the method above. 所以我在上面的方法中做到了。

I don't think it was part of the question, but for the sake of completeness, parse the date-time string as follows. 我不认为这是问题的一部分,但是为了完整起见,请按以下方式解析日期时间字符串。 The formatter you get from my getLocalizedDateFormatter can be used for formatting a LocalDateTime and many other date-time types in addition to LocalDate . getLocalizedDateFormatter获得的格式化程序可用于格式化LocalDateTime和除LocalDate之外的许多其他日期时间类型。

    LocalDateTime ldt = LocalDateTime.parse("2017-12-24 22:51:34",
            DateTimeFormatter.ofPattern("uuuu-MM-dd HH:mm:ss"));
    String formattedDate = ldt.format(getLocalizedDateFormatter(Locale.UK));

Question: Can I use JSR-310 on Android? 问:我可以在Android上使用JSR-310吗?

Yes you can. 是的你可以。 It just requires at least Java 6 . 它至少需要Java 6

  • In Java 8 and later the new API comes built-in. 在Java 8和更高版本中,内置了新的API。
  • In Java 6 and 7 get the ThreeTen Backport, the backport of the new classes (ThreeTen for JSR 310). 在Java 6和7中,获取ThreeTen反向端口,即新类的反向端口(JSR 310的ThreeTen)。
  • On Android , use the Android edition of ThreeTen Backport. 在Android上 ,使用Android版本的ThreeTen Backport。 It's called ThreeTenABP. 它称为ThreeTenABP。

In the latter two cases, make sure to add the appropriate edition of the backport library to your project, use the links below, and to import the classes I use from org.threeten.bp and org.threeten.bp.format . 在后两种情况下,请确保将适当版本的backport库添加到您的项目中,使用下面的链接,并从org.threeten.bporg.threeten.bp.format导入我使用的类。

Links 链接

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM