0

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);
bsobaid
  • 955
  • 1
  • 16
  • 36
  • I think if I can get an offset between the two timezones in int/long format, then I can simple add it to my baseDateTime. But how do I get a long/int offset between zones? Also, how to get current time in localzone in long for comparison? – bsobaid Sep 21 '20 at 03:37
  • "Don't want to create new strings" is a weird requirement. Are you sure creating new strings will cause you performance problems? – Sweeper Sep 21 '20 at 03:44
  • IMHO, this is already the most efficient way to do it. Any other way will simply make the code more complex (and probably without any performance benefit). – Arvind Kumar Avinash Sep 21 '20 at 08:45
  • You don’t need any tiem zone conversion. `ZonedDateTime.isBefore()` takes into account if the other `ZonedDateTime` is in a different time zone (it probably converts behind the scenes, but you can leave it to that). – Ole V.V. Sep 21 '20 at 12:48
  • Related, possibly a duplicate or near: (1) [Good way to convert integer YYYYMMDD into java.util.Date with local time zone](https://stackoverflow.com/questions/27910196/good-way-to-convert-integer-yyyymmdd-into-java-util-date-with-local-time-zone). (2) [Converting long (whose decimal representation represents a yyyyMMdd.. date) to a different date format](https://stackoverflow.com/questions/11577847/converting-long-whose-decimal-representation-represents-a-yyyymmdd-date-to-a). – Ole V.V. Sep 21 '20 at 13:01

2 Answers2

2

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.

Sweeper
  • 213,210
  • 22
  • 193
  • 313
  • Java should be performant enough. If the method is run often, it will be compiled to native code just like code in, say, C would from the outset. If you need to be sure, you need to make your own measurements, of course. – Ole V.V. Sep 21 '20 at 19:00
-1

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 .

Allen
  • 88
  • 6