将当前时间转换为 PST 并与另一个日期进行比较
Convert current time to PST and compare with another date
在我的一个模块中,我必须实现以下目标。
我正在从服务器获取 yyyy-MM-dd'T'HH:mm:ss'Z' 格式的日期。我必须在 PST 中转换此日期和当前日期,然后在 hours/mins/seconds.
中显示这两者之间的差异
为了将当前时间转换为太平洋标准时间,我编写了以下代码
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 对象?
是否有任何其他方法以毫秒为单位获取两个日期(当前日期和曾经从服务器接收到的日期)之间的差异?
这里有很多问题,让我们看看:
-
Z
means that the date/time is in UTC。当您创建 SimpleDateFormat
并将 Z
放在引号内 ('Z'
) 时,您将其视为文字(字母 Z 本身),所以不要这样做
java.util.Date
class没有时区。 When you print it, it uses the JVM default timezone,但是 class 本身没有
所以首先你应该解析整个字符串,包括 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 - see how to use it in Android (或者只使用 java.time classes,如果您的 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
tl;博士
切勿使用 Date
、Calendar
或 SimpleDateFormat
classes.
而是使用 java.time classes.
ChronoUnit.MILLISECONDS.between(
Instant.parse( "2018-01-23T12:34:56Z" ) ,
Instant.now()
)
详情
是正确的。
Is there any other way to get difference between two dates (current and once received from server) in milliseconds?
是的,还有另一种方法,使用现代java.time classes.
ISO 8601
您输入的是标准 ISO 8601 格式。当 parsing/generating 字符串时,java.time classes 默认使用这些标准格式。因此无需指定格式模式。
最后的Z
是Zulu
的缩写,意思是UTC。不要像在示例代码中那样忽略它。
Instant
Instant
class 表示 UTC 时间轴中的一个时刻,精度为纳秒。
String input = "2018-01-23T12:34:56Z" ;
Instant instant = Instant.parse( input ) ;
您尝试从 UTC 调整到 America/Los_Angeles
中的分区时间是不必要且无关紧要的。将时区应用于 UTC 值不会更改其在时间轴上的位置,只会更改 wall-clock 时间。因此,一对 UTC 之间经过的时间与应用时区后经过的时间相同。
经过的时间
要计算经过的时间,请使用 Duration
。
Duration d = Duration.between( instant , otherInstant ) ;
我建议使用 Duration
而不是单纯的毫秒数来跟踪经过的时间。但如果你坚持总毫秒数,使用ChronoUnit
枚举。
long millisElapsed = ChronoUnit.MILLISECONDS.between( instant , otherInstant ) ;
切勿使用令人困惑的 poorly-designed 旧版 class,例如 Date
、Calendar
和 SimpleDateFormat
。只使用它们的替代品,java.time classes,因为它们更干净、更简单,并且 well-designed.
在我的一个模块中,我必须实现以下目标。
我正在从服务器获取 yyyy-MM-dd'T'HH:mm:ss'Z' 格式的日期。我必须在 PST 中转换此日期和当前日期,然后在 hours/mins/seconds.
中显示这两者之间的差异为了将当前时间转换为太平洋标准时间,我编写了以下代码
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 对象?
是否有任何其他方法以毫秒为单位获取两个日期(当前日期和曾经从服务器接收到的日期)之间的差异?
这里有很多问题,让我们看看:
-
Z
means that the date/time is in UTC。当您创建SimpleDateFormat
并将Z
放在引号内 ('Z'
) 时,您将其视为文字(字母 Z 本身),所以不要这样做 java.util.Date
class没有时区。 When you print it, it uses the JVM default timezone,但是 class 本身没有
所以首先你应该解析整个字符串,包括 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 - see how to use it in Android
这个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
tl;博士
切勿使用 Date
、Calendar
或 SimpleDateFormat
classes.
而是使用 java.time classes.
ChronoUnit.MILLISECONDS.between(
Instant.parse( "2018-01-23T12:34:56Z" ) ,
Instant.now()
)
详情
Is there any other way to get difference between two dates (current and once received from server) in milliseconds?
是的,还有另一种方法,使用现代java.time classes.
ISO 8601
您输入的是标准 ISO 8601 格式。当 parsing/generating 字符串时,java.time classes 默认使用这些标准格式。因此无需指定格式模式。
最后的Z
是Zulu
的缩写,意思是UTC。不要像在示例代码中那样忽略它。
Instant
Instant
class 表示 UTC 时间轴中的一个时刻,精度为纳秒。
String input = "2018-01-23T12:34:56Z" ;
Instant instant = Instant.parse( input ) ;
您尝试从 UTC 调整到 America/Los_Angeles
中的分区时间是不必要且无关紧要的。将时区应用于 UTC 值不会更改其在时间轴上的位置,只会更改 wall-clock 时间。因此,一对 UTC 之间经过的时间与应用时区后经过的时间相同。
经过的时间
要计算经过的时间,请使用 Duration
。
Duration d = Duration.between( instant , otherInstant ) ;
我建议使用 Duration
而不是单纯的毫秒数来跟踪经过的时间。但如果你坚持总毫秒数,使用ChronoUnit
枚举。
long millisElapsed = ChronoUnit.MILLISECONDS.between( instant , otherInstant ) ;
切勿使用令人困惑的 poorly-designed 旧版 class,例如 Date
、Calendar
和 SimpleDateFormat
。只使用它们的替代品,java.time classes,因为它们更干净、更简单,并且 well-designed.