简单的日期格式会提供错误的时间信息

时间:2018-10-09 06:51:30

标签: android date time simpledateformat

我发现这给出了错误的日期。但是我怎么解决不了。请有人帮我。 我是android开发的新手。 预先感谢;

字符串时间戳=“ 1538970640”;

SimpleDateFormat formatter = new SimpleDateFormat("dd MMM 'at' hh:mm a z" );
String dateString = formatter.format(new Date(Long.parseLong(timestamp)));

这将返回:

19 Jan at 01:29 AM GMT+06:oo

但是应该是:

8 Oct at 9:50 AM GMT+06:00

2 个答案:

答案 0 :(得分:2)

java.util.Date构造函数自时期以来接受毫秒,而不接受秒:

  

分配一个Date对象,并将其初始化为表示自标准基准时间(即“纪元”)以来的指定毫秒数,即格林尼治标准时间1970年1月1日。

以下使用ms的代码正在工作:

String timestamp = "1538970640000";   // use ms NOT s
SimpleDateFormat formatter = new SimpleDateFormat("dd MMM 'at' hh:mm a z" );
String dateString = formatter.format(new Date(Long.parseLong(timestamp)));

08 Oct at 05:50 AM CEST

Demo

您面临的部分问题是您的日期格式省略了年份部分,而实际上是1970年。

答案 1 :(得分:0)

java.time和ThreeTenABP

我建议您使用现代Java日期和时间API java.time进行日期和时间工作。

    DateTimeFormatter timestampFormatter = new DateTimeFormatterBuilder()
            .appendValue(ChronoField.INSTANT_SECONDS)
            .toFormatter();
    DateTimeFormatter targetFormatter
            = DateTimeFormatter.ofPattern("d MMM 'at' h:mm a z", Locale.ENGLISH);

    String timestamp = "1538970640";
    ZonedDateTime dateTime = timestampFormatter.parse(timestamp, Instant.FROM)
            .atZone(ZoneId.systemDefault());
    String dateString = dateTime.format(targetFormatter);

    System.out.println(dateString);

输出为(当时区设置为GMT + 06:00时,这不是真正的时区):

10月8日,格林尼治标准时间+06:00 9:50

不过,我对将日期和时间从一种字符串格式转换为另一种字符串并不满意。在您的应用中,您不应将日期和时间当作字符串来处理,而应将其作为正确的日期和时间对象来处理,例如InstantZonedDateTime。当您从某处(服务器?)获取字符串时,首先将其解析为日期时间对象。仅在需要向用户提供字符串输出时,例如,将日期和时间格式化为用户所在时区中的字符串。

也就是说,java.time仅使用两个格式化程序执行转换。无需先解析为低级long

还有两点:

  • 给输出格式化程序一个区域设置来控制所使用的语言。由于AM和PM几乎不使用英语以外的其他语言,因此我认为Locale.ENGLISH可能是合适的。您决定。
  • 由于您希望使用8 Oct at 9:50 AM GMT+06:00,所以在每月的某天只使用一个d,而在时钟小时只使用一个h。如果数字超过9,则仍将输出两位数字,例如10 Oct at 11:50 AM GMT+06:00

您的代码出了什么问题?

您的数字1538970640(10位数字)表示自纪元以来的。这是Unix时间戳的经典定义。您使用的Date构造函数自时代起便期望毫秒。对于过时的Java日期和时间类和方法,这是典型的。自纪元以来的这些毫秒数通常为13位数字。如您所见,现代Java日期和时间类在这里对秒的支持更好。

问题:java.time是否不需要Android API级别26?

java.time在较新和较旧的Android设备上均可正常运行。它只需要至少 Java 6

  • 在Java 8和更高版本以及更新的Android设备(来自API级别26)中,内置了现代API。在这种情况下,请使用方法引用Instant.FROM代替常量Instant::from
  • 在非Android Java 6和7中,获得ThreeTen Backport,这是现代类的backport(JSR 310的ThreeTen;请参见底部的链接)。
  • 在旧版Android上,请使用Android版的ThreeTen Backport。称为ThreeTenABP。并确保使用子包从org.threeten.bp导入日期和时间类。

链接