Parsing a DateTime in a time-zone - java

I have a date-time from Los_Angeles. The daylight saving applies when possible. I'm trying to convert that date-time into a timestamp, but I don't seem to understand the Java 8 DateTime API. The following snippet returns 1238112000 (which is the correct date if it was specified in UTC). What should I change to show 1238137200 instead?
String date = "March 27, 2009 00:00:00";
DateTimeFormatter formatter = DateTimeFormatter.
ofPattern("MMMM dd, yyyy HH:mm:ss", Locale.ENGLISH).
withZone(ZoneId.of("America/Los_Angeles"));
LocalDateTime.parse(date, formatter).toEpochSecond(ZoneOffset.UTC))

By parsing the date into a LocalDateTime, you are ignoring the timezone information from the formatter. You should use a ZonedDateTime:
public static void main(String[] args) {
String date = "March 27, 2009 00:00:00";
DateTimeFormatter formatter =
DateTimeFormatter.ofPattern("MMMM dd, yyyy HH:mm:ss", Locale.ENGLISH)
.withZone(ZoneId.of("America/Los_Angeles"));
long second = ZonedDateTime.parse(date, formatter).toEpochSecond();
System.out.println(second); // prints "1238137200"
}
On the returned instance, you can then call toEpochSecond().

Related

How to convert date format to UTC in Scala?

How to convert date format "2021-02-28 13:38:00.597+0000" to "Mon, Feb 28,2021 15:25:00 UTC" UTC format in Scala?
If you are using an older Java version prior to Java 8, it's best to use the DateTimeFormat from joda-time. BTW, the +0000 zone offset is for UTC, so I could have omitted withZoneUTC(), but I still used it for the first date just to be safe:
val oldDateString = "2021-02-28 13:38:00.597+0000"
val OldFormat = "yyyy-MM-dd HH:mm:ss.SSSZ"
val NewFormat = "EEE, MMM dd, yyyy HH:mm:ss z"
val formatterOld = DateTimeFormat.forPattern(OldFormat)
val formatterNew = DateTimeFormat.forPattern(NewFormat)
val dt = formatterOld.withZoneUTC().parseDateTime(oldDateString)
val dateStringInUTC = formatterNew.withZoneUTC().print(dt)
println(dt) // 2021-02-28T13:38:00.597Z
println(dateStringInUTC) // Sun, Feb 28, 2021 13:38:00 UTC
UPDATE: For Java 8 and newer, the java.time API is your friend. Similarly, withZoneSameInstant(ZoneOffset.UTC) was not really needed:
val oldDateString = "2021-02-28 13:38:00.597+0000"
val OldFormat = "yyyy-MM-dd HH:mm:ss.SSSZZZ"
val NewFormat = "EEE, MMM dd, yyyy HH:mm:ss z"
val formatterOld = DateTimeFormatter.ofPattern(OldFormat)
val formatterNew = DateTimeFormatter.ofPattern(NewFormat)
val zdt = ZonedDateTime.parse(oldDateString, formatterOld)
val dateStringInUTC = zdt.withZoneSameInstant(ZoneId.of("UTC")).format(formatterNew)
println(zdt) // 2021-02-28T13:38:00.597Z
println(dateStringInUTC) // Sun, Feb 28, 2021 13:38:00 UTC
UPDATE: Switched to using ZoneId.of("UTC") instead of ZoneOffset.UTC because the latter does not get the String UTC printed at the end, even though ZoneOffset extends ZoneId, as #deHaar mentioned.
If you could use java.time, you would need
a DateTimeFormatter for parsing Strings with the format of your input example, which is quite near to ISO standard, but is missing the 'T' between date and time of day
another DateTimeFormatter for outputting the temporal content in the desired format, which includes (English) abbreviations for day of week and month of year
an OffsetDateTime for parsing the String with the first DateTimeFormatter and
a ZonedDateTime for the temporal value in UTC
This is how I would do it in Java:
public static void main(String[] args) {
// example String
String utcDatetimeString = "2021-02-28 13:38:00.597+0000";
// prepare a formatter that can parse a String of this format
DateTimeFormatter dtfIn = DateTimeFormatter.ofPattern(
"uuuu-MM-dd HH:mm:ss.SSSxxxx",
Locale.ENGLISH
);
// parse it to an OffsetDateTime
OffsetDateTime odt = OffsetDateTime.parse(utcDatetimeString, dtfIn);
// then convert it to a ZonedDateTime applying UTC zone
ZonedDateTime zdt = odt.atZoneSameInstant(ZoneId.of("UTC"));
// prepare a formatter that produces the desired output
DateTimeFormatter dtfOut = DateTimeFormatter.ofPattern(
"EEE, MMM dd, uuuu HH:mm:ss zzz",
Locale.ENGLISH
);
// and print the ZonedDateTime using the formatter
System.out.println(zdt.format(dtfOut));
}
Output:
Sun, Feb 28, 2021 13:38:00 UTC

Java Date TIME Format AM/PM Configuration

I am facing problems some while formatting the date:
Date : 11/06/2020 04:14:20
Date Format:dd/MM/yyyy hh:mm:ss a
Exception:
java.text.ParseException: Unparseable date: "11/06/2020 04:14:20"
Following is the code
Blockquote
public String getFormatDate(String inputDate) {
String strDate = "";
try {
DateFormat outputFormat = new SimpleDateFormat("MMMM dd, yyyy hh:mm:ss a");
DateFormat inputFormat = new SimpleDateFormat("dd/MM/yyyy hh:mm:ss a");
Date date1 = inputFormat.parse(inputDate);
strDate = outputFormat.format(date1);
}catch( Exception exe) {
exe.printStackTrace();
logger.error( "[ERROR] getFormatDate:. ", exe );
}
return strDate;
}
Blockquote
Any help would be greatly appeciated.
You can check this code you have to pass the am/pm part too with the date string value as your format is expecting that.
//String date = "11/06/2020 04:14:20";
String date = "11/06/2020 04:14:20 am";
DateFormat df = new SimpleDateFormat("dd/MM/yyyy hh:mm:ss a");
https://ideone.com/3nibwJ
Use proper date-time objects for your dates and times
For the vast majority of purposes you should not keep your date and time in a string and should not convert your date and time from a string in one format to a string in another format. Keep your date and time in a ZonedDateTime or LocalDateTime object.
When you are required to accept string input, parse that input into a date-time object immediately. I am using and recommending java.time, the modern Java date and time API:
DateTimeFormatter inputFormatter = DateTimeFormatter.ofPattern("dd/MM/uuuu HH:mm:ss");
String input = "11/06/2020 04:14:20";
LocalDateTime dateTime = LocalDateTime.parse(input, inputFormatter);
System.out.println(dateTime);
Output so far is:
2020-06-11T04:14:20
Since there is no AM or PM in your string, I have assumed that 04:14:20 was the time of day from 00:00:00 through 23:59:59. If you intended otherwise, you need to explain how.
Only when you need to give string output, format your date and time back into a string of appropriate format:
DateTimeFormatter outputFormatter = DateTimeFormatter
.ofPattern("MMMM dd, yyyy hh:mm:ss a", Locale.ENGLISH);
String output = dateTime.format(outputFormatter);
System.out.println(output);
June 11, 2020 04:14:20 AM
Do provide a locale for the formatter so Java knows which language to use for the month name and the AM/PM indicator.
What went wrong in your code?
Your string has no AM nor PM: 11/06/2020 04:14:20. Yet your format pattern string requires an AM/PM marker in the end. This is what format pattern letter a signifies. So your string wasn’t in the format that you required. This was the reason for the exception that you observed.
Link
Oracle tutorial: Date Time explaining how to use java.time.
Thanks All for your help:
I have changed the source date "11/06/2020 04:14:20" to "06/11/2020 04:14:20 PM", and then after perform follwoing steps, its working for me:
Blockquote
DateFormat inputFormat = new SimpleDateFormat("dd/MM/yyyy hh:mm:ss a");
inputFormat.setTimeZone( TimeZone.getTimeZone("UTC") );
Date dDate = inputFormat.parse( srcDate );
String strDeDate = formatDateToString( dDate, "dd/MM/yyyy hh:mm:ss a", "IST" );
public String formatDateToString(Date date, String format,String timeZone) {
if (date == null) return null;
SimpleDateFormat sdf = new SimpleDateFormat(format);
if (timeZone == null || "".equalsIgnoreCase(timeZone.trim())) {
timeZone = Calendar.getInstance().getTimeZone().getID();
}
sdf.setTimeZone(TimeZone.getTimeZone(timeZone));
return sdf.format(date);
}
Blockquote

How to compare the datetime of format "EEE MMM dd HH:mm:ss zzz yyyy" and "yyyy-MM-dd hh:mm:sss" in java?

I have date of type "EEE MM DD HH:mm:ss zzz yyyy" (Wed Mar 04 03:34:45 GMT+08:00 2020) and "yyyy-MM-dd hh:mm:ss" (2020-02-04 02:10:58).How to compare this two date in java?
Both dates are in same timezone.
If you assume that the timezone of the second date is the same as for the first one then you can just use java.time. It has all parsing tools you need. Any other fixed timezone works as well.
Here is an example:
String a = "Wed Mar 04 03:34:45 GMT+08:00 2020";
String b = "2020-02-04 02:10:58";
ZonedDateTime parsedA;
ZonedDateTime parsedB;
DateTimeFormatter formatterA = DateTimeFormatter.ofPattern("EEE MMM dd HH:mm:ss zzz yyyy");
parsedA = ZonedDateTime.parse(a, formatterA);
DateTimeFormatter formatterB = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
parsedB = LocalDateTime.parse(b, formatterB).atZone(parsedA.getZone());
// What do you want to compare? For example you can tell if a is after b.
System.out.println(parsedA.isAfter(parsedB));
Have a look here if you need another format and need a listing of Pattern Letters and Symbols.
First of all these two dates are not comparable because of missing timezone in the second date.
Secondly, If you still want to do that with system's default time zone then you need to bring both the dates into common format.
Parse the dates into Date object and then you can play around it:
DateFormat dateFormat1 = new SimpleDateFormat("EEE MMM dd HH:mm:ss Z yyyy");
Date date1 = dateFormat1.parse("Wed Mar 04 03:34:45 GMT+08:00 2020");
DateFormat dateFormat2 = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
Date date2 = dateFormat2.parse("2020-02-04 02:10:58");
System.out.println(date1.after(date2));
There is a difference between time zone and time zone offset. The Date-Time string Wed Mar 04 03:34:45 GMT+08:00 2020 has a time zone offset, not a time zone. A time zone is unique and therefore it has an ID e.g. ZoneId.of("America/New_York") whereas a time zone offset tells you about the amount of time by which a given time is offset from the UTC time. There can be many time zones falling on the same time zone offset. Check List of tz database time zones to learn more about it. So, the most appropriate type to parse Wed Mar 04 03:34:45 GMT+08:00 2020 into is OffsetDateTime.
Since the second Date-Time string 2020-02-04 02:10:58 has neither a time zone nor a time zone offset, parse it into LocalDateTime.
Make sure to use Locale with the formatter because Date-Time parsing/formatting API is Locale-sensitive.
As long as the second Date-Time string refers to a Date-Time at the same timezone offset (i.e. GMT+08:00), you can do either of the two to compare them
Convert the first Date-Time string into LocalDateTime after parsing and then compare it with the second Date-Time string parsed into a LocalDateTime.
Convert the second Date-Time string into an OffsetDateTime after parsing and then compare it with the first Date-Time string parsed into an OffsetDateTime.
I would prefer the first approach as it is simpler. However, for the sake of completeness, I've shown below both approaches.
First approach:
DateTimeFormatter odtFormatter = DateTimeFormatter.ofPattern("EEE MMM dd HH:mm:ss O uuuu", Locale.ENGLISH);
OffsetDateTime firstOffsetDateTime = OffsetDateTime.parse("Wed Mar 04 03:34:45 GMT+08:00 2020", odtFormatter);
LocalDateTime firstLocalDateTime = firstOffsetDateTime.toLocalDateTime();
DateTimeFormatter ldtFormatter = DateTimeFormatter.ofPattern("uuuu-MM-dd HH:mm:ss", Locale.ENGLISH);
LocalDateTime secondLocalDateTime = LocalDateTime.parse("2020-02-04 02:10:58", ldtFormatter);
// Compare the two LocalDateTime values using isBefore, isAfter, equals etc.
if (firstLocalDateTime.isBefore(secondLocalDateTime)) {
// ...
}
Second approach:
DateTimeFormatter odtFormatter = DateTimeFormatter.ofPattern("EEE MMM dd HH:mm:ss O uuuu", Locale.ENGLISH);
OffsetDateTime firstOffsetDateTime = OffsetDateTime.parse("Wed Mar 04 03:34:45 GMT+08:00 2020", odtFormatter);
DateTimeFormatter ldtFormatter = DateTimeFormatter.ofPattern("uuuu-MM-dd HH:mm:ss", Locale.ENGLISH);
LocalDateTime secondLocalDateTime = LocalDateTime.parse("2020-02-04 02:10:58", ldtFormatter);
OffsetDateTime secondOffsetDateTime = secondLocalDateTime.atOffset(firstOffsetDateTime.getOffset());
// Compare the two OffsetDateTime values using isBefore, isAfter, equals etc.
if (firstOffsetDateTime.isBefore(secondOffsetDateTime)) {
// ...
}
I also prefer u to y with a DateTimeFormatter.
Learn more about the the modern date-time API from Trail: Date Time.

How to find a Future Date in Java(say two months from today) in 24 February 2019 format

Below is the approach I am going with :
Date DateObject = new Date();
SimpleDateFormat formatDate = new SimpleDateFormat("dd MMMM yyyy");
String dateString = formatDate.format(DateObject);
System.out.println(dateString);
Now this gives me the current date in desired format. I want to find the Value of Date in same format exactly two months from this date.
I also tried to work with below approach :
LocalDate futureDate = LocalDate.now().plusMonths(2);
This gives me the date I want which is two months from now but in 2019-04-24 format. When I tried to format this date using SimpleDateFormat it is giving me Illegal Argument Exception.
Try using the DateTimeFormatter class introduced in Java 8, avoid using the SimpleDateFormat :
public static void main(String[] args) {
LocalDate futureDate = LocalDate.now().plusMonths(2);
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd MMMM yyyy");
String dateStr = futureDate.format(formatter);
System.out.println(dateStr);
}
Output:
24 April 2019
The DateTimeFormatter in Java 8 is immutable and thread-safe alternative to SimpleDateFormat.

Parse a Date of MMMM YYYY format

I have to parse a date string (e.g. "October 2015") to a Date.
So the question is: how can I parse a date of MMMM yyyy format? Its ok if the new Date object is the first month of the given month.
I tried:
DateTimeFormatter formatter = new DateTimeFormatterBuilder().appendPattern("MMMM yyyy").toFormatter();
TemporalAccessor ta = formatter.parse(node.textValue());
Instant instant = LocalDate.from(ta).atStartOfDay().atZone(ZoneId.systemDefault()).toInstant();
Date d = Date.from(instant);
But it does not work since the day is missing.
What you have there is a YearMonth, not a LocalDate since the day is missing.
The following works:
String string = "October 2015";
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("MMMM yyyy", Locale.ENGLISH);
YearMonth yearMonth = YearMonth.parse(string, formatter);
// Alternatively: YearMonth yearMonth = formatter.parse(string, YearMonth::from);
LocalDate date = yearMonth.atDay(1);
System.out.println(yearMonth); // prints "2015-10"
System.out.println(date); // prints "2015-10-01"
If you then want that as a java.util.Date, you need to specify which time zone you mean, maybe UTC or system default?
// ZoneId zone = ZoneOffset.UTC;
ZoneId zone = ZoneId.systemDefault();
Date javaUtilDate = Date.from(date.atStartOfDay(zone).toInstant());
System.out.println(javaUtilDate); // prints "Thu Oct 01 00:00:00 CEST 2015"
// because i'm in Europe/Stockholm.
How about this
DateFormat format = new SimpleDateFormat("MMMM yyyy", Locale.ENGLISH);
Date date = format.parse("October 2015");
System.out.println(date); // Prints Thu Oct 01 00:00:00 BST 2015
For java 8
DateTimeFormatter formatter = new DateTimeFormatterBuilder()
.appendPattern("MMMM yyyy")
.toFormatter(Locale.US);
TemporalAccessor ta = formatter.parse("October 2015");
YearMonth ym = YearMonth.from(ta);
LocalDateTime dt = LocalDateTime.of(ym.getYear(), ym.getMonthValue(),
1, 0, 0, 0);
Instant instant = Instant.from(dt.atZone(ZoneId.systemDefault()));
Date d = Date.from(instant);
You can use SimpleDateFormat's parse method for that
private static final SimpleDateFormat DATE_FORMAT = new SimpleDateFormat("MMMMM yyyy"); //MMMM yyyy example: October 2015
public Date getDateFromString(String input) {
return DATE_FORMAT.parse(input);
}
For more information, see: http://docs.oracle.com/javase/7/docs/api/java/text/SimpleDateFormat.html#parse(java.lang.String,%20java.text.ParsePosition)
Explanation of format:
MMMM indicates you are parsing full name months such as "October"
yyyy indicates you have 4-digit length years. If you wanted to parse for example, October 15, your format would look like this: "MMMM yy"
Why not use a SimpleDateFormatter?
This works fine for me:
SimpleDateFormat formatter = new SimpleDateFormat("MMMM yyyy");
Date d = formatter.parse("Oktober 2015");

Categories

Resources