英文:
efficiently convert DateTime in long format (yyyyMMddHHmmss) into another zone for comparison
问题
我有一个长整型值,表示类似于 20200319234500 的日期时间(对应于2020年3月19日晚上11:45:00)。
我想将这个长整型值(20200319234500)转换为另一个时区的长整型格式,以便可以与本地时区的当前日期时间进行大于和小于的比较。
我希望能够高效地实现这一目标,因此在运行时不必创建任何对象或在启动后进行字符串创建。
但是看起来我必须先将长时间转换为字符串,然后调用 ZonedDateTime.parse() 函数来获取日期时间,然后进行比较。是否有其他方法可以做到这一点?
// 这些在编译时已知
ZoneId baseZone = ZoneId.of("Europe/Paris");
// 这些在编译时已知
ZoneId localZone = ZoneId.of("America/New_York");
// 这些在编译时已知
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("uuuuMMddHHmmss").withZone(baseZone);
long baseDateTime = 20210321234500L;
// 不希望进行字符串操作。是否有办法将其保持为长整型,并获得另一个在不同时区的长整型?
ZonedDateTime convertedBaseDateTime = ZonedDateTime.parse(Long.toString(baseDateTime), formatter);
// 是否可以只获取一个代表本地时区当前时间的长整型?本地时区不是 JVM 时区
ZonedDateTime localDateTime = ZonedDateTime.now(localZone);
// 这是我想执行的唯一操作
boolean result = convertedBaseDateTime.isBefore(localDateTime);
英文:
I have a long value that represents a datetime like this 20200319234500 (translates into March 19th, 2020 11:45:00PM)
I want this long value (20200319234500) converted into another timezone again in long format so I can do a greater than and less than comparison with the current date time in local timezone.
I want to do it efficiently so I dont have to create any objects during run time or do string creations after the start up.
but it looks like I must first convert long time to a string and then call ZonedDateTime.parse() function to get a datetime and then do a comparison. Is there another way of doing this?
//This is known at compile time
ZoneId baseZone = ZoneId.of("Europe/Paris");
//This is known at compile time
ZoneId localZone = ZoneId.of("America/New_York");
//This is known at compile time
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("uuuuMMddHHmmss").withZone(baseZone);
long baseDateTime = 20210321234500L;
//Dont want o be doing string operations. Is there a way to keep it in long and get another long in a different zone?
ZonedDateTime convertedBaseDateTime = ZonedDateTime.parse(Long.toString(baseDateTime), formatter);
//Can I just get a long that represents current time in local zone? local zone is not JVM zone
ZonedDateTime localDateTime = ZonedDateTime.now(localZone);
//Thats the only operation I want to perform
boolean result = convertedBaseDateTime.isBefore( localDateTime);
答案1
得分: 2
你可以通过对长整型数进行一些数学计算,从中提取出年、月、日、小时、分钟和秒,然后将其传递给 ZonedDateTime.of
函数。
long baseDateTime = 20210321234500L;
int year = (int)(baseDateTime / 10000000000L);
int month = (int)(baseDateTime / 100000000L % 100);
int day = (int)(baseDateTime / 1000000L % 100);
int hour = (int)(baseDateTime / 10000L % 100);
int minute = (int)(baseDateTime / 100L % 100);
int second = (int)(baseDateTime % 100);
ZonedDateTime convertedBaseDateTime = ZonedDateTime.of(year, month, day, hour, minute, second, 0, baseZone);
这样做不会创建新的字符串。
之后,如果你只是想检查一个日期时间是否在“现在”之前,你不需要为“现在”指定时区。你只需要比较那时和现在的(毫/纳)秒数自纪元以来的数字。
// 不需要这些
// ZoneId localZone = ZoneId.of("America/New_York");
// ZonedDateTime localDateTime = ZonedDateTime.now(localZone);
// 你只需要比较
convertedBaseDateTime.toEpochSecond() * 1000 < System.currentTimeMillis()
话虽如此,如果性能对你非常重要,也许你不应该使用Java,而应该使用更底层的语言。
英文:
You can do some maths to get the year, month, day, hour. minute, second from the long, and then you can pass it to ZonedDateTime.of
long baseDateTime = 20210321234500L;
int year = (int)(baseDateTime / 10000000000L);
int month = (int)(baseDateTime / 100000000L % 100);
int day = (int)(baseDateTime / 1000000L % 100);
int hour = (int)(baseDateTime / 10000L % 100);
int minute = (int)(baseDateTime / 100L % 100);
int second = (int)(baseDateTime % 100);
ZonedDateTime convertedBaseDateTime = ZonedDateTime.of(year, month, day, hour, minute, second, 0, baseZone);
This won't create new strings.
After that, notice that if you just want to check if a date time is before "now", you don't need a zone for "now". You just need to compare the numbers of (milli/nano)seconds since the epoch of then, and now.
// don't need these
// ZoneId localZone = ZoneId.of("America/New_York");
// ZonedDateTime localDateTime = ZonedDateTime.now(localZone);
// you just need to compare
convertedBaseDateTime.toEpochSecond() * 1000 < System.currentTimeMillis()
That said, if performance is so important for you, maybe you shouldn't use Java, and should instead use a more low-level language.
答案2
得分: -1
long baseDateTime = 20210321234500L;
LocalDateTime time = LocalDateTime.ofEpochSecond(baseDateTime / 1000, 0, ZoneOffset.ofHours(8));
//然后您可以使用time2.isAfter()或其他与JDK 8 API相关联的方法进行比较。
英文:
long baseDateTime = 20210321234500L;
LocalDateTime time=LocalDateTime.ofEpochSecond(baseDateTime /1000,0,ZoneOffset.ofHours(8));
//then you can use time2.isAfter() or some other methond to comparable that is link to jdk 8 API .
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论