Given:
public static void main(String[] args) {
String dateString = "2018-07-30T13:36:17.820";
DateTimeFormatter DATE_TIME_FORMATTER = DateTimeFormatter
.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSS");
LocalDate date = LocalDate.parse(dateString, DATE_TIME_FORMATTER);
ZonedDateTime zonedDateTime = date.atStartOfDay((ZoneOffset.UTC));
System.out.println(zonedDateTime);
}
And output:
2018-07-30T00:00Z
...what is the pattern to print seconds? Stupid question no doubt but driving me a little nuts
I need:
2018-07-30T00:00:00Z
I changed java.time.LocalDate to java.time.LocalDateTime, you need it if you want to show also the seconds.
package com.test;
import java.time.LocalDateTime;
import java.time.ZoneOffset;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
public class DateFormatter {
public static void main(String[] args) {
String dateString = "2018-07-30T13:36:17.820";
DateTimeFormatter DATE_TIME_FORMATTER = DateTimeFormatter
.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSS");
LocalDateTime date = LocalDateTime.parse(dateString, DATE_TIME_FORMATTER);
ZonedDateTime zonedDateTime = date.atZone(ZoneOffset.UTC);
System.out.println(zonedDateTime);
}
}
Output is:
2018-07-30T13:36:17.820Z
LocalDate will keep just date. You need to parse LocalDateTime and convert to ZonedDateTime and you will have seconds as you expect.
var dateString = "2018-07-30T13:36:17.820";
var format = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSS");
var localDate = LocalDateTime.parse(dateString, format);
var zone = ZoneId.of( "America/Montreal" );
var zonedDateTime = localDate.atZone(zone);
System.out.println(zonedDateTime);
You will have to go a few steps:
parse the String to a LocalDateTime because it contains date and time of day
extract the date only
create a ZonedDateTime out of that by adding the start of day (LocalTime.MIN = 00:00:00) and a ZoneOffset.UTC
This code may do:
public static void main(String[] args) {
String dateString = "2018-07-30T13:36:17.820";
// parse a LocalDateTime
LocalDateTime localDateTime = LocalDateTime.parse(dateString);
// extract the date part
LocalDate localDate = localDateTime.toLocalDate();
// make it a ZonedDateTime by applying a ZoneId
ZonedDateTime zonedDateTime = ZonedDateTime.of(localDate, LocalTime.MIN, ZoneOffset.UTC);
// print the result
System.out.println(zonedDateTime.format(DateTimeFormatter.ISO_ZONED_DATE_TIME));
}
Output is
2018-07-30T00:00:00Z
There are several ways to do it, this is just one of them and it just slightly differs from most of the other answers (and comments :-) ).
tl;dr
You have used the wrong things in the wrong places.
You do not need a DateTimeFormatter explicitly in order to parse 2018-07-30T13:36:17.820 because it's already in ISO 8601 format which is also the default format used by LocalDateTime#parse. Moreover, this string has date and time instead of just date; therefore, it makes more sense to parse it into LocalDateTime instead of LocalDate. You can always get LocalDate from LocalDateTime using LocalDateTime#toLocalDate.
The ZonedDateTime#toString uses the LocalDateTime#toString which in turn uses LocalTime#toString for the time part which omits second and fraction-of-second if they are zero. If you need a string with zero second and fraction-of-second, you will need to use a DateTimeFormatter.
Demo:
import java.time.LocalDateTime;
import java.time.ZoneOffset;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
public class Main {
public static void main(String args[]) {
String dateString = "2018-07-30T13:36:17.820";
LocalDateTime localDateTime = LocalDateTime.parse(dateString);// You do not need a DateTimeFormatter here
ZonedDateTime zonedDateTime = localDateTime.toLocalDate().atStartOfDay(ZoneOffset.UTC);
// Print zonedDateTime.toString()
System.out.println(zonedDateTime);
// Custom format
final DateTimeFormatter DATE_TIME_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSS");
System.out.println(DATE_TIME_FORMATTER.format(zonedDateTime));
}
}
Output:
2018-07-30T00:00Z
2018-07-30T00:00:00.000
Learn more about the modern date-time API from Trail: Date Time.
Related
i was trying to convet string time into ZonedDateTime but not comes up with solution . This is the string format of time "2022-12-23T07:20:00"
i have tried this approach
String stringDate = "2022-12-23T07:20:00";
DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("dd-MM-yyyy HH:mm:ss");
ZonedDateTime ztdOfDateOfPurchase = ZonedDateTime.parse(stringDate , dateTimeFormatter);
this error is coming=> java.time.format.DateTimeParseException: Text '2022-12-23T07:20:00' could not be parsed at index 19
Simply parse your date-time string using LocalDateTime#parse and add the applicable ZoneId to get the ZonedDateTime.
Note that java.time API is based on ISO 8601 and therefore you do not need a DateTimeFormatter to parse a date-time string which is already in ISO 8601 format (e.g. your date-time string, 2022-12-23T07:20:00).
Demo:
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.ZonedDateTime;
class Main {
public static void main(String[] args) {
LocalDateTime ldt = LocalDateTime.parse("2022-12-23T07:20:00");
// Replace ZoneId.systemDefault() with the applicable zone ID e.g.
// ZoneId.of("America/New_York")
ZonedDateTime zdt = ZonedDateTime.of(ldt, ZoneId.systemDefault());
System.out.println(zdt);
// Alternatively,
zdt = ldt.atZone(ZoneId.systemDefault());
System.out.println(zdt);
}
}
Output in my timezone:
2022-12-23T07:20Z[Europe/London]
2022-12-23T07:20Z[Europe/London]
Learn more about the modern Date-Time API from Trail: Date Time.
I have a UTC date-time like this (a String): 2022-11-22T17:15:00
And a ZoneID like this: "America/Tijuana"
Using java.time API, I want to get the actual datetime for that zone, which is: 2022-11-22T09:15:00 (the time is 09:15 instead of 17:15)
ZonedDateTime.toLocalDateTime() returns: 2022-11-22T17:15
ZonedDateTime.toString() returns:
2022-11-22T17:15-08:00[America/Tijuana]
None of the above gives me what I'm looking for.
This is my code:
ZoneId zonaID = ZoneId.of('America/Tijuana');
CharSequence dateUTC = "2022-11-22T17:15:00";
LocalDateTime dateTimeL = LocalDateTime.parse(dateUTC);
ZonedDateTime myZDT = ZonedDateTime.now();
ZonedDateTime myZDTFinal = myZDT.of(dateTimeL, zonaID);
System.out.println("using toLocalDateTime: " + myZDTFinal.toLocalDateTime());
System.out.println("using toString: " + myZDTFinal.toString());
I know that this might be a duplicated question but there's so many questions about date-times and I just haven't been able to figure out this.
Any help will be really appreciated.
You have to convert your date to UTC, then convert the convert this zone to your expected zone using withZoneSameInstant like this:
ZonedDateTime toUTCZone = ZonedDateTime.of(dateTimeL, ZoneOffset.UTC);
ZonedDateTime myZDTFinal = toUTCZone.withZoneSameInstant(zonaID);
Output
2022-11-22T09:15-08:00[America/Tijuana]
There can be many ways to achieve the result. A simple approach would be
Parse the given string into LocalDateTime.
Convert it into an OffsetDateTime at UTC using LocalDateTime#atOffset.
Use OffsetDateTime#atZoneSameInstant to convert the resulting OffsetDateTime into a ZonedDateTime at ZoneId.of("America/Tijuana").
Get LocalDateTime out of the resulting ZonedDateTime by using ZonedDateTime#toLocalDateTime.
If required, format this LocalDateTime into the desired string.
LocalDateTime
.parse("2022-11-22T17:15:00") // Parse the given date-time string into LocalDateTime
.atOffset(ZoneOffset.UTC) // Convert it into a ZonedDateTime at UTC
.atZoneSameInstant(ZoneId.of("America/Tijuana")) // Convert the result into a ZonedDateTime at another time-zome
.toLocalDateTime() // Get the LocalDateTime out of the ZonedDateTime
.format(DateTimeFormatter.ofPattern("uuuu-MM-dd'T'HH:mm:ss", Locale.ENGLISH))); // If required
Demo:
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.ZoneOffset;
import java.time.format.DateTimeFormatter;
import java.util.Locale;
public class Main {
public static void main(String[] args) {
LocalDateTime ldtInTijuana = LocalDateTime.parse("2022-11-22T17:15:00")
.atOffset(ZoneOffset.UTC)
.atZoneSameInstant(ZoneId.of("America/Tijuana"))
.toLocalDateTime();
System.out.println(ldtInTijuana);
// Custom format
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("uuuu-MM-dd'T'HH:mm:ss", Locale.ENGLISH);
String formatted = ldtInTijuana.format(formatter);
System.out.println(formatted);
}
}
Output:
2022-11-22T09:15
2022-11-22T09:15:00
Note that LocalDateTime#toString removes second and fraction-of-second values if they are zero. Suppose you want to keep them (as you have posted in your question), you can use a DateTimeFormatter as shown above.
An alternate approach:
Alternatively, you can append Z at the end of your ISO 8601 formatted date-time string to enable Instant to parse it and then convert the Instant into a ZonedDateTime corresponding to the ZoneId.of("America/Tijuana") by using Instant#atZone. The symbol, Z refers to UTC in a date-time string.
The rest of the steps will remain the same.
Demo:
public class Main {
public static void main(String[] args) {
String text = "2022-11-22T17:15:00";
text = text + "Z"; // Z refers to UTC
Instant instant = Instant.parse(text);
LocalDateTime ldt = instant.atZone(ZoneId.of("America/Tijuana")).toLocalDateTime();
System.out.println(ldt);
}
}
Output:
2022-11-22T09:15
Learn more about the modern Date-Time API from Trail: Date Time.
I am getting an Assertion error " Body Content Expected child but was null when asserting the andExpect XML. If I input as as a String "2020-10-01-5:00" it works fine but if I concatenate the date into a string like:
LocalDate startDate = LocalDate.now().minusDays(90);
String startDateLine = "<start-date>" + startDate + "-5:00</start-date>\n";
It throws the AssertionError. I have verified that the XML is correct before the call so I am unsure what about getting the date and converting to a string causes the test to fail.
Update
Do not add the offset string to the LocalDate string in order to convert it into an OffsetDateTime string. Shown below is the idiomatic way to convert a LocalDate to OffsetDateTime
LocalDate.of(2020, 10, 1)
.atStartOfDay()
.atOffset(ZoneOffset.of("-05:00"));
Demo:
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.OffsetDateTime;
import java.time.ZoneOffset;
public class Main {
public static void main(String[] args) {
LocalDate date = LocalDate.of(2020, 10, 1);
LocalDateTime ldt = date.atStartOfDay();
OffsetDateTime odt = ldt.atOffset(ZoneOffset.of("-05:00"));
System.out.println(odt);
}
}
Output:
2020-10-01T00:00-05:00
ONLINE DEMO
You can get the String representation of an OffsetDateTime using the function OffsetDateTime#toString e.g.
String strOdt = odt.toString();
Original answer
Change your input to have the timezone offset in the format HH:mm e.g. -05:00 so that it conforms to ISO 8601 standards.
Use DateTimeFormatterBuilder with .parseDefaulting(ChronoField.HOUR_OF_DAY, 0) to default the hour-of-day to 0.
Parse the given string to OffsetDateTime as it has timezone offset and OffsetDateTime is the best fit to represent Date-Time with timezone offset.
Demo:
import java.time.OffsetDateTime;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeFormatterBuilder;
import java.time.temporal.ChronoField;
import java.util.Locale;
public class Main {
public static void main(String[] args) {
DateTimeFormatter dtf =new DateTimeFormatterBuilder()
.appendPattern("u-M-d[H:m:s]XXX")
.parseDefaulting(ChronoField.HOUR_OF_DAY, 0)
.toFormatter(Locale.ENGLISH);
OffsetDateTime odt = OffsetDateTime.parse("2020-10-01-05:00", dtf);
System.out.println(odt);
}
}
Output:
2020-10-01T00:00-05:00
ONLINE DEMO
Notice the optional pattern inside a square bracket.
Learn more about the modern Date-Time API* from Trail: Date Time.
I have a string - 20180915 in format yyyyMMdd
I need to get epoch milli seconds for this date, answer for 20180915 should be 1537012800000
I was able to do this using following function -
import java.text.ParseException;
import java.time.LocalDateTime;
import java.time.ZoneOffset;
import java.time.format.DateTimeFormatter;
public static void main(String args[]) throws ParseException {
String myDate = "2018-09-15 12:00:00";
LocalDateTime localDateTime = LocalDateTime.parse(myDate,
DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss") );
System.out.println(localDateTime);
long millis = localDateTime
.atZone(ZoneOffset.UTC)
.toInstant().toEpochMilli();
System.out.println(millis);
}
The problem I am facing is -
I am passing String as "2018-09-15 12:00:00" but my input is "20180915".
I am unable to find good way to convert "20180915" to "2018-09-15 12:00:00"
How can i achieve this ?
Answer -
private static final DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyyMMdd");
public static Long getMillisForDate(String date) {
return LocalDateTime
.of(LocalDate.parse(date, formatter), LocalTime.NOON)
.atZone(ZoneOffset.UTC)
.toInstant().toEpochMilli();
}
You can make the DateTimeFormatter do all the work, which is especially useful if you need to parse multiple dates, as it reduces the number of intermediate parsing steps (and objects created):
DateTimeFormatter fmt = new DateTimeFormatterBuilder()
.appendPattern("uuuuMMdd")
.parseDefaulting(ChronoField.HOUR_OF_DAY, 12)
.toFormatter()
.withZone(ZoneOffset.UTC);
String input = "20180915";
long epochMilli = OffsetDateTime.parse(input, fmt).toInstant().toEpochMilli();
System.out.println(epochMilli); // prints: 1537012800000
You can replace OffsetDateTime with ZonedDateTime. Makes no difference to the result.
Parse the date with proper mask "yyyyMMdd"
SimpleDateFormat format = new SimpleDateFormat("yyyyMMdd");
Date date = format.parse("20180915");
long epochs = date.getTime();
I am using Java 8
This is what my ZonedDateTime looks like
2013-07-10T02:52:49+12:00
I get this value as
z1.format(DateTimeFormatter.ISO_OFFSET_DATE_TIME)
where z1 is a ZonedDateTime.
I wanted to convert this value as 2013-07-10T14:52:49
How can I do that?
Is this what you want?
This converts your ZonedDateTime to a LocalDateTime with a given ZoneId by converting your ZonedDateTime to an Instant before.
LocalDateTime localDateTime = LocalDateTime.ofInstant(z1.toInstant(), ZoneOffset.UTC);
Or maybe you want the users system-timezone instead of hardcoded UTC:
LocalDateTime localDateTime = LocalDateTime.ofInstant(z1.toInstant(), ZoneId.systemDefault());
It looks like you need to convert to the desired time zone (UTC) before sending it to the formatter.
z1.withZoneSameInstant( ZoneId.of("UTC") )
.format( DateTimeFormatter.ISO_OFFSET_DATE_TIME )
should give you something like 2018-08-28T17:41:38.213Z
#SimMac Thanks for the clarity. I also faced the same issue and able to find the answer based on his suggestion.
public static void main(String[] args) {
try {
String dateTime = "MM/dd/yyyy HH:mm:ss";
String date = "09/17/2017 20:53:31";
Integer gmtPSTOffset = -8;
ZoneOffset offset = ZoneOffset.ofHours(gmtPSTOffset);
// String to LocalDateTime
LocalDateTime ldt = LocalDateTime.parse(date, DateTimeFormatter.ofPattern(dateTime));
// Set the generated LocalDateTime's TimeZone. In this case I set it to UTC
ZonedDateTime ldtUTC = ldt.atZone(ZoneOffset.UTC);
System.out.println("UTC time with Timezone : "+ldtUTC);
// Convert above UTC to PST. You can pass ZoneOffset or Zone for 2nd parameter
LocalDateTime ldtPST = LocalDateTime.ofInstant(ldtUTC.toInstant(), offset);
System.out.println("PST time without offset : "+ldtPST);
// If you want UTC time with timezone
ZoneId zoneId = ZoneId.of( "America/Los_Angeles" );
ZonedDateTime zdtPST = ldtUTC.toLocalDateTime().atZone(zoneId);
System.out.println("PST time with Offset and TimeZone : "+zdtPST);
} catch (Exception e) {
}
}
Output:
UTC time with Timezone : 2017-09-17T20:53:31Z
PST time without offset : 2017-09-17T12:53:31
PST time with Offset and TimeZone : 2017-09-17T20:53:31-08:00[America/Los_Angeles]
If z1 is an instance of ZonedDateTime, then the expression
z1.withZoneSameInstant(ZoneOffset.UTC).toLocalDateTime()
evaluates to an instance of LocalDateTime with the string representation requested by the OP. This is illustrated by the following program:
import java.time.LocalDateTime;
import java.time.ZoneOffset;
import java.time.ZonedDateTime;
import java.time.temporal.ChronoUnit;
public class Main {
public static void main(String[] args) {
ZonedDateTime time = ZonedDateTime.now();
ZonedDateTime truncatedTime = time.truncatedTo(ChronoUnit.SECONDS);
ZonedDateTime truncatedTimeUtc = truncatedTime.withZoneSameInstant(ZoneOffset.UTC);
LocalDateTime truncatedTimeUtcNoZone = truncatedTimeUtc.toLocalDateTime();
System.out.println(time);
System.out.println(truncatedTime);
System.out.println(truncatedTimeUtc);
System.out.println(truncatedTimeUtcNoZone);
}
}
Sample output:
2020-10-26T16:45:21.735836-03:00[America/Sao_Paulo]
2020-10-26T16:45:21-03:00[America/Sao_Paulo]
2020-10-26T19:45:21Z
2020-10-26T19:45:21
I wanted to convert this value as 2013-07-10T14:52:49
👉 2013-07-10T02:52:49+12:00 ≠2013-07-10T14:52:49 at UTC
👉 2013-07-10T02:52:49+12:00 = 2013-06-09T14:52:49 at UTC (which is obtained by subtracting 12:00 hours of the offset from 2013-07-10T02:52:49).
Demo:
import java.time.LocalDateTime;
import java.time.OffsetDateTime;
import java.time.ZoneOffset;
class Main {
public static void main(String[] args) {
ZoneOffset zoneOffset = ZoneOffset.of("+12:00");
OffsetDateTime odtGiven = OffsetDateTime.of(LocalDateTime.of(2013, 7, 10, 2, 52, 49), zoneOffset);
System.out.println(odtGiven);
OffsetDateTime odtUtc = odtGiven.withOffsetSameInstant(ZoneOffset.UTC);
System.out.println(odtUtc);
System.out.println(odtUtc.toLocalDateTime());
}
}
Output:
2013-07-10T02:52:49+12:00
2013-07-09T14:52:49Z
2013-07-09T14:52:49
Learn about the modern Date-Time API from Trail: Date Time.