将当前时间转换为PST并与另一个日期进行比较

时间:2018-03-29 12:24:07

标签: java android date simpledateformat

在我的一个模块中,我必须实现以下目标。

我在 yyyy-MM-dd' HH:mm:ss' Z' 格式中从服务器获取日期。我必须在PST中转换这个日期和当前日期,然后以小时/分钟/秒显示这两者之间的差异。

为了将当前时间转换为PST,我编写了以下代码

        Calendar cal = Calendar.getInstance(TimeZone.getTimeZone("America/Los_Angeles"));

        Date currentLocalTime = cal.getTime();
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'", LocaleManager.getLocale());


        TimeZone tz = TimeZone.getTimeZone("America/Los_Angeles");
        format.setTimeZone(tz);
        String localTime = format.format(currentLocalTime);
        Date currentDate = format.parse(localTime);

这里当前时间被转换为字符串(代码中的 localTime ),但是当我解析此字符串以获取Date对象时,我只在时区中获取日期。

我的问题是格式化程序是否在不同时区格式化日期然后解析为什么同一日期没有转换为Date对象?

有没有其他方法可以在两个日期(当前和从服务器收到一次)之间获得差异,以毫秒为单位?

2 个答案:

答案 0 :(得分:2)

这里有很多问题,让我们看看:

首先,您应该解析整个字符串,包括UTC信息。然后你使用另一个格式化程序将其转换为另一个时区:

// parse the date/time with Z
SimpleDateFormat parser = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssXXX");
Date date = parser.parse("2018-03-21T10:00:00Z");

// convert to another timezone
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssXXX");
TimeZone tz = TimeZone.getTimeZone("America/Los_Angeles");
format.setTimeZone(tz);
String formattedDate = format.format(date); // 2018-03-21T03:00:00-07:00

但我建议你使用threeten backport - 看看如何在Android here中使用它(或者只使用 java.time 类,如果你的API水平有它)。

此API更好更容易:

// parse input
Instant instant = Instant.parse("2018-03-21T10:00:00Z");

// convert to timezone
ZonedDateTime zdt = instant.atZone(ZoneId.of("America/Los_Angeles"));

DateTimeFormatter fmt = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ssXXX");
System.out.println(zdt.format(fmt)); // 2018-03-21T03:00:00-07:00

答案 1 :(得分:1)

TL;博士

切勿使用DateCalendarSimpleDateFormat类。

相反,请使用 java.time 类。

ChronoUnit.MILLISECONDS.between( 
    Instant.parse( "2018-01-23T12:34:56Z" )  , 
    Instant.now() 
)

详细

Answer by QPS是正确的。

  

有没有其他方法可以在两个日期(当前和从服务器收到一次)之间获得差异,以毫秒为单位?

是的,还有另一种方法,使用现代的 java.time 类。

ISO 8601

您的输入采用标准ISO 8601格式。在解析/生成字符串时, java.time 类默认使用这些标准格式。因此无需指定格式化模式。

最后ZZulu的缩写,表示UTC。不要像在你的示例代码中那样忽略这一点。

Instant

Instant类表示UTC时间轴中的一个时刻,分辨率为纳秒。

String input = "2018-01-23T12:34:56Z" ;
Instant instant = Instant.parse( input ) ;

您在America/Los_Angeles中尝试从UTC调整到分区时间是不必要的,也无关紧要。将时区应用于UTC值不会更改其在时间轴上的位置,只会更改挂钟时间。因此,一对UTC之间的经过时间与应用时区之后经过的时间相同。

经过时间

要计算已用时间,请使用Duration

Duration d = Duration.between( instant , otherInstant ) ;

我建议使用Duration而不是仅仅数毫秒来跟踪已用时间。但如果您坚持总毫秒数,请使用ChronoUnit枚举。

long millisElapsed = ChronoUnit.MILLISECONDS.between( instant , otherInstant ) ;

永远不要使用设计不当的遗留类,例如DateCalendarSimpleDateFormat。只使用他们的替换 java.time 类,因为它们更干净,更简单,并且设计得很好。

相关问题