【问题标题】:Format Date on Server Response from REST API not working来自 REST API 的服务器响应格式日期不起作用
【发布时间】:2018-07-26 04:57:01
【问题描述】:

我有一个从 REST 服务器获取数据的方法。该方法以“2017-08-14T17:45:16.24Z”的格式返回日期。我还写了一个方法,以“dd/MM/yyyy”的顺序格式化日期。这很有效,但是当我尝试从服务器格式化日期并将其设置为 Edittext 时,它不起作用。这表明我在服务器响应中格式化日期的方法不起作用。我格式化日期的方法如下:

private String formatDate(String dateString) {
    try {
        SimpleDateFormat sd = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS" );
        Date d = sd.parse(dateString);
        sd = new SimpleDateFormat("dd/MM/yyyy");
        return sd.format(d);
    } catch (ParseException e) {
    }
    return "";
}

下面的这个方法从服务器获取日期并格式化日期并将日期设置为编辑文本。

public void getProfile() {

    Retrofit retrofit = RetrofitClient.getClient(authUser.getToken());
    APIService mAPIService = retrofit.create(APIService.class);

    mAPIService.getProfile("Bearer " + authUser.getToken()).enqueue(new Callback<Profile>() {
        @Override
        public void onResponse(Response<Profile> response, Retrofit retrofit) {
            if(response.isSuccess()) {
                try {
                    String loginSuccess = response.body().getSuccess();
                    if (loginSuccess.equals("true")) {
                        id_name.setText(response.body().getData().getName());
                        id_email.setText(response.body().getData().getEmail());
                        phone_input_layout.setText(response.body().getData().getPhoneNumber());
                        id_gender.setText(response.body().getData().getGender());
                        String dateOfBirth = response.body().getData().getDateOfBirth();
                        id_date_of_birth.setText(formatDate(dateOfBirth));
                        //updateLabel(dateOfBirth);
                        id_residential_address.setText(response.body().getData().getResidentialAddress());
                        if (response.body().getData().getEmploymentStatus().equals("Student")) {
                            id_nss_number.setVisibility(View.VISIBLE);
                            maximum_layout.setVisibility(View.INVISIBLE);
                            extended_layout.setVisibility(View.INVISIBLE);
                        } else if (response.body().getData().getEmploymentStatus().equals("Employed")) {
                            maximum_layout.setVisibility(View.VISIBLE);
                            extended_layout.setVisibility(View.INVISIBLE);
                            id_nss_number.setVisibility(View.INVISIBLE);
                            id_type.setText(response.body().getData().getIdType());
                            id_number.setText(response.body().getData().getIdNumber());
                            id_expiry_date.setText(response.body().getData().getIdExpiryDate());
                        }


                    } else {
                        String message = response.body().getMessage();
                        Log.e("getProfileError", message);
                        Toast.makeText(UserProfileActivity.this, message, Toast.LENGTH_LONG).show();
                    }
                }catch (Exception e){
                    Toast.makeText(getApplicationContext(), "Some fields are empty", Toast.LENGTH_SHORT).show();
                    e.printStackTrace();
                }

            }


        }

        @Override
        public void onFailure(Throwable throwable) {
            Log.e("getProfileError", throwable.getMessage());
            Toast.makeText(UserProfileActivity.this, "Unable to Login, Please Try Again", Toast.LENGTH_LONG).show();
        }
    });
}

这是我从日期格式中得到的例外

I/dateError:: Unparseable date: "1988-11-09T00:00:00Z"

【问题讨论】:

  • catch (ParseException e) { } 隐藏异常绝不是一个好主意,尤其是如果出现问题,并且您不知道是什么或为什么。另外,显示您的实际代码:您发布的代码永远不会编译,因为您有一个 dateOfBirth 的双重声明
  • @Stultuske 我更新了我的问题
  • 你得到了什么异常?
  • 我也不例外,但是编辑文本没有显示任何数据@ZaidMirza
  • @OleV.V.这是我从日期格式 I/dateError:: Unparseable date: "1988-11-09T00:00:00Z" (at offset 19) 中得到的异常

标签: java android datetime simpledateformat


【解决方案1】:

你想要的格式是

yyyy-MM-dd'T'HH:mm:ss.SSS'Z' 

最后一个 Z 代表“零小时偏移”,也称为“祖鲁时间”(UTC)。

SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'", Locale.US);
format.setTimeZone(TimeZone.getTimeZone("UTC"));

使用此UTC 时区,转换后的小时将为20H

如果您不添加时区,您将获得预期小时 17H

【讨论】:

  • 我仍然遇到同样的问题。这并不能解决我的问题,但最好的方式来格式化我的日期
  • 这不会按预期工作,因为使用“S”模式字符会将值映射到毫秒数。输入示例(“16.24”)将被解析为 16 秒和 24 毫秒,例如16.024 秒,而不是预期的 16.24 秒。
  • 我们假设预期的输入总是相同的。此外,如果您尝试仅将 16.24 解析为该格式,您肯定会遇到异常。
  • @RoxanneAkorley 我尝试使用我发布的模式来格式化您的日期并且它有效。输出:Mon Aug 14 20:45:16 EEST 2017。现在取决于您所在地区的时区或预期时区。
  • @FlorescuCătălin 但由于某种原因,在从服务器获取日期的方法中未调用格式化日期的方法。编辑文本不显示任何数据。
【解决方案2】:

这是我从 formatDate I/dateError:: Unparseable date: "1988-11-09T00:00:00Z" 得到的错误(偏移量 19)

该日期时间字符串的秒数没有小数点(也没有小数点)。偏移量 19 是 Z 所在的位置,以及格式模式字符串中小数点所在的位置。这会导致您的异常。

java.time,现代 Java 日期和时间 API,将轻松解决您的问题:

private static final DateTimeFormatter dateFormatter
        = DateTimeFormatter.ofPattern("dd/MM/yyyy");

private static String formatDate(String dateString) {
    return Instant.parse(dateString)
            .atZone(ZoneId.of("Australia/Queensland"))
            .format(dateFormatter);
}

这将在秒上使用和不使用小数:

    System.out.println(formatDate("2017-08-14T17:45:16.24Z"));
    System.out.println(formatDate("1988-11-09T00:00:00Z"));

打印出来

15/08/2017
09/11/1988

当字符串中的 day-of-month 为 14 时,第一行表示月份的 15 日,您可能会感到惊讶。这是因为当 UTC 时间是 17:45 时,已经是澳大利亚的第二天.我想您希望用户所在时区中的这一天。因此,如果它不是澳大利亚/昆士兰,请替换您想要的时区。如果您确实需要 UTC 日期,请使用此行而不是 atZone 调用:

            .atOffset(ZoneOffset.UTC) 

这将确保您获得与字符串中相同的日期。

作为一个细节,上面的代码也正确地解析了你的 0.24 秒。 SimpleDateFormat 将 24 理解为 24 毫秒,所以你得到了 0.024 秒,这有点不准确。另一个细节,我声明了你的方法static,没必要,但我们也可以。

问题:我可以在 Android 上使用 java.time 吗?

是的,您可以在 Android 上使用 java.time。它只需要至少 Java 6

  • 在 Java 8 及更高版本以及更新的 Android 设备上,内置了现代 API。
  • 在 Java 6 和 7 中,获取 ThreeTen Backport,即新类的后向端口(对于 JSR 310,ThreeTen;请参阅底部的链接)。
  • 在较旧的 Android 上使用 ThreeTen Backport 的 Android 版本。它被称为 ThreeTenABP。并确保从 org.threeten.bp 导入日期和时间类以及子包。

链接

【讨论】:

  • 我如何将它与我的日期格式方法结合起来......抱歉问这个新手问题
  • 不客气。请参阅我的编辑:您只需将方法中的代码替换为我的。我还将格式化程序移到方法之外,并在答案中添加了一些其他细节。
猜你喜欢
  • 1970-01-01
  • 2016-01-17
  • 2019-03-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多