服务器上的格式化日期来自REST API的响应不起作用

时间:2018-02-15 12:21:03

标签: java android datetime simpledateformat

我有一个从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"

2 个答案:

答案 0 :(得分:0)

您想要的格式是

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

最后一个Z代表&#34;零小时偏移&#34;也被称为&#34;祖鲁时间&#34; (UTC)。

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

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

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

答案 1 :(得分:0)

  

这是我从formatDate I / dateError :: Unparseable日期得到的错误:“1988-11-09T00:00:00Z”(偏移19处)

该日期时间字符串在第二个字符串上没有小数(并且没有小数点)。偏移19是Z所在的位置,小数点位于格式模式字符串中。这会导致您的例外。

现代Java日期和时间API

java.time将轻松解决您的问题:

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

你可能会惊讶的是,第一行表示字符串中的日期为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上使用Android版的ThreeTen Backport。它被称为ThreeTenABP。并确保使用子包从org.threeten.bp导入日期和时间类。

链接