高效地将长格式的 DateTime(yyyyMMddHHmmss)转换为另一个时区,以进行比较。

huangapple go评论72阅读模式
英文:

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&#39;t need these
// ZoneId localZone = ZoneId.of(&quot;America/New_York&quot;);
// ZonedDateTime localDateTime = ZonedDateTime.now(localZone);

// you just need to compare
convertedBaseDateTime.toEpochSecond() * 1000 &lt; 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 .

huangapple
  • 本文由 发表于 2020年9月21日 11:31:19
  • 转载请务必保留本文链接:https://go.coder-hub.com/63985839.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定