Skip to content
Advertisement

Kotlin/java – How to convert a date time string to Instant?

I am trying to create an instance of Instant from date and time strings. Date is formatted like this yyyy-MM-dd. So the values could look like this:

val date = "2021-11-25"
val time = "15:20"

I am trying to make a valid instant from this 2 strings like this:

val dateTime = "${date}T${time}:00"
val instantDateTime = ZonedDateTime.parse(dateTime, 
                                          DateTimeFormatter.ISO_OFFSET_DATE_TIME.withZone(defaultTimeZone)
                                         ).toInstant()

I have also tried with it:

val instantDateTime = Instant.from(DateTimeFormatter .ISO_OFFSET_DATE_TIME.withZone(defaultTimeZone).parse(dateTime))

But, that is not working, I get:

Exception in thread "main" java.time.format.DateTimeParseException: Text '2021-11-25T15:20:00' could not be parsed at index 19

Advertisement

Answer

You can combine the date and time strings to create a date-time string in ISO 8601 format which you can parse into LocalDateTime and then convert into Instant by using the applicable ZoneId. Note that the modern Date-Time API is based on ISO 8601 and does not require using a DateTimeFormatter object explicitly as long as the Date-Time string conforms to the ISO 8601 standards.

import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneId;

public class Main {
    public static void main(String[] args) {
        String strDate = "2021-11-25";
        String strTime = "15:20";
        String strDateTime = strDate + "T" + strTime;
        LocalDateTime ldt = LocalDateTime.parse(strDateTime);
        Instant instant = ldt.atZone(ZoneId.systemDefault()).toInstant();
        System.out.println(instant);
    }
}

Output:

2021-11-25T15:20:00Z

ONLINE DEMO

Some alternative approaches:

  1. Create the instance of LocalDateTime can be as suggested by daniu i.e. parse the date and time strings individually and create the instance of LocalDateTime using them.

Demo:

import java.time.Instant;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.ZoneId;

public class Main {
    public static void main(String[] args) {
        String strDate = "2021-11-25";
        String strTime = "15:20";
        LocalDateTime ldt = LocalDateTime.of(LocalDate.parse(strDate), LocalTime.parse(strTime));
        Instant instant = ldt.atZone(ZoneId.systemDefault()).toInstant();
        System.out.println(instant);
    }
}

ONLINE DEMO

  1. Create the instance of ZonedDateTime using ZonedDateTime#of(LocalDate, LocalTime, ZoneId) as suggested by Ole V.V.. Another variant that you can try with this approach is by using ZonedDateTime#of(LocalDateTime, ZoneId).

Demo:

import java.time.Instant;
import java.time.LocalDate;
import java.time.LocalTime;
import java.time.ZoneId;
import java.time.ZonedDateTime;

public class Main {
    public static void main(String[] args) {
        String strDate = "2021-11-25";
        String strTime = "15:20";
        ZonedDateTime zdt = ZonedDateTime.of(LocalDate.parse(strDate), LocalTime.parse(strTime),
                                                ZoneId.systemDefault());
        // Alternatively
        // ZonedDateTime zdt = ZonedDateTime.of(LocalDateTime.of(LocalDate.parse(strDate), LocalTime.parse(strTime)),
        //                                          ZoneId.systemDefault());
        
        Instant instant = zdt.toInstant();
        System.out.println(instant);
    }
}

ONLINE DEMO

  1. Combine the date and time strings to create a date-time string in ISO 8601 format and parse the same to ZonedDateTime using DateTimeFormatter.ISO_LOCAL_DATE_TIME.withZone(ZoneId.systemDefault()).

Demo:

import java.time.Instant;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;

public class Main {
    public static void main(String[] args) {
        String strDate = "2021-11-25";
        String strTime = "15:20";
        DateTimeFormatter dtf = DateTimeFormatter.ISO_LOCAL_DATE_TIME.withZone(ZoneId.systemDefault());
        ZonedDateTime zdt = ZonedDateTime.parse(strDate + "T" + strTime, dtf);
        Instant instant = zdt.toInstant();
        System.out.println(instant);
    }
}

ONLINE DEMO

  1. Create an instance of LocalDateTime by parsing the date and time strings, and use the LocalDateTime#toInstant to get the required Instant.

Demo:

import java.time.Instant;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.ZoneId;

public class Main {
    public static void main(String[] args) {
        String strDate = "2021-11-25";
        String strTime = "15:20";
        LocalDateTime ldt = LocalDateTime.of(LocalDate.parse(strDate), LocalTime.parse(strTime));
        Instant instant = ldt.toInstant(ZoneId.systemDefault().getRules().getOffset(ldt));
        System.out.println(instant);
    }
}

ONLINE DEMO

Learn more about the modern Date-Time API* from Trail: Date Time. Check this answer and this answer to learn how to use java.time API with JDBC.


* If you are working for an Android project and your Android API level is still not compliant with Java-8, check Java 8+ APIs available through desugaring. Note that Android 8.0 Oreo already provides support for java.time.

Advertisement