是否可以根据两个时间戳确定 UTC 偏移量?
Is it possible to determine the UTC offset from two timestamps?
假设我有两个时间戳。一个是 UTC,另一个时区未知,但有日期和时间。后者的格式为YYYY:MM:DD HH:MM:SS
.
通过简单地从 UTC 时间戳中减去第二个时间戳,然后四舍五入小时来获得与 UTC 的偏移是否合理?
有没有使用 Java 的直接方法? (例如 Joda 或 JUT?)
谢谢!
一点背景知识:这些日期来自图像的 EXIF 元数据。 EXIF 以 YYYY:MM:DD HH:MM:SS
格式存储图像的 CreateDate
,没有时区信息。它还在 GPSTimeStamp
下存储 UTC 时间戳(有时)。使用这两个值,我希望导出偏移量以便用它存储创建日期。虽然 TZ 偏移有 EXIF 元数据,但相机很少记录。
这里有一个建议:
String dateTimeStringUtc = "2017-08-25T11:46:47.307";
// for the sake of the example I took North Korean time; don’t tell anyone just yet :-)
String dateTimeStringUnknownOffset = "2017-08-25T20:16:47.307";
LocalDateTime utcTime = LocalDateTime.parse(dateTimeStringUtc);
LocalDateTime unknownOffsetTime = LocalDateTime.parse(dateTimeStringUnknownOffset);
long offsetSeconds = ChronoUnit.SECONDS.between(utcTime, unknownOffsetTime);
if (Math.abs(offsetSeconds) > 64800) { // out of range
System.out.println("The time strings cannot represent the same time");
} else {
ZoneOffset offset = ZoneOffset.ofTotalSeconds((int) offsetSeconds);
System.out.println("The zone offset is " + offset);
}
这会打印:
The zone offset is +08:30
正如评论中所讨论的那样,四舍五入到整小时通常不是一个好主意。这些天四舍五入到一刻钟可能是安全的,但我会犹豫,谁知道明年某些地方是否会引入 8:20 的偏移量?历史上存在以秒为单位的时区偏移,因此如果您的时间戳表示“过去的美好时光”,您应该避免四舍五入。
这就是我最后做的:
public static ZoneOffset determineTimeZoneOffset(OffsetDateTime localTime, OffsetDateTime utcTime) {
if(utcTime == null || localTime == null) {
return null;
}
OffsetDateTime ceilingUtc = utcTime.truncatedTo(ChronoUnit.HOURS).plusHours(1);
OffsetDateTime ceilingLocal = localTime.truncatedTo(ChronoUnit.HOURS).plusHours(1);
int offsetHours = (int)ChronoUnit.HOURS.between(ceilingUtc, ceilingLocal);
return ZoneOffset.ofHours(offsetHours);
}
有关截断为小时的警告已被很好地接受,但出于应用程序的目的,这是因为我们不需要走那么远。但是,我想使用 ChronoUnit.MINUTES
甚至几秒钟进行截断会很容易。 Ole V.V 的一个有趣的练习。有帮助地指出。
不确定为什么这会被否决——可能是对时间戳含义的混淆。我认为从问题中可以清楚地看出我指的是通用时间戳(如 Ole V.V. 和其他人指出的那样)。我希望反对者重新阅读问题并调整他们的评估。
虽然我真的不认为它与问题相关,但这些日期来自图像的 EXIF 元数据。 EXIF 以 YYYY:MM:DD HH:MM:SS
格式存储图像的 CreateDate
,没有时区信息。它还在 GPSTimeStamp
下存储 UTC 时间戳(有时)。使用这两个值,我希望导出偏移量以便用它存储创建日期。虽然有 TZ 偏移的 EXIF 元数据,但相机很少记录。
假设我有两个时间戳。一个是 UTC,另一个时区未知,但有日期和时间。后者的格式为YYYY:MM:DD HH:MM:SS
.
通过简单地从 UTC 时间戳中减去第二个时间戳,然后四舍五入小时来获得与 UTC 的偏移是否合理?
有没有使用 Java 的直接方法? (例如 Joda 或 JUT?)
谢谢!
一点背景知识:这些日期来自图像的 EXIF 元数据。 EXIF 以 YYYY:MM:DD HH:MM:SS
格式存储图像的 CreateDate
,没有时区信息。它还在 GPSTimeStamp
下存储 UTC 时间戳(有时)。使用这两个值,我希望导出偏移量以便用它存储创建日期。虽然 TZ 偏移有 EXIF 元数据,但相机很少记录。
这里有一个建议:
String dateTimeStringUtc = "2017-08-25T11:46:47.307";
// for the sake of the example I took North Korean time; don’t tell anyone just yet :-)
String dateTimeStringUnknownOffset = "2017-08-25T20:16:47.307";
LocalDateTime utcTime = LocalDateTime.parse(dateTimeStringUtc);
LocalDateTime unknownOffsetTime = LocalDateTime.parse(dateTimeStringUnknownOffset);
long offsetSeconds = ChronoUnit.SECONDS.between(utcTime, unknownOffsetTime);
if (Math.abs(offsetSeconds) > 64800) { // out of range
System.out.println("The time strings cannot represent the same time");
} else {
ZoneOffset offset = ZoneOffset.ofTotalSeconds((int) offsetSeconds);
System.out.println("The zone offset is " + offset);
}
这会打印:
The zone offset is +08:30
正如评论中所讨论的那样,四舍五入到整小时通常不是一个好主意。这些天四舍五入到一刻钟可能是安全的,但我会犹豫,谁知道明年某些地方是否会引入 8:20 的偏移量?历史上存在以秒为单位的时区偏移,因此如果您的时间戳表示“过去的美好时光”,您应该避免四舍五入。
这就是我最后做的:
public static ZoneOffset determineTimeZoneOffset(OffsetDateTime localTime, OffsetDateTime utcTime) {
if(utcTime == null || localTime == null) {
return null;
}
OffsetDateTime ceilingUtc = utcTime.truncatedTo(ChronoUnit.HOURS).plusHours(1);
OffsetDateTime ceilingLocal = localTime.truncatedTo(ChronoUnit.HOURS).plusHours(1);
int offsetHours = (int)ChronoUnit.HOURS.between(ceilingUtc, ceilingLocal);
return ZoneOffset.ofHours(offsetHours);
}
有关截断为小时的警告已被很好地接受,但出于应用程序的目的,这是因为我们不需要走那么远。但是,我想使用
ChronoUnit.MINUTES
甚至几秒钟进行截断会很容易。 Ole V.V 的一个有趣的练习。有帮助地指出。不确定为什么这会被否决——可能是对时间戳含义的混淆。我认为从问题中可以清楚地看出我指的是通用时间戳(如 Ole V.V. 和其他人指出的那样)。我希望反对者重新阅读问题并调整他们的评估。
虽然我真的不认为它与问题相关,但这些日期来自图像的 EXIF 元数据。 EXIF 以
YYYY:MM:DD HH:MM:SS
格式存储图像的CreateDate
,没有时区信息。它还在GPSTimeStamp
下存储 UTC 时间戳(有时)。使用这两个值,我希望导出偏移量以便用它存储创建日期。虽然有 TZ 偏移的 EXIF 元数据,但相机很少记录。