我必须检查服务器和Android设备系统的时间差是否超过1小时。现在我从服务器上得到了以下字符串:
2020-08-24T11:50:18.613+0300
这些是我用于SimpleDateFormat的常量:
private static final String SYSTEM_FORMAT = "yyyy-MM-dd'T'HH:mm:ss.SSSZ"
问题是,当我尝试将字符串日期转换为日期类时,我得到了以下结果:
Mon Aug 24 13:50:18 GMT+05:00 2020
据我所知,05:00是因为它是在Android设备默认设置的时区。这就是我如何得到这个日期:
Locale locale = new Locale("ru","RU");
DateFormat df = new SimpleDateFormat(SYSTEM_FORMAT, locale);
df.setTimeZone(TimeZone.getTimeZone("Europe/Moscow"));
Date date = df.parse(serverDate);
正如你所看到的,即使将时区设置为3(莫斯科时间)也不会使我期望的日期。我知道我可以用字符串比较它,但要求是比较日期
在比较时间时,无需担心与UTC或时区的偏移。跨偏移量的比较进展顺利。
我正在使用java。时间,现代Java日期和时间API。让我们首先定义几个有用的常数:
private static final Duration TOLERANCE = Duration.ofHours(1);
private static final DateTimeFormatter serverFormatter = new DateTimeFormatterBuilder()
.append(DateTimeFormatter.ISO_LOCAL_DATE_TIME)
.appendPattern("XX")
.toFormatter();
现在我们可以做到:
String serverDateTimeString = "2020-08-24T11:50:18.613+0300";
OffsetDateTime serverTime = OffsetDateTime.parse(serverDateTimeString, serverFormatter);
System.out.println("Server time: " + serverTime);
ZoneId deviceTimeZone = ZoneId.of("Asia/Yekaterinburg");
OffsetDateTime deviceTime = OffsetDateTime.now(deviceTimeZone);
System.out.println("Device time: " + deviceTime);
if (deviceTime.isBefore(serverTime.minus(TOLERANCE)) || deviceTime.isAfter(serverTime.plus(TOLERANCE))) {
System.out.println("Difference between time on server and Android device system time more than 1 hour");
} else {
System.out.println("Difference between time on server and Android device system time 1 hour or less");
}
我已经使用了问题中的字符串,所以当我现在运行它时,代码片段告诉我们这两次之间有很大的差异时,我们不应该感到惊讶:
Server time: 2020-08-24T11:50:18.613+03:00
Device time: 2020-08-24T23:08:57.939565+05:00
Difference between time on server and Android device system time more than 1 hour
为了便于实验,我们还可以试着将设备时间设置为问题的时间:
OffsetDateTime deviceTime = OffsetDateTime.of(2020, 8, 24, 13, 50, 18, 0, ZoneOffset.ofHours(5));
Server time: 2020-08-24T11:50:18.613+03:00
Device time: 2020-08-24T13:50:18+05:00
Difference between time on server and Android device system time 1 hour or less
JAVA时间在旧的和新的Android设备上都能很好地工作。它至少需要Java6。
org.threeten.bp
导入日期和时间类。java.time
。 java.time
到Java6和7的Backport(用于JSR-310的Threeten)。 你没有真正的时区,而是一个偏移量。
要正确转换从服务器获取的String
,您应该使用java.time
而不是过时的java.util.Date
或java.util.日历
。
下面是一个根据您的情况使用合适类的示例(java.time.OffsetDateTime
):
public static void main(String[] args) {
String stringFromServer = "2020-08-24T11:50:18.613+0300";
OffsetDateTime timeFromServer = OffsetDateTime.parse(
stringFromServer,
DateTimeFormatter.ofPattern("uuuu-MM-dd'T'HH:mm:ss.SSSZ")
);
System.out.println(timeFromServer.format(
DateTimeFormatter.ofPattern("EEE MMM dd HH:mm:ss XXX uuuu", Locale.ENGLISH))
);
}
该文件的输出(使用模仿您发布的模式格式化的OffsetDateTime
)如下所示:
Mon Aug 24 11:50:18 +03:00 2020
您也可以使用ZoneDateTime
,但随后必须添加ZoneId
,ZoneId。关于(“欧洲/莫斯科”)
,很可能
可以使用已经创建的OffsetDateTime timeFromServer
这样做:
ZonedDateTime moscowTime = timeFromServer.atZoneSameInstant(ZoneId.of("Europe/Moscow"));
ZonedDateTime berlinTime = timeFromServer.atZoneSameInstant(ZoneId.of("Europe/Berlin"));
和系统。在没有特殊格式的情况下删除它们,可以得到以下几行:
2020-08-24T11:50:18.613+03:00[Europe/Moscow]
2020-08-24T10:50:18.613+02:00[Europe/Berlin]
请注意:由于有Android的API反脱脂,您可以在Android 26以下的API级别中使用Java8()功能。
看起来你对日期时间字符串中区域偏移的理解有一些差距。日期时间字符串2020-08-24T11:50:18.613 0300
表示它是0300小时
的区域偏移处的日期时间,即UTC
上相应的日期时间字符串将是2020-08-24T8:50:18.613 0000
。
注意java。util。日期
缺少时区和区域偏移信息。它只有自1970年1月1日00:00:00 UTC以来的毫秒数。打印java时。util。日期
使用SimpleDateFormat
的实例,将表示时区设置中日期时间的字符串打印到SimpleDateFormat
的实例中。您可以从以下示例中理解:
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;
import java.util.TimeZone;
public class Main {
public static void main(String[] args) throws ParseException {
// Parse the date-time string to java.util.Date
String serverDate = "2020-08-24T11:50:18.613+0300";
final String SYSTEM_FORMAT = "yyyy-MM-dd'T'HH:mm:ss.SSSZ";
DateFormat dfSource = new SimpleDateFormat(SYSTEM_FORMAT);
Date date = dfSource.parse(serverDate);
System.out.println(date);
// Get the date-time string for the time-zone of Europe/Moscow from
// java.util.Date
Locale locale = new Locale("ru", "RU");
DateFormat dfTarget = new SimpleDateFormat(SYSTEM_FORMAT, locale);
dfTarget.setTimeZone(TimeZone.getTimeZone("Europe/Moscow"));
System.out.println(dfTarget.format(date));
}
}
我建议您停止使用过时且容易出错的java。util
date-time API和SimpleDataFormat
。切换到现代的java。时间
date-time API和相应的格式化API(java.time.format
)。从Trail:date-time了解更多关于现代日期时间API的信息。如果您的android版本不符合Java-8,您可以使用Three Ten BackportCheck进行backport。查看如何在Android项目中使用ThreeTenABP。
import java.text.ParseException;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
public class Main {
public static void main(String[] args) throws ParseException {
// Given date-time string
String serverDate = "2020-08-24T11:50:18.613+0300";
// Date-time formatter
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSSZ");
ZonedDateTime zdtServer = ZonedDateTime.parse(serverDate, formatter);
System.out.println("Given date-time: " + zdtServer);
System.out.println("Zone Offset of the given date-time: " + zdtServer.getOffset());
// Convert it to some other time-zone e.g Etc/UTC
ZonedDateTime zdtatUTC = zdtServer.withZoneSameInstant(ZoneId.of("Etc/UTC"));
System.out.println("Equivalent date-time at UTC: " + zdtatUTC);
// Convert it to some other time-zone e.g Europe/London
ZonedDateTime zdtInLondon = zdtServer.withZoneSameInstant(ZoneId.of("Europe/London"));
System.out.println("Equivalent date-time in London: " + zdtInLondon);
}
}
输出:
Given date-time: 2020-08-24T11:50:18.613+03:00
Zone Offset of the given date-time: +03:00
Equivalent date-time at UTC: 2020-08-24T08:50:18.613Z[Etc/UTC]
Equivalent date-time in London: 2020-08-24T09:50:18.613+01:00[Europe/London]
请注意,现代日期时间API有一个名为ZonedDateTime
的类,该类具有时区信息以及日期
问题内容: 将日期转换为JSON时,javascript会以以下格式保存日期: 但是,我不确定如何将其放入python datetime对象。我已经尝试过这些: 我相信javascript会将字符串保存为官方ISO格式,因此似乎应该有一种方法可以让python 读取它? 问题答案: 请尝试以下格式: 例如: 该的日期只是手段,它应该被解释为UTC时间,所以忽略它不会造成任何信息丢失。您可以在这里找
问题内容: 我从来没有不得不将时间与UTC转换。最近有人要求我的应用注意时区,并且我一直在圈子里奔波。我发现很多有关将本地时间转换为UTC的信息,这很基本(也许我也做错了),但是我找不到任何有关将UTC时间轻松转换为最终用户时区的信息。 简而言之,android应用程序向我发送了(appengine应用程序)数据,该数据中包含时间戳。要将时间戳存储为UTC时间,我正在使用: 那似乎行得通。当我的应
问题内容: 我在mysql中使用NOW()获取当前日期和时间。我想将日期值转换为varchar并将其与另一个字符串连接。我该怎么做? 问题答案: 使用DATE_FORMAT()
问题内容: 例如字符串: 我将把它们推回到数据库中正确的日期时间字段中,因此我需要将它们魔术化为实际的日期时间对象。 这是通过Django的ORM进行的,因此我无法使用SQL进行插入时的转换。 问题答案: 是将字符串解析为日期时间的主要例程。它可以处理各种格式,格式由你为其指定的格式字符串确定: 生成的对象是时区未使用的。 链接: 适用于strptime:Python 2和Python 3的 Py
问题内容: 我试图将字符串转换为日期时间对象。我从新闻提要中获取的字符串格式如下:“星期四,2014年10月16日美国东部时间01:16:17” 我尝试使用datetime.strptime()进行转换。即 并得到以下错误: 追溯(最近一次通话最近): 文件“”,第1行,位于datetime.strptime(’Thu,16 Oct 2014 01:16:17 EDT’,’%a,%d%b%Y%H:
我有以下字符串: 我尝试用以下代码将此字符串转换为: Java . time . format . datetimeparseexception:无法解析文本“18/07/2019 04:30:00”:无法从TemporalAccessor获取LocalDateTime 我错过了什么?