Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to convert a date time string to long (UNIX Epoch Time) in Java 8 (Scala)

I want the UNIX Epoch Time (Posix Time, Unix Time) of a string in some pattern, the string is in normal format (so UTC). Please using Java 8, not Joda or old Java.

(For milliseconds please see How to convert a date time string to long (UNIX Epoch Time) Milliseconds in Java 8 (Scala))

So far I have the below, but I hate this for a number of reasons:

  1. It's way too verbose for what is the most common thing to do with dates (convert to UNIX Epoch Time). 7 method calls for what should be 1.
  2. It has to specify UTC, but surely UTC is just a default, why do I have to be explicit here?
  3. It has a string literal "UTC"
  4. It has a magic number ZoneOffset.ofHours(0)

My best so far:

def dateTimeStringToEpoch(s: String, pattern: String): Long = 
    LocalDateTime.parse(s, DateTimeFormatter.ofPattern(pattern))
      .atZone(ZoneId.ofOffset("UTC", ZoneOffset.ofHours(0)))
      .toInstant().getEpochSeconds

Also, bonus question, is it efficient? Is there any overhead to creating the DateTimeFormatter via DateTimeFormatter.ofPattern(pattern)? If so why?

like image 948
samthebest Avatar asked Jan 24 '19 12:01

samthebest


People also ask

How do you convert date string to epoch time?

Convert from human-readable date to epochlong epoch = new java.text.SimpleDateFormat("MM/dd/yyyy HH:mm:ss").parse("01/01/1970 01:00:00").getTime() / 1000; Timestamp in seconds, remove '/1000' for milliseconds. date +%s -d"Jan 1, 1980 00:00:01" Replace '-d' with '-ud' to input in GMT/UTC time.

How do I make LocalDateTime long?

The easiest way to create an instance of the LocalDateTime class is by using the factory method of(), which accepts year, month, day, hour, minute, and second to create an instance of this class. A shortcut to create an instance of this class is by using atDate() and atTime() method of LocalDate and LocalTime class.

What is epoch date format Java?

What is epoch time? The Unix epoch (or Unix time or POSIX time or Unix timestamp) is the number of seconds that have elapsed since January 1, 1970 (midnight UTC/GMT), not counting leap seconds (in ISO 8601: 1970-01-01T00:00:00Z).

How do I change timestamp format?

We can format the Timestamp value using SimpleDateFormat class. Initially, by using the Timestamp class, the time is getting displayed in a standard format, but we can format it to our own choice using SimpleDateFormat class.


3 Answers

You may use the equivalent of the following Java code:

static long dateTimeStringToEpoch(String s, String pattern) {
    return DateTimeFormatter.ofPattern(pattern).withZone(ZoneOffset.UTC)
        .parse(s, p -> p.getLong(ChronoField.INSTANT_SECONDS));
}

Of course, processing DateTimeFormatter.ofPattern(pattern).withZone(ZoneOffset.UTC) implies work that could be avoided when encountering the same pattern string multiple times. Whether this amount of work is relevant for your application, depends on what is is doing beside this operation.

like image 107
Holger Avatar answered Oct 14 '22 07:10

Holger


This one is more than two times shorter (only 3 method calls):

def dateTimeStringToEpoch(s: String, pattern: String): Long = 
     LocalDateTime.parse(s, DateTimeFormatter.ofPattern(pattern))
                  .toEpochSecond(ZoneOffset.UTC)

Btw, I would build the DateTimeFormatter outside of dateTimeStringToEpoch and pass it as a method parameter:

def dateTimeStringToEpoch(s: String, formatter: DateTimeFormatter): Long = 
     LocalDateTime.parse(s, formatter).toEpochSecond(ZoneOffset.UTC)

Having actually run a performance test, there is little difference in performance (barely a factor of 2) in initialising the DateTimeFormatter outside the method.

scala> val pattern = "yyyy/MM/dd HH:mm:ss"
pattern: String = yyyy/MM/dd HH:mm:ss

scala>   time(() => randomDates.map(dateTimeStringToEpoch(_, pattern)))
Took: 1216

scala>   time(() => randomDates.map(dateTimeStringToEpochFixed))
Took: 732
like image 45
ETO Avatar answered Oct 14 '22 05:10

ETO


Can you try this one, based on what you have said, it is parsing UTC time, so I have this as a sample.

Instant.parse("2019-01-24T12:48:14.530Z").getEpochSecond

like image 26
Edwin Langga Avatar answered Oct 14 '22 07:10

Edwin Langga